iOS页面间传值方式(代理Delegate,通知Notification,块Block)

代理Delegate传值

  1. Xcode新建Single View Application项目
  2. Main.storyboard拖拽UILabel,Button和UINavigationBar控件,添加好自动布局约束,如下图:

  3. 新建File –> Cocoa Touch Class –> DelegateByValViewController,勾选”Also create XIB file”,如下图:

  4. DelegateByValViewController.xib 拖拽UITextField,UIButton和UINavigationBar控件,添加约束,并拖线UITextField输出接口和UIButton按钮点击事件,如下图:
    iOS页面间传值方式(代理Delegate,通知Notification,块Block)_第1张图片

  5. DelegateByValViewController.h文件里需要设置代理协议和代理属性:

    
    #import <UIKit/UIKit.h>
    
    // 代理协议 begin
    @protocol DelegateByValViewControllerDelegate <NSObject>
    - (void)changeText:(NSString *)text;
    @end
    // 代理协议 end
    
    @interface DelegateByValViewController : UIViewController
    
    // 代理属性
    @property (nonatomic, assign) id <DelegateByValViewControllerDelegate> delegate;
    
    @end
  6. DelegateByValViewController.m文件里需要取得UITextField 的值,并在回退按钮事件中让代理去执行更改文本:

    - (IBAction)onBackPressed:(id)sender {
    // 代理执行更改文本
    [self.delegate changeText:self.inputedText.text];
    
    // 返回
    [self dismissViewControllerAnimated:YES completion:^{
    
    }];
    }
  7. Main.storyboard布局上的显示值的UILabel拖线到ViewController,定义输出接口,代理传值按钮拖线实现点击事件:

    - (IBAction)gotoDelegateByValPage:(id)sender {
    DelegateByValViewController *detalsViewCtrl = [[DelegateByValViewController alloc] init];
    // 设置代理
    detalsViewCtrl.delegate = self;
    
    //页面跳转
    [self presentViewController:detalsViewCtrl animated:YES completion:^{
    
    }];
    }
    
  8. 最后在ViewController.m文件中遵守DelegateByValViewControllerDelegate协和并执行协议中的方法:

    - (void)changeText:(NSString *)text {
    self.shownText.text = text;
    }

总结:代理模式到此结束,相对来说比较复杂的一种传值方式。上面只贴出了关键代码,具体代码见DEMO。

通知传值

  1. 在上面的项目中新建File –> Cocoa Touch Class –> NotificationByValViewController,勾选”Also create XIB file”,如下图:

  2. NotificationByValViewController.xib 拖拽UITextField,UIButton和UINavigationBar控件,添加约束,并拖线UITextField输出接口和UIButton按钮点击事件,如下图:

  3. NotificationByValViewController.m中的按钮返回事件中发送名称为“LabelTextChangeNotification”的通知

    - (IBAction)backBtnOnClick:(id)sender {
    // 发送通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"LabelTextChangeNotification" object:nil userInfo:@{@"inputedText": self.labelText.text}];
    
    // 返回
    [self dismissViewControllerAnimated:YES completion:^{
    
    }];
    }
    
  4. Main.storyboard中的通知传值按钮拖线到ViewController.m并实现点击事件:

    - (IBAction)gotoNotificationByValPage:(id)sender {
    NotificationByValViewController *notificationByValCtrl = [[NotificationByValViewController alloc] init];
    [self presentViewController:notificationByValCtrl animated:YES completion:^{
    
    }];
    }
  5. ViewController.m中的viewDidLoad方法需要去注册通知“LabelTextChangeNotification”,并实现收到通知的方法:

    - (void)viewDidLoad {
    [super viewDidLoad];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeTextByNotification:) name:@"LabelTextChangeNotification" object:nil];
    }
    
    - (void)changeTextByNotification:(NSNotification *)notification {
    // 取得值
    NSString *text = [[notification userInfo] objectForKey:@"inputedText"];
    // 显示
    self.shownText.text = text;
    }

    总结:通知传值方式比代理传值更简单。别忘了在dealloc方法中取消注册removeObserver。

块Block传值

  1. 按照上述新建文件的方法,新建BlockByValViewController

  2. 在BlockByValViewController.h文件中,定义一个参数为字符串的block:

    typedef void (^testBlock) (NSString *text);
    
    
    @interface BlockByValViewController : UIViewController
    
    @property (nonatomic, copy) testBlock block;
    
    @end
    
  3. BlockByValViewController.m的返回方法中:

    - (IBAction)onBackOnClick:(id)sender {
    self.block(self.inputedText.text);
    [self dismissViewControllerAnimated:YES completion:nil];
    }
    
  4. ViewController.m文件中,块传值按钮的点击事件代码:

    - (IBAction)gotoBlockbyValPage:(id)sender {
    BlockByValViewController *blockCtrl = [[BlockByValViewController alloc] init];
    [self presentViewController:blockCtrl animated:YES completion:nil];
    blockCtrl.block = ^(NSString *str) {
        self.shownText.text = str;
    };
    }

    总结:iOS4.0以后支持的block,封装的代码可以在任何时候执行,这种方式传值也比较简单,多线程中常用的传值方式。

最后附上DEMO工程:DEMO下载

你可能感兴趣的:(ios)