麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

從零開始學ios開發(二十):ApplicationSettingsandUserDefaults(下)

2019-11-14 20:15:45
字體:
來源:轉載
供稿:網友

在上一篇的學習中,我們知道了如何為一個App添加它的Settings設置項,在Settings設置項中我們可以添加哪些類型的控件,這些控件都是通過一個plist來進行管理的,我們只需對plist進行修改添加,就可以映射到Settings中。但是在上一篇中,我們并沒有學習Settings和App的交互,在這一篇中我們將進行學習,如何在一個App中讀取Settings中的值,如何在App中修改Settings中的值,好了,下面開始我們這次的學習。

1)NSUserDefaults
NSUserDefaults是ios自帶的一個對象,它的主要作用對Settings中的變量(我們添加的控件)進行取值和賦值。在上一篇中,我們在創建plist的時候,每一個Item都有一個Key,NSUserDefaults就是根據這個Key來找到對象,然后取得值,或者賦值。這個其實就是一個key-value對,NSUserDefaults在用法上和NSDictionary是一樣的,因此它也有很多類似的對象例如:objectForKey,intForKey,floatForKey,boolForKey,這些都很簡單。另外NSUserDefaults是一個單例模式(Singleton),也就是說在整個app中只有一個NSUserDefaults對象存在,這樣可以避免在2個地方同時對一個Item進行操作的情況,在程序中,我們使用standardUserDefaults方法來取得NSUserDefaults對象:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

2)從Settings中讀取值
打開BIDMainViewController.h,添加如下代碼

復制代碼
#import "BIDFlipsideViewController.h"#define kUsernameKey        @"username"#define kPassWordKey        @"password"#define kPRotocolKey        @"protocol"#define kWarpDriveKey       @"warp"#define kWarpFactorKey      @"warpFactor"#define kFavoriteTeaKey     @"favoriteTea"#define kFavoriteCandyKey   @"favoriteCandy"#define kFavoriteGameKey    @"favoriteGame"#define kFavoriteExcuseKey  @"favoriteExcuse"#define kFavoriteSinKey     @"favoriteSin"@interface BIDMainViewController : UIViewController <BIDFlipsideViewControllerDelegate>@property (weak, nonatomic) IBOutlet UILabel *usernameLabel;@property (weak, nonatomic) IBOutlet UILabel *passwordLabel;@property (weak, nonatomic) IBOutlet UILabel *protocolLabel;@property (weak, nonatomic) IBOutlet UILabel *warpDriveLabel;@property (weak, nonatomic) IBOutlet UILabel *warpFactorLabel;@property (weak, nonatomic) IBOutlet UILabel *favoriteTeaLabel;@property (weak, nonatomic) IBOutlet UILabel *favoriteCandyLabel;@property (weak, nonatomic) IBOutlet UILabel *favoriteGameLabel;@property (weak, nonatomic) IBOutlet UILabel *favoriteExcuseLabel;@property (weak, nonatomic) IBOutlet UILabel *favoriteSinLabel;- (void)refreshFields;@end
復制代碼

上面的代碼定義了10個常量Key,用來在之后的代碼中根據Key獲取Settings中的值,接著聲明10個IBOutlet,且他們都是指向Label的,最后聲明了一個refreshField方法,用于從Settings中讀取值然后賦給Label。

保存上面的code,然后在Project navigator中選中MainStoryboard.storyboard,在Layout area中會顯示2個View,分別是Main View和FlipSide View,我們選中Main View,然后打開Attribute inspector,找到Backgrund,將其背景色變為白色

在Main View的右下角,有一個Info button(一個圓圈,中間有一個字母i),選中它,然后在Attribute inspector中將其Type改成“Info Dark”

這樣就能夠很容易的找到它所在的地方了

如果你覺得直接在Main View中選擇一個白色的Info button很困難,那么你可以打開Main View Controller Scene,在里面你可以方便的找到它

好,接下來我們就要往Main View中拖控件了,一共拖20個Label,其中十個Label為靜態的,僅僅顯示文字,另外十個需要與剛才定義的IBOutlet關聯起來,用于顯示Settings中的值。

根據下圖的樣子,將Label拖入到Main View中

