• iOS 页面间几种传值方式(属性,代理,block,单例,通知)


    iOS 页面间几种传值方式(属性,代理,block,单例,通知)

    姜糖水 2015-05-03 52 阅读

    第二个视图控制器如何获取第一个视图控制器的部分信息

    例如 :第二个界面中的lable显示第一个界面textField中的文本

    这就需要用到属性传值、block传值

    那么第一个视图控制器如何获的第二个视图控制器的部分信息

    例如:第一个界面中的lable显示第二个界面textField中的文本

    这就需要使用代理传值

    页面间传值有八大传值方式,下面我们就简单介绍下页面间常用的五种传值方式:

    (一)属性传值

    第二个界面中的lable显示第一个界面textField中的文本

    首先我们建立一个RootViewControllers和一个DetailViewControllers,在DetailViewControllers中声明一个textString属性,用于接收传过来的字符串,

    同时创建一个Lable用来显示传过的字符串

    在RootViewControllers上引入DetailViewControllers同时声明一个textField属性用来输入字符串

    然后在RootViewControllers上我们创建并添加一个button,当点击button时响应相应方法进行视图间的切换完成视图间的传值

    (二)Block传值

    block传值也是从第二个界面给第一个界面传值

    首先我们在DetailViewcontrollers的.h文件中,属性

    在RootViewControllers的.m文件中,其他不变,在button的响应方法里我们为block属性赋值完成block传值

    (三)代理传值

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

    首先在DetailViewControllers.h文件中我们创建协议方法

    在DetailViewControllers的.m中我们判定代理对象存在时,为其绑定相应方法

    RootViewControllers的.m文件中我们指定代理并让其执行代理的方法

    (四)单例传值

    单例传值(实现共享)

    AppStatus.h  创建一个单例类 AppStatus

    复制代码
     #import <Foundation/Foundation.h>
     
     @interface AppStatus : NSObject
     {
         NSString *_contextStr;
     }
     
     @property(nonatomic,retain)NSString *contextStr;
     
     +(AppStatus *)shareInstance;
     
     @end
    复制代码

    AppStatus.m

    复制代码
     #import "AppStatus.h"
     
     @implementation AppStatus
     
     @synthesize contextStr = _contextStr;
     
     static AppStatus *_instance = nil;
     
     +(AppStatus *)shareInstance
     {
         if (_instance == nil)
         {
             _instance = [[super alloc]init];
         }
         return _instance;
     }
     
     -(id)init
     {
         if (self = [super init])
         {
             
         }
         return self;
     }
     
     -(void)dealloc
     {
         [super dealloc];
     }
     
     @end
    复制代码

    RootViewController.h

    复制代码
     #import "RootViewController.h"
     #import "DetailViewController.h"
     #import "AppStatus.h"
     
     @interface RootViewController ()
     
     @end
     
     @implementation RootViewController
     
     -(void)loadView
     {
         //核心代码 
         UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
         btn.frame = CGRectMake(0, 0, 100, 30);
         [btn setTitle:@"Push" forState:0];
         [btn addTarget:self action:@selector(pushAction:) forControlEvents:UIControlEventTouchUpInside];
         [self.view addSubview:btn];
     }
     
     -(void)pushAction:(id)sender
     {
         tf = (UITextField *)[self.view viewWithTag:1000];
     
      //单例传值  将要传递的信息存入单例中(共享中)
       //  [[AppStatus shareInstance]setContextStr:tf.text]; 跟下面这种写法是等价的
         [AppStatus shareInstance].contextStr = tf.text;
         //导航push到下一个页面
         //pushViewController 入栈引用计数+1,且控制权归系统
         DetailViewController *detailViewController = [[DetailViewController alloc]init];
     
         //导航push到下一个页面
         [self.navigationController pushViewController:detailViewController animated:YES];
         [detailViewController release];
     } 
     
     @end
    复制代码

    DetailViewController.h

    复制代码
     #import <UIKit/UIKit.h>
     @protocol ChangeDelegate;//通知编译器有此代理
     
     @interface DetailViewController : UIViewController
     {
         UITextField *textField;
     }
     
     @end
    复制代码

    DetailViewController.m

    复制代码
     #import "DetailViewController.h"
     #import "AppStatus.h"
     
     @interface DetailViewController ()
     
     @end
     
     @implementation DetailViewController
     
     @synthesize naviTitle = _naviTitle;
     
     -(void)loadView
     {
         self.view = [[[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 480)]autorelease];
     
         //单例
         self.title = [AppStatus shareInstance].contextStr;
         textField = [[UITextField alloc]initWithFrame:CGRectMake(100, 100, 150, 30)];
         textField.borderStyle = UITextBorderStyleLine;
         [self.view addSubview:textField];
         [textField release];
     
         UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDonetarget:self action:@selector(doneAction:)];
         self.navigationItem.rightBarButtonItem = doneItem;
         [doneItem release];
     }
     
     //这个方法是执行多遍的  相当于刷新view
     -(void)viewWillAppear:(BOOL)animated
     {
         [super viewWillAppear:animated];
         tf = (UITextField *)[self.view viewWithTag:1000];
         tf.text = [AppStatus shareInstance].contextStr;
     }
     
     //pop回前一个页面
     -(void)doneAction:(id)sender
     {
         //单例传值
         [AppStatus shareInstance].contextStr = textField.text;
         [self.navigationController popToRootViewControllerAnimated:YES];
     }
    复制代码

    (五)通知传值

    谁要监听值的变化,谁就注册通知  特别要注意,通知的接受者必须存在这一先决条件

    A页面RootViewController.h

    复制代码
     #import <UIKit/UIKit.h>
     #import "DetailViewController.h"
     @interface RootViewController : UIViewController<ChangeDelegate>
     {
         UITextField *tf;
     }
     @end
    复制代码

    A页面RootViewController.m

    复制代码
     #import "IndexViewController.h"
     #import "DetailViewController.h"
     #import "AppStatus.h"
     
     @implementation IndexViewController
     
     -(void)dealloc
     {
         [[NSNotificationCenter defaultCenter] removeObserver:self
                                                         name:@"CHANGE_TITLE" object:nil];
         [super dealloc];
     }
     
     -(id)init
     {
         if (self = [super init])
         {
             [[NSNotificationCenter defaultCenter] addObserver:self
                                                      selector:@selector(change:)
                                                          name:@"CHANGE_TITLE"
                                                        object:nil];
         }
         return self;
     }
     
     -(void)change:(NSNotification *)aNoti
     {
         // 通知传值
         NSDictionary *dic = [aNoti userInfo];
         NSString *str = [dic valueForKey:@"Info"];
         
         UITextField *tf =  (UITextField *)[self.view viewWithTag:1000];
         tf.text = str;
     }
      
     -(void)viewWillAppear:(BOOL)animated
     {
         [super viewWillAppear:animated];
         /*
         // 单例传值
         UITextField *tf =  (UITextField *)[self.view viewWithTag:1000];
         tf.text = [AppStatus shareInstance].contextStr;
         */
     }
     
     @end
    复制代码

    DetailViewController.h

    复制代码
     #import <UIKit/UIKit.h>
     @protocol ChangeDelegate;//通知编译器有此代理
     
     @interface DetailViewController : UIViewController
     {
         UITextField *textField;
     }
     @end
    复制代码

    DetailViewController.m

    复制代码
     #import "DetailViewController.h"
     #import "AppStatus.h"
     
     @implementation DetailViewController
     @synthesize naviTitle = _naviTitle;
     
     -(void)loadView
     {
         UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDonetarget:self action:@selector(doneAction:)];
         self.navigationItem.rightBarButtonItem = doneItem;
         [doneItem release];
     }
     
     // pop回前一个页面
     -(void)doneAction:(id)sender
     {
     NSDictionary *dic = [NSDictionary dictionaryWithObject:textField.text forKey:@"Info"];
     
     [[NSNotificationCenter defaultCenter] postNotificationName:@"CHANGE_TITLE" object:nil userInfo:dic];
     
     [self.navigationController popViewControllerAnimated:YES];
     
     }
  • 相关阅读:
    Python: 通过 pip 安装第三方包后依然不能 import
    jar命令
    vim中删除^M
    Linux 非互联网环境安装依赖包
    安装rpm包时提示错误:依赖检测失败的解决方法
    python3.5安装
    yum配置安装 及报错
    统计数组元素出现的次数
    插入法排序
    选择法排序
  • 原文地址:https://www.cnblogs.com/leo23/p/5051892.html
Copyright © 2020-2023  润新知