zoukankan      html  css  js  c++  java
  • iOS 中的传值方式

    一、 属性传值   将A页面所拥有的信息通过属性传递到B页面使用

    很常用的传值,也很方便,但是要拿到类的属性。例如:

    B页面定义了一个naviTitle属性,在A页面中直接通过属性赋值将A页面中的值传到B页面。

    A页面DetailViewController.h文件

    #import <UIKit/UIKit.h>

    #import "DetailViewController.h"

    @interface RootViewController :UIViewController<ChangeDelegate>

    {

        UITextField *tf;

    }

    @end


    A RootViewController.m页面实现文件

    #import "RootViewController.h"

    #import "DetailViewController.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.viewviewWithTag:1000];

        //导航push到下一个页面

        //pushViewController 入栈引用计数+1,且控制权归系统

        

        DetailViewController *detailViewController = [[DetailViewControlleralloc]init];

        //属性传值,直接属性赋值

        detailViewController.naviTitle =tf.text;

        //导航push到下一个页面

        [self.navigationControllerpushViewController:detailViewController animated:YES];

        [detailViewControllerrelease];   

    }

    B页面DetailViewController.h文件

    #import <UIKit/UIKit.h>

    @interface DetailViewController :UIViewController

    {

       UITextField *textField;

       NSString *_naviTitle;

    }

    @property(nonatomic,retain)NSString *naviTitle;

    @end

    B页面.m实现文件

    #import "DetailViewController.h"

    @interface DetailViewController ()

    @end

    @implementation DetailViewController

    @synthesize naviTitle =_naviTitle;

    -(void)loadView

    {

        self.view = [[[UIViewalloc]initWithFrame:CGRectMake(0,0320,480)]autorelease];

       self.title = self.naviTitle ;    

    }


    二、 代理传值  delegate

     

    拿不到属性怎么办?使用代理吧~

     

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

    A页面RootViewController.h文件

    #import <UIKit/UIKit.h>

    #import "DetailViewController.h"

    @interface RootViewController : UIViewController<ChangeDelegate> //继承代理,表示A类接受B类的协议

    {

        UITextField *tf;

    }

    @end


    A页面RootViewController.m实现文件

    #import "RootViewController.h"

    #import "DetailViewController.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];

        //A页面push到B页面

        [btn addTarget:self action:@selector(pushAction:) forControlEvents:UIControlEventTouchUpInside];

        [self.view addSubview:btn];

    }

     

    -(void)pushAction:(id)sender

    {

        tf = (UITextField *)[self.view viewWithTag:1000];

        //导航push到下一个页面

        //pushViewController 入栈引用计数+1,且控制权归系统

        DetailViewController *detailViewController = [[DetailViewController alloc]init]; 

     

         //代理传值

      //让当前类对象作为代理人

       detailViewController.delegate = self;

        //导航push到下一个页面

        [self.navigationController pushViewController:detailViewController animated:YES];

        [detailViewController release];   

    }

     

    //实现代理方法//需要代理人做的事情

    -(void)changeTitle:(NSString *)aStr

    {

        tf = (UITextField *)[self.view viewWithTag:1000];

        tf.text = aStr;//将从B页面传入的参数赋给A页面中的TextField

     

    }

     

     

    B页面DetailViewController.h文件

    #import <UIKit/UIKit.h>

     

    //定义协议

     

    @protocol ChangeDelegate <NSObject>

     

    -(void)changeTitle:(NSString *)aStr;//声明协议方法

     

    @end

     

    @interface DetailViewController : UIViewController

    {

        UITextField *textField;

       //定义代理

      id <ChangeDelegate> _delegate;

    }

     

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

    @end

    B页面DetailViewController.m文件

    #import "DetailViewController.h"

    @interface DetailViewController ()

    @end

    @implementation DetailViewController

    -(void)loadView

    {

        self.view = [[[UIView alloc]initWithFrame:CGRectMake(00320480)]autorelease];

     

        UIBarButtonItem *doneItem = [[UIBarButtonItemalloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDonetarget:selfaction:@selector(doneAction:)];

        self.navigationItem.rightBarButtonItem = doneItem;

        [doneItemrelease];

    }

     

    //pop回前一个页面

    -(void)doneAction:(id)sender

    {

      //若代理存在且响应了changeTitle这个方法

       if (self.delegate && [self.delegaterespondsToSelector:@selector(changeTitle:)])

        {

            //[self.delegate changeTitle:textField.text];

        //textField.text参数传给changeTitle方法  让代理,也就是A类的对象去实现这个方法

          [self.delegate changeTitle:textField.text];

            NSLog(@"%@",self.navigationController.viewControllers);

     

            [self.navigationControllerpopViewControllerAnimated:YES];

        }

    }

     


    三、 单例传值(实现共享)

     

    类只有一个对象,这时候单例很方便~


    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


    A页面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
     
    B页面DetailViewController.h

    #import <UIKit/UIKit.h>

    @protocol ChangeDelegate;//通知编译器有此代理


    @interface DetailViewController : UIViewController

    {

        UITextField *textField;

    }

    @end



    B页面DetailViewController.m

    #import "DetailViewController.h"

    #import "AppStatus.h"


    @interface DetailViewController ()


    @end


    @implementation DetailViewController

    @synthesize naviTitle = _naviTitle;


    -(void)loadView

    {

        self.view = [[[UIView alloc]initWithFrame:CGRectMake(00320480)]autorelease];

        

        //单例

        self.title = [AppStatus shareInstance].contextStr;

        

        

        textField = [[UITextField alloc]initWithFrame:CGRectMake(10010015030)];

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


    }


    Block

    几种形式的Block

        //无返回值
        void (^block1) (void);
        block1 = ^{
            NSLog(@"bock demo");
        };
        block1();
        
        //int返回类型
        int (^block2) (void);
        block2  = ^(void)
        {
            int a  = 1 ,b =1;
            int c = a+b;
            return  c;
        };
        
        //有返回 有参数
        int (^block3)(int, int)= ^(int a, int b)
        {
            int c = a +b;
            return c;
            
        };
        NSLog(@"bock=%d",block3(1,2));
        
        //有返回值,有参数并且可以修改block之外变量的block
        static int sum = 10;// __blcik and static关键字 或者 _block int sum = 10
        int (^block4) (int) =^(int a)
        {
            sum=11;
            int c = sum+a;   //此时sum就是可以修改的了,若没加static或_block关键字则不能修改block之外变量
            return c;
        };
        NSLog(@"block4= %d",block4(4));


    Block传值

    例如A(Ablock)页面的值传道B(Bblock)页面 


    在A页面中ABlock.h

    @interface Ablock : UIViewController<UITableViewDelegate,UITableViewDataSource>
    {
        UITableView *_tableview;
        UILabel *labe;
        UIImageView *imagevies;
    }
    @end


    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [_tableview deselectRowAtIndexPath:indexPath animated:YES];
        
        Bblcok *bblock = [[Bblcok alloc] initwithBlock:Block_copy(^(NSString *aBlock){    
            labe.text = aBlock;
            NSLog(@"%@",aBlock);

        })];
        

        bblock.imgeviews = imagevies.image;
        bblock.String = labe.text;
        [self.navigationController pushViewController:bblock animated:YES];
        [bblock release];
    }



    在A页面中Bblock.h

    #import <UIKit/UIKit.h>
    typedef  void (^MyBlock) (NSString *);
    @interface Bblcok : UIViewController
    {
        UIImageView *image;
        UITextField *aField;
        UIButton *aButt;
        NSString *_String;
        id _imgeviews;
        MyBlock myBlock;
    }
    @property(nonatomic,copy)MyBlock myBlock;  
    @property(nonatomic,retain) id imgeviews;
    @property(nonatomic,retain) NSString *String;
    -(id)initwithBlock:(MyBlock)aBlcok;
    @end


    //
    //  Bblcok.m
    //  Blcok
    //
    //  Created by zhu  on 13-8-12.
    //  Copyright (c) 2013年 Zhu Ji Fan. All rights reserved.
    //

    #import "Bblcok.h"

    @interface Bblcok ()

    @end

    @implementation Bblcok
    @synthesize imgeviews = _imgeviews , String = _String;
    @synthesize myBlock = _myBlock;
    -(id)initwithBlock:(MyBlock)aBlcok
    {
        if (self = [super init])
        {
            self.myBlock = aBlcok;
        }
        return self;
    }

    -(void) dealloc
    {
        [super dealloc];
    }

    -(void) loadView
    {
        UIControl *cont = [[UIControl alloc] initWithFrame:CGRectMake(0, 0, 320, 568-44)];
        [cont addTarget:self action:@selector(Clcik) forControlEvents:UIControlEventTouchUpInside];
        self.view = cont;
        
        aField = [[UITextField alloc] initWithFrame:CGRectMake(60, 10, 160, 30)];
        aField.borderStyle = UITextBorderStyleLine;
        aField.placeholder = self.String;
        [self.view addSubview:aField];
        
        aButt = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        aButt.frame = CGRectMake(60, 50, 70, 30);
        [aButt setTitle:@"修改" forState:0];
        [aButt addTarget:self action:@selector(aButtClcik:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:aButt];
        
        image = [[UIImageView alloc] initWithFrame:CGRectMake(60, 100, 210, 260)];
        image.backgroundColor = [UIColor blueColor];
        image.image = self.imgeviews;
        [self.view addSubview:image];
        [image release];

    }

    -(IBAction)aButtClcik:(id)sender
    {
        NSString *sting = aField.text;
        myBlock(sting);
        [self.navigationController popToRootViewControllerAnimated:YES];
    }


    -(void)Clcik
    {
        [aField resignFirstResponder];
    }
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
    }

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

    @end

    参考链接: http://www.cnblogs.com/JuneWang/p/3850859.html

          通知中心的介绍

  • 相关阅读:
    go语言关于线程与通道channal
    linux 搭建SVN服务端
    使用mbedtls的使用说明和AES加密方法(原来的PolarSSL)
    清理 Xcode 10 记录
    Windows下修改iTunes备份路径
    Winform窗口自适应
    修改类模板文件
    HashTable
    修改App.config的键和值
    博客园动画效果
  • 原文地址:https://www.cnblogs.com/A--G/p/4538222.html
Copyright © 2011-2022 走看看