排列什么的無所謂,自己喜歡就好,主要是右邊的10個Label,他們的寬度都是到最右邊出現輔助線的位置,以保證能夠最大限度容納字符。

好了,下面的工作就是關聯IBOutlet和view上面的Label了,一共要關聯10個Label,選中Main View Controller Scene中的Main View Control,control-drag到Label上(右邊的一排Label),在彈出的框中選中相對應的IBOutlet

好了,保存所有的修改,下面開始編碼。

打開BIDMainViewController.m,添加以下code

復制代碼
@implementation BIDMainViewController- (void)refreshFields {    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];    self.usernameLabel.text = [defaults objectForKey:kUsernameKey];    self.passwordLabel.text = [defaults objectForKey:kPasswordKey];    self.protocolLabel.text = [defaults objectForKey:kProtocolKey];    self.warpDriveLabel.text = [defaults boolForKey:kWarpDriveKey] ? @"Enabled" : @"Disabled";    self.warpFactorLabel.text = [[defaults objectForKey:kWarpFactorKey] stringValue];    self.favoriteTeaLabel.text = [defaults objectForKey:kFavoriteTeaKey];    self.favoriteCandyLabel.text = [defaults objectForKey:kFavoriteCandyKey];    self.favoriteGameLabel.text = [defaults objectForKey:kFavoriteGameKey];    self.favoriteExcuseLabel.text = [defaults objectForKey:kFavoriteExcuseKey];    self.favoriteSinLabel.text = [defaults objectForKey:kFavoriteSinKey];}- (void)viewDidAppear:(BOOL)animated {    [super viewDidAppear:animated];    [self refreshFields];}
復制代碼

首先我們實現了refreshFields方法,里面首先聲明了NSUserDefaults,用于獲取Settings中的值,之后調用objextForKey,通過Key來獲取10個Label的值,有2個比較特殊,第一個是kWarpDriveKey,由于WarpDrive是一個Switch,它返回的是一樣bool型,因此通過三元運算符來判斷YES或NO,如果是YES,返回“Enabled”,如果是NO,則返回“Disabled”。另一個比較特殊的是WarpFactor,由于WarpFactor是一個slider,返回的是一個int型,所以通過stringValue將int型轉換為string輸出。

然后我們重載了viewDidAppear方法,在view出現時調用refreshFields方法。

接著在BIDMainViewController.m中找到flipsideViewControllerDidFinish方法,添加如下code

- (void)flipsideViewControllerDidFinish:(BIDFlipsideViewController *)controller{    [self refreshFields];    [self dismissViewControllerAnimated:YES completion:nil];}

在Main View的右下角有一個info button,點擊它會切換到flipsideView,當從flipsideView切換回來的時候,就會調用上面的這個方法,然后再次刷新Settings中的數據。

好了,編譯運行一下程序,程序啟動后,在Settings中為AppSettings中的每一項賦值,然后打開AppSettings程序,就可以看到一下類似的截圖了。

 

3)將值寫入Settings
剛才我們通過NSUserDefaults從Settings讀取了值,現在我們將學習如何在程序中設置值,然后再寫入到Settings中。

打開MainStoryboard.storyboard,在layout area中,將Flipside View Controller布局成如下樣子

將View的背景色改成Light Gray color,View的title改成“Warp Settings”,添加了2個Label,添加了一個Switch和Slider,其中,Slider的左右兩個圖片是在其Attributs inspector中設置的

然后將slider的最小值設為1,最大值設為10,當前值設為5,同樣也是在Attributes inspector中進行設置

根據View中的內容,我們可以看出是針對Settings中的switch(WarpDrive)和slider(Warp Factor),打開BIDFlipsideViewController.h,添加如下code

復制代碼
#import <UIKit/UIKit.h>@class BIDFlipsideViewController;@protocol BIDFlipsideViewControllerDelegate- (void)flipsideViewControllerDidFinish:(BIDFlipsideViewController *)controller;@end@interface BIDFlipsideViewController : UIViewController@property (weak, nonatomic) id <BIDFlipsideViewControllerDelegate> delegate;@property (weak, nonatomic) IBOutlet UISwitch *engineSwitch;@property (weak, nonatomic) IBOutlet UISlider *warpFactorSlider;- (void)refreshFields;- (IBAction)engineSwitchTapped;- (IBAction)warpSliderTouched;- (IBAction)done:(id)sender;@end
復制代碼

