用户默认设置是应用程序首选项的一部分,由NSUserDefaults类实现,用户保存和获取首选项。与NSDictonary获取数据一样,实用键值读取和保存首选项数据。不同之处是NSUserDefaults数据被持久化到文件系统中,而没有存储在内存中的对象实例中。
Settings应用程序的优势之一是无需为首选项设计用户界面。创建属性列表来定义应用程序的可用设置后,Settings应用程序会自动创建用户界面。但是使用Settings应用程序也有一些限制,当应用程序正在运行时,用户可能需要更改的任何首选项都不应该受到Settings应用程序的限制,因为用户可能被强制退出应用程序以更改这些值。互动式应用程序,通常应该提供首选项视图,使用户更改设置时无需退出应用程序。
下面开始这一章的练习。
创建新的项目,这次使用的是Utility Application模板。我创建的项目名称是:IP_10Seting
这个模板从来没有使用过,首先先来熟悉一下该模板。该模板创建出来的应用程序有一个主视图和一个辅助试图,点击主视图中的信息按钮会进入辅助试图,点击辅助试图中的Done按钮会返回主视图。
在这个项目中,你会发现没有Classes文件夹,因为事先这种类型的应用程序需要许多文件,该模板已经将这些文件组织到一些分组中,展开文件夹Main View、Flipside View和Application Controllers,然后将Resources也打开。然后就会看到在每一个文件夹下面会自动对应几个类文件。组成主视图的所有类,包括试图控制器和一个UIView子类,都包含在Main View文件夹中。事先flipside试图所需要的源代码文件都包含在Flipside View文件夹中,最后应用程序委托和控制器类都包含在Application Controllers文件夹中。
打开MainWindow.xib,将主视图更改为列表模式,点击Root View Controller,View,light info button并在此上apple+4,在type中选择info dark这样主视图中的信息按钮就会变成黑色,这样在白色背景下面就会有好的显示效果。
更改info.plist文件,添加图标。
在根目录上面(就是点IP_10Seting)创建新项目,选择Settings Bundle,创建一个新的Bundle(用默认的名字)。
创建属性列表时要用固定的模式,在创建的Bundle中已经存在了一个Root.plist文件,我们对这个文件进行修改就好了。
打开Root.plist文件,在最上面的Title里修改你Setting的名字。SettingsTable先不用管。在PreferenceSpecifiers项下,有许都的项目,删除2,3,4项。然后展开1,修改Title,这个Title会显示在Settings里面。然后在Item1下面在添加一项,默认是string类型,修改为Dictionary,然后向里面添加5项。Type/PSTextFieldSpecifier,Title/Username,Key/username,AutocapitalizetionType/None,AutocorrectionType/No。PSTextFieldSpecifier说明我们希望在该文本字段中编辑此设置。AutocapitalizetionType指的是该文本字段不要尝试自动大写用户输入的内容。AutocorrectionType这个是告诉Settings不需要自动更正输入到该文本中的值。
到此都可以运行一下看看结果了。
下面添加安全字段设置。
添加一新项,简单的方法就是直接复制item 2然后粘贴就好了,修改item 3中的项。
Type/PSTextFieldSpecifier,Title/Pasword,Key/pasword,AutocapitalizetionType/None,AutocorrectionType/No,IsSecure/Boolean类选中,这样输入的密码就要被点所代替。
添加多值字段。还利用上面的方法,复制一个。
Type/PSMultiValueSpecifier,Title/Protocol,Key/protocol,添加两个Array类型的值。Titles和Values,其中Titles是显示在Settings中的值,而values是显示的值对应的一个值。DefaultValue/1,这个是启动的时候默认的值。
添加开关设置。继续复制、粘贴、修改。
Type/PSToggleSwitchSpecifier,Title/Warp Drive,Key/warp,Truue/Engaged,Falsue/Disabled,DefaultValue/Engaged。
添加滑块设置。在添加滑块设置前,让我们再创建一个分组。很简单就是复制item 1,然后粘贴就好了。(这个例子中的粘贴都是选中最后行然后粘贴,让粘贴的行成为最后的行)
修改键值。
Type/PSSliderSpecifier,Key/warpfactor,DefaultValue/5,MinimumValue/0,MaximumValue/10,MinimumValueImage/rabbit.png,MaximumValueImage/turtle.png,从前到后以此为类型,key值,默认值,最小值,最多值,slider左边显示的图标,slider右边显示的图标。
再添加一个分组,然后添加子视图设置。
所谓的添加子视图,其实就是再添加一个plist文件罢了。在复制,粘贴一行,修改键值。
Type/PSChildPaneSpecifier,Title/More Settings,File/More这个就是新的plist文件。
创建新的plist文件也有一个诀窍,我们可以复制一个Root.plist文件,粘贴然后修改名字,修改里面的项就Ok了。但是这里的复制和粘贴不能在Xcode里面完成,我们必须找到项目所在的文件夹,找到Setting.bundle然后点右键,让其显示文件夹里面的内容,在这里面进行复制粘贴操作才可。
到此该bundle创建完成,下面的就是我们怎么读出来了。
读取应用程序设置。
读取操作主要是应用NSUserDefaults类进行。
首先打开MainViewController.h。添加常量和变量。
//这里面定义的常量对应Setting.bundle里面Root.plist里面每一项的key值
#define kUsernameKey @"username"
#define kSwitch @"warp"
#define kSlider @"warpfactor"
#define kPasword @"pasword"
#define kProtocol @"protocol"
#define kSecondname @"secondname"
#define kUseraddress @"useraddress"
#define kUserBirth @"userbirth"
#define kUserPhone @"userphone"
#define kSecondProtocol @"secondprotocol"
IBOutlet UILabel *usernameLabel;
IBOutlet UILabel *paswordLabel;
IBOutlet UILabel *protocolLabel;
IBOutlet UILabel *secondname;
IBOutlet UILabel *useraddress;
IBOutlet UILabel *userbirth;
IBOutlet UILabel *userphone;
IBOutlet UILabel *secondprotocol;
IBOutlet UILabel *switchStats;
IBOutlet UILabel *sliderValue;
然后打开MainViewController.m添加三个方法。
//这个新的方法仅用于抓取标准用户默认设置,并使用我们输入到属性文件中的键值,将所有标签的文本属性设置为用户默认设置中的适当对象
-(void)refreshFields
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
usernameLabel.text = [defaults objectForKey:kUsernameKey];
paswordLabel.text = [defaults objectForKey:kPasword];
protocolLabel.text = [defaults objectForKey:kProtocol];
secondname.text = [defaults objectForKey:kSecondname];
useraddress.text = [defaults objectForKey:kUseraddress];
userbirth.text = [defaults objectForKey:kUserBirth];
userphone.text = [defaults objectForKey:kUserPhone];
secondprotocol.text = [defaults objectForKey:kSecondProtocol];
switchStats.text = [defaults objectForKey:kSwitch];
sliderValue.text = [[defaults objectForKey:kSlider]stringValue];
}
//在viewDidLoad和viewDidAppear中调用refreshfields方法,使得在视图载入时显示的字段将设置为合适的首选项值,然后在视图更新
//首选项时,显示的字段将被刷新
-(void)viewDidAppear:(BOOL)animated
{
[self refreshFields];
[super viewDidAppear:animated];
}
- (void)viewDidLoad {
[self refreshFields];
}
当然了,需要打开MainView.xib,向里面拖入适当的UILabel并且和刚才定义的变量进行关联。
现在添加辅助视图,在辅助试图我们添加一个switch和一个slider用来读取应用程序设置中的值。
打开FlipsideViewController.h,添加两个输出口。
IBOutlet UISwitch *switchshow;
IBOutlet UISlider *slidershow;
打开FlipsideViewController.m,首先引入MainViewController。
#import "MainViewController.h"
添加两个方法。
- (void)viewDidLoad
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
switchshow.on = ([[defaults objectForKey:kSwitch]isEqualToString:@"Engaged"])?YES:NO;
slidershow.value = [defaults floatForKey:kSlider];
}
//重写viewWillDisappear方法,以便在主视图再次显示之前,将控件的值填充到用户默认设置中。
- (void)viewWillDisappear:(BOOL)animated
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *prefValue = (switchshow.on)? @"Engaged": @"Disabled";
[defaults setObject:prefValue forKey:kSwitch];
[defaults setFloat:slidershow.value forKey:kSlider];
[super viewWillDisappear:animated];
}
好了,释放资源,build and go运行吧,看看结果。
源码下载