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


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

    例如 :第二个界面中的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传值

    注意:这里是 self.textField.text = aLabel.text

     在DetailViewcontrollers的调用

    self.block(self.label);

    (三)代理传值

    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];
     } 

    (五)通知传值

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

    1、注册通知

    2、通知中心发送一条消息通知,其中name前后一定要一样

    3、实现通知中心内部的方法,并实现传值

    4、消息发送完,要移除掉。(页面将要消失的时候)

    A页面RootViewController.m

    SecondViewController.m

     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    关于对象
    python *args **kwargs用法
    程序员的自我修养:链接、装载与库
    LInux高性能服务器编程:多线程编程
    Linux高性能服务器编程:多进程编程
    使用burpsuite进行手动sql注入
    selenium+webdriver 实现上传文件,方法有三种,
    burp下载
    初识burp suite
    jmeter函数助手_详情,(资源来源网络)
  • 原文地址:https://www.cnblogs.com/erdeng/p/4941245.html
Copyright © 2020-2023  润新知