兩個IBOutlet自然是指向View上的Switch和Slider的,refreshFields是用來刷新Flipside上的數據的,2個IBAction,當swtich發生改變時,觸發engineSwitchTapped事件,當slider發生改變時,觸發warpSliderTouched事件。

下面就是綁定了,展開Flipside View Controller Scene

然后選中Flipside View Controller根節點,control-drag到switch上,在彈出的框中選擇engineSwitch
同樣的方法,control-drag到slider上,選中warpFactorSlider

然后綁定事件,這次在Flipside View Controller選中switch,然后control-drag到Flipside View Controller Scene中的根節點Flipside View Controller上,會彈出一個框

選中enginSwitchTapped,同學選擇slider,control-drag,選擇warpSliderTouched

好了,界面上的操作全部完成了,下面開始編碼,打開BIDFlipsideViewController.m,添加如下代碼

復制代碼
- (void)viewDidLoad{    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    [self refreshFields];}......- (void)refreshFields{    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];    self.engineSwitch.on = [defaults boolForKey:kWarpDriveKey];    self.warpFactorSlider.value = [defaults floatForKey:kWarpFactorKey];}- (IBAction)engineSwitchTapped{    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];    [defaults setBool:self.engineSwitch.on forKey:kWarpDriveKey];}- (IBAction)warpSliderTouched{    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];    [defaults setFloat:self.warpFactorSlider.value forKey:kWarpFactorKey];}
復制代碼

首先在viewDidLoad中調用refreshFields的方法,接著實現了refreshFields,用于讀取Settings中的值并顯示在界面上,然后實現了2個IBAction,第一個用于保存Swtich的值,另一個保存Slider的值,2個方法都很簡單,看代碼就能看懂了。

好,保存編譯運行程序,在主界面中點擊右下角的info button,切換到flip view

flip view上顯示了Settings中Warp Drive的值和Warp Factor的值,然后我們調整一下,將Warp Engines設為ON,然后改變一下Warp Factor的位置,例如

然后按左上角的Done,返回main view,可以看到Warp Drive和Warp Factor的值也相應發生了改變

3)設置默認值
好了,到目前位置,我們已經可以做很多事情了,在App中讀取Settings中的值,在App中改變Settings中的值并保存回Settings中,但是大家有沒有發現,當你們第一運行app時,main view中其實是空的,什么都沒有,只有當我們退出程序,在Settings中設置好值以后,再回到App中,此時main view中的值才會有。其實這個情況是正確的,但是我們更希望能夠有一個默認值存在,我們無法在Settings.bundle中設置默認值,但是NSUserDefaults為我們提供了方法,打開BIDAppDelegate.m,添加如下代碼

復制代碼
#import "BIDAppDelegate.h"#import "BIDMainViewController.h"@implementation BIDAppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{    // Override point for customization after application launch.    NSDictionary *defaults = @{kWarpDriveKey: @YES,                               kWarpFactorKey: @5,                               kFavoriteSinKey: @"Greed"};        [[NSUserDefaults standardUserDefaults] registerDefaults:defaults];    return YES;}
復制代碼

從代碼中可以看到,NSUserDefaults通過registerDefaults方法設置默認值,它的參數是一個NSDictionary,在NSDictionary設置了3個對象的默認值。好了,在重新編譯運行程序之前,請確保將模擬器中的AppSettings刪除,再編譯運行,效果如下

可以看到,Warp Drive, Warp Factor, Favorite Sin三個對象都有默認值,和我們的預期是一樣的。

4)數據的同步
相信大家現在的手機至少是ios4以上的版本了,從ios4開始,ios就支持多任務了(雖然表面上是支持的),用戶可以在多個app之間進行切換。我們這個app當然也可以,但是有一個問題,我們運行程序,app默認界面如下

接著按Home鍵,回到桌面進入Settings,為Username

然后退出Settings,再進入AppSettings,你會發現剛才輸入的username并沒有顯示出來

