什麼是通知?
通知中心傳值,可以跨越多個頁面傳值, 一般也是從後面的頁面傳給前面的頁面。
通知傳值的步驟
通知傳值可分為三個步驟:
一.在發送者(視圖二)中實作一個方法進行發送通知。
[[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
- 效果圖
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL0MGRPBTSU1UMVpHW3BjMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLyYGZhJTN2MTYjdzMmZjM5YzY1QTOyYTY5Q2NmN2Y3E2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
- 點選跳轉按鈕進入第二個界面并且在textField中輸入内容
- 再點選傳回按鈕傳回第一個界面,發現label和textField中都有剛才輸入的内容,傳值成功