(9) iphone 開發 AppSettings , 系統setting與應用程序setting間的數據控制

引言:以手機爲例, 當你在用一款軟件聽音樂時,會發現手機自帶的大小聲控制鍵和播放軟件自帶大小聲控制鍵都可對聲音進行大小聲控制,而且他們的動作都會保持一致。那就讓我們一探究竟吧!


一:設置束(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


2)創建後運行結果:



三:具體的程序分析

1)首先創建一個應用程序:


2)向主屏幕(程序一開始最先顯示的視圖)  拖控件:


3)向副視圖(這裏的作用是與系統Setting一樣後臺控制主屏幕)  添加控件:


四:  首先看到的是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)作用的體現)。

程序結果:





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章