ok,好,我們現在就來解決這個問題。首先簡單的說一下原理,這里用到了ios的一個機制:Notification。當一個后臺的程序被激活后,它將收到一個notification:UIApplicationWillEnterForegroundNotification,表示app即將顯示到前臺來。我們首先定義一個方法,當發生notification時會調用該方法,分別打開BIDMainViewController.m和BIDFlipsideViewController.m,分別添加如下代碼

- (void)applicationWillEnterForeground:(NSNotification *)notification{    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];    [defaults synchronize];    [self refreshFields];}

NSUserDefaults的synchronize方法是用來同步Settings中的值的,當值同步完后,調用refreshFields方法,顯示到view中。

再分別為BIDMainViewController.m和BIDFlipsideViewController.m添加如下方法

復制代碼
- (void)viewWillAppear:(BOOL)animated{    [super viewWillAppear:animated];        UIApplication *app = [UIApplication sharedApplication];    [[NSNotificationCenter defaultCenter] addObserver:self                                             selector:@selector(applicationWillEnterForeground:)                                                 name:UIApplicationWillEnterForegroundNotification                                               object:app];}
復制代碼

該方法用于監聽ios發出的notification,當監聽到UIApplicationWillEnterForegroundNotification通知后,就調用applicationWillEnterForeground方法。

我們還要更新2個已經寫好的方法,engineSwitchTapped和warpSliderTouched(在BIDFlipsideViewController.m中),修改如下

復制代碼
- (IBAction)engineSwitchTapped{    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];    [defaults setBool:self.engineSwitch.on forKey:kWarpDriveKey];    [defaults synchronize];}- (IBAction)warpSliderTouched{    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];    [defaults setFloat:self.warpFactorSlider.value forKey:kWarpFactorKey];    [defaults synchronize];}
復制代碼

新增了同步,每當值發生改變,就同步一下。

我們最后還要添加一個方法,用于釋放notification,還是分別為BIDMainViewController.m和BIDFlipsideViewController.m添加如下方法

- (void)viewDidDisappear:(BOOL)animated{    [super viewDidDisappear:animated];    [[NSNotificationCenter defaultCenter] removeObserver:self];}

當view消失后(進入后臺或者程序退出),將notification釋放。

好了,再次編譯運行app,按Home鍵回到桌面,進入Settings修改值再回到AppSettings,會發現相對于的值發生了改變。

5)總結
應該說,這篇以及上一篇關于Settings的內容都已經講完了,涵蓋了絕大部分關于Settings的操作,這部分的內容在程序設計開發的過程中還是相對有用的,對我來說收獲很大。下一篇開始,我們將重點講解ios對于數據的保存功能是如何實現的,又是一個很有用的內容,每個app幾乎都會使用到,有些保存的方法其實我們已經學習過了,在下一章會重點再介紹一次,希望下一篇會很快到來,我會努力的!


AppSettings_all.zip


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 国产91丝袜在线熟 | 日韩视频在线观看免费 | 欧美成人se01短视频在线看 | 爱福利视频 | 狠狠操天天射 | 久久人添人人爽人人爽人人片av | 免费在线观看成人av | 一级成人在线 | 19禁国产精品福利视频 | 激情亚洲一区二区 | 免费一级毛片在线播放不收费 | 九九热九九爱 | 精品一区二区在线观看视频 | 久久久久久久久久综合 | 97人操| 日韩精品中文字幕在线观看 | 特级黄色一级毛片 | 国产精品免费观看视频 | 日韩黄色av网站 | 7777视频 | 成人午夜在线免费 | 一级在线| 国产精品欧美久久久久一区二区 | 在线视频观看一区二区 | 亚洲综人网 | 一级爱爱| 美国人成人在线视频 | 撅高 自己扒开 调教 | 国产精品亚洲综合一区二区三区 | 一级毛片免费高清 | 久久人人爽人人爽人人片av高清 | 精国品产一区二区三区有限公司 | 香蕉成人在线视频 | 中文字幕偷拍 | 久久精品99国产国产精 | 热re91久久精品国产99热 | 久久探花 | 久久撸视频 | 亚洲成人在线视频网站 | 久久久一区二区三区四区 | 特级黄aaaaaaaaa毛片 |