標籤:
如今,即便是最簡單的電腦程式也會包含一個喜好設定視窗,使用者可以在其中設定應用專屬的選項。在MAC OS X中,Preferences...菜單通常位於應用菜單中。選擇該功能表項目會彈出一個視窗,使用者可以在其中輸入和更改各種選項。iPhone和其他iOS裝置有一個專門的“設定”應用程式來進行各種設定,你肯定用過很多次了。
設定捆綁包
通過應用設定,使用者可以輸入和更改任何帶有設定捆綁包(settings bundle)的應用中的喜好設定。設定捆綁包是應用內建的一組檔案,用於告訴設定該應用期望得到使用者的哪些喜好設定。是執行個體:
對於iOS使用者預設設定(User Defaults)機制,設定應用充當著通用使用者介面的角色。使用者預設設定是儲存和擷取喜好設定的系統的一部分。
在iOS應用中,使用者預設設定由NSUserDefaults類實現。應用通過NSUserDefaults用索引值對的方式來讀取和儲存喜好設定資料,與通過鍵從NSDictionary對象中擷取資料一樣。不同之處在於NSUserDefaults資料會被持久儲存在檔案系統中,而不是儲存在記憶體的對象執行個體中。
應用
接下來的部分,通過建立一個簡單的應用,來實現應用設定控制應用程式。
建立應用
在Xcode中,建立Tabbed Application工程。
使用設定捆綁包
設定應用使用每個應用中設定捆綁包的內容構建出一個應用的設定視圖。如果應用沒有設定捆綁包,則設定應用不會顯示出應用程式的任何資訊。每個設定捆綁包必須包含一個名為Root.plist的屬性列表,它定義了根級喜好設定視圖。此屬性列表必須遵循一種非常嚴格的格式。
當設定應用啟動時,它會檢查每個應用程式的設定捆綁包並為包含設定捆綁包的每個應用添加設定組。
在項目中添加設定捆綁包
建立設定捆綁包,操作如
在iOS-->Resource-->Settings Bundle點擊Next,名字保留預設,最後點擊Create即可。
編輯屬性列表檔案
接下來需要編輯Root.plist檔案,具體內容如
在Item8中,引用的More.plist檔案,具體內容如
這裡需要補充說明一點:
iOS上的應用不能從其他應用的沙箱中讀取檔案。設定捆綁包並不是我們應用沙箱的一部分,而是設定應用沙箱的一部分。
設計展示介面
資料準備好之後,添加表徵圖資源,設計資料展示介面。如下
介面是通過代碼實現的,主要使用了如下幾個控制項:
@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
讀取應用中的設定
我們將使用NSUserDefaults類訪問使用者佈建。NSUserDefaults作為單例類,意味著應用中只能有一個NSUserDefaults執行個體在運行。為了訪問這個執行個體,需要調用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];}添加控制項響應事件
為SecondViewController中的UIButton,UISwitch和UISlider控制項添加監聽事件。
- (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];}//切換到“設定”應用程式-(void)settingInfoClicked{ [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];}註冊預設值
//AppDelegate.m- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. //程式啟動後的一些自訂設定 NSDictionary *defaults = @{kWarpDriveKey:@YES, kWarpFactorKey:@2, kFavoriteAlienKey:@"Vulcan" }; [[NSUserDefaults standardUserDefaults] registerDefaults:defaults]; return YES;}保證設定有效
如果現在將應用運行,查看設定資訊並按下主畫面按鈕來修改一些值。然後再按Home鍵,再重新開啟應用,結果發現設定並沒有生效。
原因在於:在iOS中,當應用正在運行時按Home鍵並不會退出該應用,而是由作業系統在後台將其暫停,這樣它就能隨時快速啟動。
在這個例子中,我們需要添加一點工作,以實現應用被喚醒時,能重新載入使用者喜好設定並重新顯示它們。
通知,時對象之間進行通訊的輕量級機制。任何對象都能定義一個或多個發送到應用通知中樞的通知。通知中樞是一個單例對象,作用在於對象之間傳送通知。
UIApplication類會發送大量的通知,大多數通知的用途從命名就能看出來,這個例子中我們就使用到了通知。
將下列代碼添加到兩個控制器的viewDidLoad方法中:
UIApplication *app = [UIApplication sharedApplication]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:app];
然後添加相應的回應程式法
-(void)applicationWillEnterForeground:(NSNotification *)notification{ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults synchronize]; [self refreshFields];}小結
本文主要講解了如何使用應用設定,如何使用NSUserDefaults讀取喜好設定,以及如何讓使用者在應用內修改喜好設定。
執行個體原始碼地址:https://github.com/CharsDavy/BridgeControl
iOS之應用設定