天天看點

【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】—— 通知傳值什麼是通知?通知傳值的步驟界面傳值的小執行個體