🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
引言:以手机为例, 当你在用一款软件听音乐时,会发现手机自带的大小声控制键和播放软件自带大小声控制键都可对声音进行大小声控制,而且他们的动作都会保持一致。那就让我们一探究竟吧! 一:设置束(settings bundle),设置束是构建到应用程序中的一组plist文件,是他向系统设置(Setting:系统设置(Setting)图标是在设备上默认有一个图标,位于屏幕上)的应用程序发送消息 ,Setting应用程序会自动创建用户界面。在ios应用程序当中,用户默认设置是由NSUserDefault类来实现,NSUserDefault类可以看做是系统Setting与应用程序用户Setting间沟通的桥梁,NSUserDefault类也是用键值来存取数据的,其特殊的一点就是NSUserDefault是将数据持久化的保存到文件系统中,而不是保存到内存的对象实例中。 二: ### 1) 创建Setting:Setting.bundle展开后需加入的plist文件模版,点击http://download.csdn.net/detail/dongstone/4229357 ![](https://box.kancloud.cn/2016-06-12_575cce8075657.gif) ### 2)创建后运行结果: ![](https://box.kancloud.cn/2016-06-12_575cce80b0683.png) ### 三:具体的程序分析 ### 1)首先创建一个应用程序: ![](https://box.kancloud.cn/2016-06-12_575cce80e2d55.png) ### 2)向主屏幕(程序一开始最先显示的视图)  拖控件: ![](https://box.kancloud.cn/2016-06-12_575cce811ec86.png) ### 3)向副视图(这里的作用是与系统Setting一样后台控制主屏幕)  添加控件: ![](https://box.kancloud.cn/2016-06-12_575cce815798e.png) ### 四:  首先看到的是xcode模板为我们生成了两个视图控制器MainViewController和FlipsideViewController。 在这里MainViewController的作用相当与音乐播放器的前台,而FlipsideViewController与系统Setting的作用是一样的,对前台数据进行操作。当然这样举例也不是很严谨,因为有的播放器程序前台视图界里面完全可以执行例如控制声音大小的简单操作,或者弹窗控制,做了更多优化。在这里为了化繁为简,突出它的具体特性,讲解一个小程序。 1)MainViewController.h ~~~ #import "FlipsideViewController.h" @interface MainViewController : UIViewController <FlipsideViewControllerDelegate> { UILabel *usernamelable; UILabel *passwordlable; UILabel *warplable; UILabel *warpfactorlable; } - (IBAction)showInfo:(id)sender; @property (nonatomic, strong) IBOutlet UILabel *usernamelable; @property (nonatomic, strong) IBOutlet UILabel *passwordlable; @property (nonatomic, strong) IBOutlet UILabel *warpDrivelable; @property (nonatomic, strong) IBOutlet UILabel *warpfactorlable; //自定义方法用于刷新数据 - (void)refreshFields; //自定义方法用于后台返回响应 -(void)backupdata; @end ~~~ MainViewController.m ~~~ #import "MainViewController.h" @implementation MainViewController @synthesize usernamelable; @synthesize passwordlable; @synthesize warpDrivelable; @synthesize warpfactorlable; - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark obtain source from plist //刷新方法: -(void)refreshFields{ //与系统设置(Setting.bundle)相连,可相互传递数据 NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults]; //从沙盒里取值,这里的key是plist文件里定义好的 usernamelable.text=[defaults objectForKey:@"name"]; passwordlable.text=[defaults objectForKey:@"password"]; warpDrivelable.text=[defaults boolForKey:@"wrap"]?@"Enable":@"Disable"; warpfactorlable.text=[[defaults objectForKey:@"slider"] stringValue] ; NSLog(@"%@",[[defaults objectForKey:@"slider"] stringValue]); } #pragma mark - View lifecycle //视图每次切换呈现时都会调用这个方法,这里需要注意的就是当按下iphone的home键时程序进入后台,程序再走到前台时并不会调用这个方法。 -(void)viewDidAppear:(BOOL)animated{ //刷新 [self refreshFields]; [super viewDidAppear:animated]; } - (void)viewDidLoad { //得到应用程序的单例对象 UIApplication *app=[UIApplication sharedApplication]; //将当前类作为观察着,来接收应用程序的通知(从后台走到前台)来响应backupdata方法 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(backupdata) name:UIApplicationWillEnterForegroundNotification object:app]; [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } -(void)backupdata{ NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults]; //同步系统,当从手机自带系统设置更改,程序从后台回到前台时将系统(磁盘)的setting数据同步到应用程序的Setting。 [defaults synchronize]; [self refreshFields]; } - (void)viewDidUnload { [self setUsernamelable:nil]; [self setPasswordlable:nil]; [self setWarpDrivelable:nil]; [self setWarpfactorlable:nil]; [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); } #pragma mark - Flipside View - (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller { [self dismissModalViewControllerAnimated:YES]; } - (IBAction)showInfo:(id)sender { FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"FlipsideViewController" bundle:nil]; controller.delegate = self; //设置view的过渡模式 controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; //呈现模式(效果就是切换视图)。 [self presentModalViewController:controller animated:YES]; } @end ~~~ 2)FlipsideViewController.h ~~~ #import <UIKit/UIKit.h> @class FlipsideViewController; @protocol FlipsideViewControllerDelegate - (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller; @end @interface FlipsideViewController : UIViewController { UISwitch *_MySwitch; UISlider *_MySilder; } @property (weak, nonatomic) IBOutlet id <FlipsideViewControllerDelegate> delegate; @property (nonatomic, strong) IBOutlet UISwitch *MySwitch; @property (nonatomic, strong) IBOutlet UISlider *MySilder; - (IBAction)done:(id)sender; //自定义方法视图从后台返回时将被调用。 -(void)applicationWillEnterForeground; //用于改变系统数据 - (IBAction)myswitchchange:(id)sender; - (IBAction)mysliderchange:(id)sender; //刷新数据 -(void)refreshField; @end ~~~ FlipsideViewController.m ~~~ #import "FlipsideViewController.h" @implementation FlipsideViewController @synthesize delegate = _delegate; @synthesize MySwitch = _MySwitch; @synthesize MySilder = _MySilder; - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle - (void)viewDidLoad { //得到应用程序对象用于做通知的过滤条件 UIApplication *app=[UIApplication sharedApplication]; //添加观察者为self,接收应用程序的通知,响应方法为applicationWillEnterForeground。(也就是程序从后台进入前台) [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:app]; //刷新数据 [self refreshField]; [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (void)viewDidUnload { [self setMySwitch:nil]; [self setMySilder:nil]; [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); } -(void)applicationWillEnterForeground{ NSUserDefaults *defau=[[NSUserDefaults alloc]init]; //同步系统,刷新系统(磁盘)的Setting [defau synchronize]; [self refreshField]; } - (IBAction)myswitchchange:(id)sender { NSUserDefaults *defau=[[NSUserDefaults alloc] init]; [defau setBool:self.MySwitch.on forKey:@"wrap"]; //同步系统,刷新系统(磁盘)的setting [defau synchronize]; } - (IBAction)mysliderchange:(id)sender { NSUserDefaults *defau=[[NSUserDefaults alloc] init]; [defau setFloat:self.MySilder.value forKey:@"slider"]; //同步系统,刷新系统(磁盘)的setting [defau synchronize]; } -(void)refreshField{ NSUserDefaults *defua=[[NSUserDefaults alloc] init]; //同步系统,刷新系统(磁盘)的setting [defua synchronize]; self.MySwitch.on=[defua boolForKey:@"wrap"]; self.MySilder.value=[defua floatForKey:@"slider"]; } #pragma mark - Actions - (IBAction)done:(id)sender { [self.delegate flipsideViewControllerDidFinish:self]; } @end ~~~ ### 3)小结:这个小程序里也包含了很多别的知识如:系统自动生成的部分,页面间的反转切换方法的调用,信息传递等。以前写过,有详细讲解(点击参见:[(7)---02 iphone 开发 数据传递 : 页面切换与数据的反向传递以及协议(protocol)作用的体现](http://blog.csdn.net/dongstone/article/details/7457320))。 ### 程序结果: ![](https://box.kancloud.cn/2016-06-12_575cce8198ccc.gif)