iOS之应用偏好设置
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
如今,即便是最簡(jiǎn)單的計(jì)算機(jī)程序也會(huì)包含一個(gè)偏好設(shè)置窗口,用戶可以在其中設(shè)置應(yīng)用專屬的選項(xiàng)。在MAC OS X中,Preferences...菜單通常位于應(yīng)用菜單中。選擇該菜單項(xiàng)會(huì)彈出一個(gè)窗口,用戶可以在其中輸入和更改各種選項(xiàng)。iPhone和其他iOS設(shè)備有一個(gè)專門(mén)的“設(shè)置”應(yīng)用程序來(lái)進(jìn)行各種設(shè)置,你肯定用過(guò)很多次了。
設(shè)置捆綁包
通過(guò)應(yīng)用設(shè)置,用戶可以輸入和更改任何帶有設(shè)置捆綁包(settings bundle)的應(yīng)用中的偏好設(shè)置。設(shè)置捆綁包是應(yīng)用自帶的一組文件,用于告訴設(shè)置該應(yīng)用期望得到用戶的哪些偏好設(shè)置。下圖是實(shí)例效果圖:
? ? ? ?
對(duì)于iOS用戶默認(rèn)設(shè)置(User Defaults)機(jī)制,設(shè)置應(yīng)用充當(dāng)著通用用戶界面的角色。用戶默認(rèn)設(shè)置是保存和獲取偏好設(shè)置的系統(tǒng)的一部分。
在iOS應(yīng)用中,用戶默認(rèn)設(shè)置由NSUserDefaults類實(shí)現(xiàn)。應(yīng)用通過(guò)NSUserDefaults用鍵值對(duì)的方式來(lái)讀取和保存偏好設(shè)置數(shù)據(jù),與通過(guò)鍵從NSDictionary對(duì)象中獲取數(shù)據(jù)一樣。不同之處在于NSUserDefaults數(shù)據(jù)會(huì)被持久保存在文件系統(tǒng)中,而不是存儲(chǔ)在內(nèi)存的對(duì)象實(shí)例中。
應(yīng)用
接下來(lái)的部分,通過(guò)創(chuàng)建一個(gè)簡(jiǎn)單的應(yīng)用,來(lái)實(shí)現(xiàn)應(yīng)用設(shè)置控制應(yīng)用程序。
創(chuàng)建應(yīng)用
在Xcode中,創(chuàng)建Tabbed Application工程。
使用設(shè)置捆綁包
設(shè)置應(yīng)用使用每個(gè)應(yīng)用中設(shè)置捆綁包的內(nèi)容構(gòu)建出一個(gè)應(yīng)用的設(shè)置視圖。如果應(yīng)用沒(méi)有設(shè)置捆綁包,則設(shè)置應(yīng)用不會(huì)顯示出應(yīng)用程序的任何信息。每個(gè)設(shè)置捆綁包必須包含一個(gè)名為Root.plist的屬性列表,它定義了根級(jí)偏好設(shè)置視圖。此屬性列表必須遵循一種非常嚴(yán)格的格式。
當(dāng)設(shè)置應(yīng)用啟動(dòng)時(shí),它會(huì)檢查每個(gè)應(yīng)用程序的設(shè)置捆綁包并為包含設(shè)置捆綁包的每個(gè)應(yīng)用添加設(shè)置組。
在項(xiàng)目中添加設(shè)置捆綁包
新建設(shè)置捆綁包,操作如下圖
在iOS-->Resource-->Settings Bundle點(diǎn)擊Next,名字保留默認(rèn),最后點(diǎn)擊Create即可。
編輯屬性列表文件
接下來(lái)需要編輯Root.plist文件,具體內(nèi)容如下圖
在Item8中,引用的More.plist文件,具體內(nèi)容如下圖
這里需要補(bǔ)充說(shuō)明一點(diǎn):
iOS上的應(yīng)用不能從其他應(yīng)用的沙盒中讀取文件。設(shè)置捆綁包并不是我們應(yīng)用沙盒的一部分,而是設(shè)置應(yīng)用沙盒的一部分。
設(shè)計(jì)展示界面
數(shù)據(jù)準(zhǔn)備好之后,添加圖標(biāo)資源,設(shè)計(jì)數(shù)據(jù)展示界面。效果圖如下
? ??
界面是通過(guò)代碼實(shí)現(xiàn)的,主要使用了如下幾個(gè)控件:
@interface?FirstViewController?()@property?(nonatomic,?strong)?UILabel?*officerLabel; @property?(nonatomic,?strong)?UILabel?*authorizationCodeLabel; @property?(nonatomic,?strong)?UILabel?*rankLabel; @property?(nonatomic,?strong)?UILabel?*warpDriveLabel; @property?(nonatomic,?strong)?UILabel?*warpFactorLabel; @property?(nonatomic,?strong)?UILabel?*favoriteTeaLabel; @property?(nonatomic,?strong)?UILabel?*favoriteCaptainLabel; @property?(nonatomic,?strong)?UILabel?*favoriteGadgetLabel; @property?(nonatomic,?strong)?UILabel?*favoriteAlienLabel;@end @interface?SecondViewController?()@property?(nonatomic,?strong)?UISwitch?*engineSwitch; @property?(nonatomic,?strong)?UISlider?*warpFactorSlider; @property?(nonatomic,?strong)?UIButton?*settingInfo;@end讀取應(yīng)用中的設(shè)置
我們將使用NSUserDefaults類訪問(wèn)用戶設(shè)置。NSUserDefaults作為單例類,意味著應(yīng)用中只能有一個(gè)NSUserDefaults實(shí)例在運(yùn)行。為了訪問(wèn)這個(gè)實(shí)例,需要調(diào)用standardUserDefaults。
鍵宏定義
#ifndef?BridgeControl_Constants_h#define?BridgeControl_Constants_h#define?kOfficerKey?@"officer"#define?kAuthorizationCodeKey?@"authorizationCode"#define?kRankKey?@"rank"#define?kWarpDriveKey?@"warp"#define?kWarpFactorKey?@"warpFactor"#define?kFavoriteTeaKey?@"favoriteTea"#define?kFavoriteCaptionKey?@"favoriteCaptain"#define?kFavoriteGadgetKey?@"favoriteGadget"#define?kFavoriteAlienKey?@"favoriteAlien"#endif更新主視圖控制器
//FirstViewController.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.officerLabel.text?=?[defaults?objectForKey:kOfficerKey];self.authorizationCodeLabel.text?=?[defaults?objectForKey:kAuthorizationCodeKey];self.rankLabel.text?=?[defaults?objectForKey:kRankKey];self.warpDriveLabel.text?=?[defaults?boolForKey:kWarpDriveKey]???@"engaged"?:?@"Disabled";self.warpFactorLabel.text?=?[[defaults?objectForKey:kWarpFactorKey]?stringValue];self.favoriteTeaLabel.text?=?[defaults?objectForKey:kFavoriteTeaKey];self.favoriteCaptainLabel.text?=?[defaults?objectForKey:kFavoriteCaptionKey];self.favoriteGadgetLabel.text?=?[defaults?objectForKey:kFavoriteGadgetKey];self.favoriteAlienLabel.text?=?[defaults?objectForKey:kFavoriteAlienKey]; } //SecondViewController.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]; }添加控件響應(yīng)事件
為SecondViewController中的UIButton,UISwitch和UISlider控件添加監(jiān)聽(tīng)事件。
-?(void)engineSwitchTapped?{NSUserDefaults?*defaults?=?[NSUserDefaults?standardUserDefaults];[defaults?setBool:self.engineSwitch.on?forKey:kWarpDriveKey];[defaults?synchronize]; }-?(void)warpSliderTouched?{NSUserDefaults?*defaults?=?[NSUserDefaults?standardUserDefaults];[defaults?setFloat:self.warpFactorSlider.value?forKey:kWarpFactorKey];[defaults?synchronize]; } //切換到“設(shè)置”應(yīng)用程序-(void)settingInfoClicked{[[UIApplication?sharedApplication]?openURL:[NSURL?URLWithString:UIApplicationOpenSettingsURLString]]; }注冊(cè)默認(rèn)值
//AppDelegate.m-?(BOOL)application:(UIApplication?*)application?didFinishLaunchingWithOptions:(NSDictionary?*)launchOptions?{//?Override?point?for?customization?after?application?launch.????//程序啟動(dòng)后的一些自定義設(shè)置NSDictionary?*defaults?=?@{kWarpDriveKey:@YES,kWarpFactorKey:@2,kFavoriteAlienKey:@"Vulcan"???};[[NSUserDefaults?standardUserDefaults]?registerDefaults:defaults];????return?YES; }保證設(shè)置有效
如果現(xiàn)在將應(yīng)用運(yùn)行,查看設(shè)置信息并按下主屏幕按鈕來(lái)修改一些值。然后再按Home鍵,再重新打開(kāi)應(yīng)用,結(jié)果發(fā)現(xiàn)設(shè)置并沒(méi)有生效。
原因在于:在iOS中,當(dāng)應(yīng)用正在運(yùn)行時(shí)按Home鍵并不會(huì)退出該應(yīng)用,而是由操作系統(tǒng)在后臺(tái)將其暫停,這樣它就能隨時(shí)快速啟動(dòng)。
在這個(gè)例子中,我們需要添加一點(diǎn)工作,以實(shí)現(xiàn)應(yīng)用被喚醒時(shí),能重新加載用戶偏好設(shè)置并重新顯示它們。
通知,時(shí)對(duì)象之間進(jìn)行通信的輕量級(jí)機(jī)制。任何對(duì)象都能定義一個(gè)或多個(gè)發(fā)送到應(yīng)用通知中心的通知。通知中心是一個(gè)單例對(duì)象,作用在于對(duì)象之間傳送通知。
UIApplication類會(huì)發(fā)送大量的通知,大多數(shù)通知的用途從命名就能看出來(lái),這個(gè)例子中我們就使用到了通知。
將下列代碼添加到兩個(gè)控制器的viewDidLoad方法中:
UIApplication?*app?=?[UIApplication?sharedApplication];[[NSNotificationCenter?defaultCenter]?addObserver:self?selector:@selector(applicationWillEnterForeground:)?name:UIApplicationWillEnterForegroundNotification?object:app];然后添加相應(yīng)的響應(yīng)方法
-(void)applicationWillEnterForeground:(NSNotification?*)notification{NSUserDefaults?*defaults?=?[NSUserDefaults?standardUserDefaults];[defaults?synchronize];[self?refreshFields]; }小結(jié)
本文主要講解了如何使用應(yīng)用設(shè)置,如何使用NSUserDefaults讀取偏好設(shè)置,以及如何讓用戶在應(yīng)用內(nèi)修改偏好設(shè)置。
?
實(shí)例源代碼地址:https://github.com/CharsDavy/BridgeControl
?
轉(zhuǎn)載于:https://my.oschina.net/chars/blog/603451
總結(jié)
以上是生活随笔為你收集整理的iOS之应用偏好设置的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 设计模式(结构型模式)——装饰模式(De
- 下一篇: redis命令 举例