8UI界面传值的四种方法:
UI中界面跟界面之间值传递在iOS项目开发中非常得常见,几乎两个界面之间的跳转都伴随着值传递。
今天我总结了下,页面传值的四种方式,正向传递 逆向传递 单例传递 通知传递。
在今后的项目中会经常用到这四种方式
。
情形:我要做一个阅读器,阅读器总共有三个页面,登陆页面(ZFYViewControl)。
主页面(ZFYMainViewController) 配置界面 (ZFYConfigViewController)。
用户进入第一次进入app需要在登陆(ZFYViewControl)页面上输入用户名,输入用户名后点击登陆按钮,然后进入主页面,主页面会显示从ZFYViewControl传递过来的用户名。 在主界面中有一个进入配置(ZFYConfigViewController)页面的按钮,在配置页面有一个文本框(对应一个按钮),用来修改主页面的的字体。还有一个修改页面皮肤的按钮。
1. 正向传递
在这个情形中,从登陆页面跳转到主页面中,需要在跳转的时候将用户名传递到主页面,这里是登陆页面创建了主页面,这种值传递形势是正向传递
在主页面中定义
@property (copy, nonatomic)NSString *username;// 为了接受来自登陆页面传递过来username;
在登陆页面实例化主界面的对象
//实例化主界面
ZFYMainViewController *mvc=[[ZFYMainViewController alloc]init];
mvc.username=textfield.text; //获取文本框中的内容 将内容复制给username
[self presentViewController:mvc animated:YES completion:nil]效果图如下
2.逆向传递
这个需求涉及到配置页面,在主页面中有一个按钮进入配置页面,进入配置页面后有修改主界面字体的按钮。
主页面跟配置页面的关系是,主页面创建配置了配置页面,刚刚我们传递用户名的时候,是谁创建了谁,然后顺便把值传给谁,但是,这次反过来,是被创建的页面要传值给创建的页面,这里我们需要用的传递方法叫逆向传递。
我们点击了主页面的按钮进入配置页面,然后要将配置页面的值传递到主界面。
要传递值到主界面,那么配置页面必须要获取主界面的地址。那么就需要在进入配置页面的时候,我需要在配置页面设置一个属性来纪录主页面的地址
@property(assign ,nonatomic)id <ConfigViewControllerDelegate> delegate; //这个属性用来纪录主页面的地址
在主页面的进入配置按钮处理事件中把主页面的地址传递给了配置页面
#pragma mark 进入配置页面的点击事件
-(void)btnClick:(UIButton*)button
{
ZFYConfigViewController *zfycvc=[[ZFYConfigViewController alloc]init];
//把当前界面得指针传到zfycvc
//希望配置界面中字体改变得时候通知主界面
//这里用config页面对象去保存当前页面得指针, 为了能够在config页面能够操控main函数里面得方法.
zfycvc.delegate=self; //将主页面的地址保存到配置页面的delegate属性中
[self presentViewController:zfycvc animated:YES completion:nil];
}
这里我们已经在配置页面中纪录了主页面的地址。
//点击更换字体大小方法
-(void)btnClick:(UIButton*)button
{
//这里点击返回主页的按钮
//配置页面代理实现主页面的方法。 但是有一点,我们不知道主页面也没有给我实现changeFontSize这个方法。万一没有实现我调用的方法,那我就奔溃了。所以
我在这里制定一条协议,协议里面加上一条changeFontSize方法,你主页面必须遵守我的协议,同时要去实现我的changeFontSize方法。
[self.delegate changeFontSize:fonttextfield.text.intValue];
//返回主界面
[self dismissViewControllerAnimated:YES completion:nil];
}
在配置界面的.h文件中定义一个协议
@protocol ConfigViewControllerDelegate <NSObject>
//这是其他类必须遵守得方法
-(void)changeFontSize:(int)size;
@end
然后在主界面去遵守这个协议
@interface ZFYMainViewController : UIViewController <ConfigViewControllerDelegate>
然后实现协议中的changeFontSize方法
-(void)changeFontSize:(int)size
{
normallable.font=[UIFont systemFontOfSize:size];
}
到此逆向传递就结束了 附上逆向传递的效果图
点击返回主页 我们把默认的16号字体已经修改成了12号字体
3.单例传值
现在我们有这样的想法,我们在任何页面需要获取一个对象里面的属性,就类似于全局变量,在所有的函数体里面你都可以接收这个变量。
我们需要新建一个类,在这个类中我们写一个类方法来创建类的对象,有一个 属性,用来保存信息
@property(copy,nonatomic)NSString *appinfo;
+(id)shareInstance
{
//第一次 dc为空。会申请一个对象
// 以后执行:dc不为空 直接返回以前创建得对象
static ZFYDataCenter *dc=nil;
if (dc==nil) {
dc=[[ZFYDataCenter alloc]init];
}
return dc;}
然后我们在AppDelegate 里面给appinfo赋予初值
ZFYDataCenter *dc=[ZFYDataCenter shareInstance];
dc.appinfo=@"前锋一枝花版权,翻版必究";
就这样,在任何页面我们都可以去使用appinfo属性。
使用的时候只需要使用shareInstance方法创建,然后
ZFYDataCenter *dc=[ZFYDataCenter shareInstance];
UILabel *appinfolable=[[UILabel alloc]initWithFrame:CGRectMake(100, 200, 200, 30)];
appinfolable.backgroundColor=[UIColor whiteColor];
appinfolable.text=dc.appinfo;
[self.view addSubview:appinfolable];
我们来个效果图,表示在配置页面已经获取了appinfo值
4.通知传递。
在配置页面中,我们添加了一个换肤的按钮
这个按钮可以通知我想要更换皮肤的页面去换皮肤。
在配置页面的单击事件中
-(void)btnChangeSkin:(UIButton*)button
{
//发出换肤得通知
//1.参数name :通知得名字
//2.参数object 要发给那个对象 nil表示所有的对象
//3.userInfo 通知附加得信息,皮肤颜色 是一个字典类型
//NSLog(@"在这里点击了换肤");
//default 表示单例模式
NSNotificationCenter *nc=[NSNotificationCenter defaultCenter];
[nc postNotificationName:@"changeSkin" object:nil userInfo:@{@"skincolor":@"red"}];
}
我们在主界面接收配置页面发出的换皮肤的通知
//获取换肤得通知
NSNotificationCenter *nc=[NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(dealChangeSkin:) name:@"changeSkin" object:nil];
//然后去实现换皮肤的方法:
-(void)dealChangeSkin:(NSNotification*)notification
{
//获取附件中得通知内容
NSString *skincolor=notification.userInfo[@"skincolor"];
if ([skincolor isEqualToString:@"red"])
{
self.view.backgroundColor=[UIColor redColor];
}
//换完了皮肤回到主页面
[self dismissViewControllerAnimated:YES completion:nil];
}
在这里我们已经把主界面的皮肤换成了红色的 ,如果你还想再换其他页面的皮肤。你只需要,再接收下通知,实现下通知的方法。
页面传值的四种方式都完了。