iOS之界面传值(通知,属性,协议,NSUserDefaults,KVC)

通知传值
通知是在跳转控制器之间常用的传值代理方式。NSNotificationCenter提供了一种解耦的方式,就是任何对象都可以发送通知到中心,同时任何对象可以监听中心的通知。

  • 发送通知(传值页面)
//通知中心NSNotificationCenter,发送通知
 - (IBAction)changeColorAction2:(id)sender {
    UIColor *color = [UIColor greenColor];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeColorKey" object:color];
    [[self navigationController] popViewControllerAnimated:YES];
}
  • 注册通知(取值页面)
//注册通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeColor:) name:@"ChangeColorKey" object:nil];
  • 响应接收通知
//响应通知中心NSNotificationCenter
 - (void)changeColor:(NSNotification *)notification{
    if([notification object] != nil)
    {
        UIColor *color = [notification object];
        [self.view setBackgroundColor:color];
    }
}
  • 移除通知
- (void)dealloc {
    //移除通知
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"ChangeColorKey" object:nil];
}

注意:注意参数notification Observer为要删除的观察者,一定不能置为nil。

协议传值
A页面push到B页面,如果B页面的信息想回传(回调)到A页面,就用代理传值,其中B定义协议和声明代理,A确认并实现代理,A作为B的代理。

  • 在需要传值给其他类的类头文件中定义一个协议
@protocol ViewControllerAdelegate

-(void)changeBgColorFromCtrlA:(ViewControllerA *)aView withColor:(UIColor *)color;

@end
  • 在该类中声明一个代理属性
@interface ViewControllerA : UIViewController

@property( assign, nonatomic ) id< ViewControllerAdelegate > delegate;

@end
  • 在.m中实现
@implementation ViewControllerA
@synthesize delegate;
  • 在需要触发传值的方法中调用协议中的方法
//使用协议代理Delegate
-(IBAction)changeColorAction:(id)sender{
    [delegate changeBgColorFromCtrlA:self withColor:[UIColor grayColor]];
    [[self navigationController] popViewControllerAnimated:YES];
}
  • 在传值给的类中的.h文件中引用该协议
@interface ViewControllerB : UIViewController<ViewControllerAdelegate>

@end
  • 在.m中
ViewControllerA *_ViewControllerA = [stryBoard instantiateViewControllerWithIdentifier:@"ViewControllerA"];
    _ViewControllerA.delegate = self;
  • 然后实现该方法
//响应协议代理Delegate
-(void)changeBgColorFromCtrlA:(ViewControllerA *)aView withColor:(UIColor *)color{
    [self.view setBackgroundColor:color];
}

顺便附上个人写的”通知传值“和”协议传值“的全部demo

  • ViewControllerA的.h文件
// Created by Ydw on 16-03-17.
// Copyright (c) 2016年 com. All rights reserved.
//

#import <UIKit/UIKit.h>
@class ViewControllerA;

@protocol ViewControllerAdelegate

-(void)changeBgColorFromCtrlA:(ViewControllerA *)aView withColor:(UIColor *)color;

@end

@interface ViewControllerA : UIViewController

@property( assign, nonatomic ) id< ViewControllerAdelegate > delegate;

-(IBAction)changeColorAction:(id)sender;
-(IBAction)changeColorAction2:(id)sender;

@end
  • ViewControllerA的.m文件
// Created by Ydw on 16-03-17.
// Copyright (c) 2016年 com. All rights reserved.
//

#import "ViewControllerA.h"
#import "ViewControllerB.h"
@interface ViewControllerA ()

@end

@implementation ViewControllerA
@synthesize delegate;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.title = @"Ctrl A";
}

//使用协议代理Delegate
- (IBAction)changeColorAction:(id)sender {
    [delegate changeBgColorFromCtrlA:self withColor:[UIColor grayColor]];
    [[self navigationController] popViewControllerAnimated:YES];
}

//通知中心NSNotificationCenter,发送通知
- (IBAction)changeColorAction2:(id)sender {
    UIColor *color = [UIColor greenColor];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeColorKey" object:color];
    [[self navigationController] popViewControllerAnimated:YES];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
  • ViewControllerB的.h文件
// Created by Ydw on 16-03-17.
// Copyright (c) 2016年 com. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "ViewControllerA.h"
@interface ViewControllerB : UIViewController<ViewControllerAdelegate>

@end
  • ViewControllerB的.m文件
// Created by Ydw on 16-03-17.
// Copyright (c) 2016年 com. All rights reserved.
//

#import "ViewControllerB.h"

@implementation ViewControllerB

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.title = @"Ctrl B";

    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Go CtrlA" style:UIBarButtonItemStylePlain target:self action:@selector(go)];
    //注册通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeColor:) name:@"ChangeColorKey" object:nil];
}

