天天看点

【iOS】—— 通知传值什么是通知?通知传值的步骤界面传值的小实例

什么是通知?

通知中心传值,可以跨越多个页面传值, 一般也是从后面的页面传给前面的页面。

通知传值的步骤

通知传值可分为三个步骤:

一.在发送者(视图二)中实现一个方法进行发送通知。

[[NSNotificationCenter defaultCenter] postNotificationName:@"TransDataNoti" object:nil userInfo:_dictionary];
 //postNotificationName:之后的参数就是这个通知的名字,要和要和接收者中的名字一样,才能让接收者正确接收。     
 //object:接收对象。
 //userInfo: 携带的参数,为字典类型的数据,在例子中我携带了一个字典,因为有时候我们要传递的参数不只是一个,所以把东西全部放在通知里面,在接收者中,根据字典里面的键来取出里面的值。
 //_dictionary是我之前定义的一个字典实例。
           

二.在接收者(视图一)中注册通知,也就是接收者要进行接收通知,接收通知和发送通知的名字要一致。

//注册通知,用于接收通知,接收通知的名称必须和发送通知的名称保持一致才能接收到,否则无法接收到发出的通知
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notiReceived:) name:@"TransDataNoti" object:nil];
  //注:务必让接收者中name后面的参数和发送者中的name后面的参数一样。
           

三.在接收者(视图一)中实现通知中的方法。

// 参数类型是NSNotification
- (void)notiReceived:(NSNotification*)sender {
    self.textField.text = sender.userInfo[@"content"];
    self.label.text = sender.userInfo[@"content"];
}
           

四.在不用的时候移除通知。

- (void)dealloc {
    //移除所有通知
//    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
    //移除某个通知
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"TransDataNoti" object:nil];
}
           

注意参数Observer为要删除的观察者,一定不能置为nil。

如果为nil它会报警告:

Null passed to a callee that requires a non-null argument。

iOS9以上对其不进行移除处理不会崩溃,但是如果这个对象是在监听一个单例对象的属性的话,在其他地方,又修改该属性,还是会崩溃。

界面传值的小实例

  • 发送者(视图二)的NewViewController.h
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface NewViewController : UIViewController<UITextFieldDelegate>

@property (nonatomic, strong) UIButton *back;
@property (nonatomic, strong) UITextField *textField;
@property (nonatomic, copy) NSMutableDictionary *dictionary;

@end

NS_ASSUME_NONNULL_END
           
  • 发送者(视图二)的NewViewController.m
#import "NewViewController.h"

@interface NewViewController ()

@end

@implementation NewViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    
    self.title = @"子界面";
    
    _back = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    _back.frame = CGRectMake(200, 300, 50, 40);
    [_back setTitle:@"返回" forState:UIControlStateNormal];
    [_back addTarget:self action:@selector(back:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_back];
    
    _textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 400, 250, 50)];
    _textField.keyboardType = UIKeyboardTypeDefault;
    _textField.borderStyle = UITextBorderStyleRoundedRect;
    _textField.delegate = self;
    [self.view addSubview:_textField];
    
}

//协议事件,textField结束编辑的时候执行
- (void)textFieldDidEndEditing:(UITextField *)textField {
    NSString *string = [[NSString alloc] initWithString:_textField.text];
    _dictionary = [[NSMutableDictionary alloc] init];
    [_dictionary setObject:string forKey:@"content"];
}

//按钮事件
- (void)back:(UIButton*)button {
    //发送通知回传数据,回传的数据格式自定义,这里定义为dictionary类型
    [[NSNotificationCenter defaultCenter] postNotificationName:@"TransDataNoti" object:nil userInfo:_dictionary];
    [self dismissViewControllerAnimated:YES completion:nil];
}

//点击空白处键盘回收,同时结束textField编辑
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [_textField endEditing:YES];
}
@end
           
  • 接收者(视图一)的ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<UITextFieldDelegate>

@property (nonatomic, strong) UIButton *button;
@property (nonatomic, strong) UITextField *textField;
@property (nonatomic, strong) UILabel *label;

@end
           
  • 接收者(视图一)的ViewController.m
#import "ViewController.h"
#import "NewViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    self.title = @"主界面";
    
    _button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [_button setTitle:@"跳转" forState:UIControlStateNormal];
    [_button addTarget:self action:@selector(jump:) forControlEvents:UIControlEventTouchUpInside];
    _button.frame = CGRectMake(100, 200, 60, 30);
    [self.view addSubview:_button];
    
    _label = [[UILabel alloc] init];
    _label.text = @"通知";
    _label.frame = CGRectMake(200, 300, 100, 40);
    [self.view addSubview:_label];
    
    _textField = [[UITextField alloc] initWithFrame:CGRectMake(100, 400, 250, 50)];
    _textField.keyboardType = UIKeyboardTypeDefault;
    _textField.borderStyle = UITextBorderStyleRoundedRect;
    _textField.delegate = self;
    [self.view addSubview:_textField];
    
    //注册通知,用于接收通知,接收通知的名称必须和发送通知的名称保持一致才能接收到,否则无法接收到发出的通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notiReceived:) name:@"TransDataNoti" object:nil];
}

- (void)notiReceived:(NSNotification*)sender {
    self.textField.text = sender.userInfo[@"content"];
    self.label.text = sender.userInfo[@"content"];
}

- (void)dealloc {
    //移除所有通知
//    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
    //移除某个通知
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"TransDataNoti" object:nil];
}

- (void)jump:(UIButton*)button {
    NewViewController *show = [[NewViewController alloc] init];
    show.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:show animated:YES completion:nil];
}

@end
           
  • 效果图
【iOS】—— 通知传值什么是通知?通知传值的步骤界面传值的小实例
  • 点击跳转按钮进入第二个界面并且在textField中输入内容
【iOS】—— 通知传值什么是通知?通知传值的步骤界面传值的小实例
  • 再点击返回按钮返回第一个界面,发现label和textField中都有刚才输入的内容,传值成功
【iOS】—— 通知传值什么是通知?通知传值的步骤界面传值的小实例