您的位置:首页 > 移动开发 > IOS开发

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

2016-03-17 14:46 447 查看
通知传值

通知是在跳转控制器之间常用的传值代理方式。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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息