-(void)go {
    UIStoryboard *stryBoard=[UIStoryboard storyboardWithName:@"Main" bundle:nil];
    ViewControllerA *_ViewControllerA = [stryBoard instantiateViewControllerWithIdentifier:@"ViewControllerA"];
    _ViewControllerA.delegate = self;
    [[self navigationController] pushViewController:_ViewControllerA animated:YES];
    _ViewControllerA = nil;

}

//响应协议代理Delegate
-(void)changeBgColorFromCtrlA:(ViewControllerA *)aView withColor:(UIColor *)color{
    [self.view setBackgroundColor:color];
}

//响应通知中心NSNotificationCenter
- (void)changeColor:(NSNotification *)notification{
    if([notification object] != nil)
    {
        UIColor *color = [notification object];
        [self.view setBackgroundColor:color];
    }
}

- (void)dealloc{
    //移除通知
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"ChangeColorKey" object:nil];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

属性传值
属性传值是将A页面所拥有的信息通过属性传递到B页面使用。B页面定义了一个属性,在A页面中直接通过属性赋值将A页面中的值传到B页面。(相对而言,最简单一种的传值,就不具体说明了)

  • 首先在SecondViewController视图中(即B页面)需要有一个属性用来存储传递过来的值:
@property(nonatomic,retain) NSString *firstValue;//属性传值
  • 然后MainViewController视图(即A页面)需要引用SecondViewController视图的头文件,在视图中的按钮点击事件中,通过SecondViewController的对象将需要传递的值存在firstValue中:
 - (void)buttonAction:(UIButton *)button {
    SecondViewController *second = [[SecondViewController alloc]init];
    second.firstValue = _txtFiled.text;
    [self.navigationController pushViewController:second animated:YES];
}
  • 页面跳转之后,就能在SecondViewController视图中,通过存值的属性,取用刚才传递过来的值:
[_txtFiled setText:_firstValue];//显示传过来的值,firstValue保存传过来的值

NSUserDefaults
1、NSUserDefaults记录本地一些轻量级的数据,是单例类。其通过userDefaults对象来将数据保存到NSUserDefaults的plist文件中,这个文件实际上是一个plist文件,在沙盒中的/Library/Preferences
/NSUserDefaults.plist 这个位置中。
2、NSUserDefaults支持的数据格式有:NSNumber(Integer、Float、Double),NSString,NSDate,NSArray,NSDictionary,BOOL类型。
3、NSUserDefaults是本地数据持久化的一种,可以投机取巧地进行数据传值,通过给NSUserDefaults设置一个DefaultsKey,就可以在任何页面通过DefaultsKey来取到值。简单的举例说明一下:

  • NSUserDefaults存值
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableArray *rootArray = nil;
    if ([defaults objectForKey:DefaultsKey]) {
        rootArray = [NSMutableArray arrayWithArray:[defaults objectForKey:DefaultsKey]];
    }else {
        rootArray = [NSMutableArray array];
    }
    NSDictionary *infoDictionary = @{NameKey:@"Ydw",PhoneKey: @"1314520"};
    [rootArray addObject:infoDict];
    [defaults setObject:rootArray forKey:DefaultsKey];
    [defaults synchronize];
  • NSUserDefaults取值
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSArray *rootArray = [defaults objectForKey:DefaultsKey];
    if (rootArray && rootArray.count > 0) {
        NSLog(@"%@", rootArray);
    }else {
        NSLog(@"读取数据失败!");
    }
  • NSUserDefaults删除数据
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults removeObjectForKey:DefaultsKey];
    [defaults synchronize];
    NSLog(@"数据删除成功!");

KVC
KVC是Key Value Coding的缩写,即是键值编码。在iOS中,提供了一种方法通过使用属性的名称(也就是Key)来间接访问对象的属性方法。实际上,就是通过类定义我们可以看到类的各种属性,那么使用属性的名称就能访问到类实例化后的对象的这个属性值。这个方法可以不通过getter/setter方法来访问对象的属性。
NSArray/NSSet等都支持KVC。

  • 定义一个myInformation的类
@interface myInformation : NSObject {  
    NSString *_name;  
    int      _age;  
    int      _height;  
    int      _weight;  
}  
@end  
  • 声明属性对象
@interface myViewController : UIViewController 

@property (nonatomic, retain) myInformation *information;  

@end  
  • 使用KVC读取和改变类中的属性的值
 - (void)useKVC {  
    information = [[myInformation alloc] init];    
    NSLog(@"information's init height = %@", [information valueForKey:@"height"]);  
    [information setValue:[NSNumber numberWithInt:168] forKey:@"height"];  
    NSLog(@"information's height = %@", [information valueForKey:@"height"]);  
} 
  • KVC的常用方法
- (id)valueForKey:(NSString *)key; - (void)setValue:(id)value forKey:(NSString *)key;

你可能感兴趣的:(ios,KVC,界面传值,协议传值,通知传值)