UI学习:通知传值

文章目录

通知传值

通知传值是 iOS 开发中一种解耦 的传值方式,它允许没有直接引用关系的对象之间进行通信。

核心概念

什么是通知中心

NSNotificationCenter 是一个单例对象,负责管理通知的发送和接收。它像一个"广播站":

  • 发送者:发布通知(不需要知道谁在监听)
  • 接收者:监听通知(不需要知道谁在发送)
  • 通知中心:负责转发

三个核心角色

角色 说明 对应方法
通知对象 携带信息的载体 NSNotification
观察者 监听通知的对象 addObserver:selector:name:object:
发布者 发送通知的对象 postNotificationName:object:userInfo:

通知的组成

复制代码
NSNotification 包含三个部分:
- name: 通知名称(唯一标识)
- object: 发送通知的对象(通常是 self)
- userInfo: 传递的数据(字典)

通知的生命周期

  1. 观察者注册 → 2. 发送通知 → 3. 通知中心分发 → 4. 观察者回调 → 5. 移除观察者

举例讲解

VCSecond 有一个 TextField,输入文字后通过通知传给 VCFirst 的 Label 显示

创建VCFirst 和 VCSecond 两个视图控制器

给VCFirst 定义属性showLahbel用来显示传值的结果, 定义button 来通过调用事件切换视图控制器

定义通知的名称

objc 复制代码
VCFirsrt.m 

// 定义通知名称
static NSString * const kTextFieldNotification = @"TextFieldNotification";
    
@interface VCFirst ()
@property (nonatomic, strong) UILabel *showLabel;
@property (nonatomic, strong) UIButton *pushButton;
@end

定义通知名称的作用:

通知名称就像一个"频道号"或"广播频率",决定了通知发送方和接收方能否匹配上。

创建VCFirst 的Label 和 UIButton, 并注册通知监听

objc 复制代码
// VCFirst.m

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    self.title = @"First VC";
    
    // 创建 Label(用于显示接收的数据)
    self.showLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 250, 300, 50)];
    self.showLabel.text = @"等待接收文字...";
    self.showLabel.textAlignment = NSTextAlignmentCenter;
    self.showLabel.backgroundColor = [UIColor lightGrayColor];
    self.showLabel.textColor = [UIColor blackColor];
    [self.view addSubview:self.showLabel];
    
    // 创建按钮(跳转到 Second VC)
    self.pushButton = [UIButton buttonWithType:UIButtonTypeSystem];
    self.pushButton.frame = CGRectMake(100, 350, 150, 44);
    [self.pushButton setTitle:@"去输入文字" forState:UIControlStateNormal];
    [self.pushButton addTarget:self action:@selector(pushToSecond) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.pushButton]; 
    
     // 注册通知监听
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(receiveText:)
                                                 name:kTextFieldNotification
                                               object:nil];
}

[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveText:) name:kTextFieldNotification object:nil的作用:

这是向通知中心注册一个观察者的方法调用,包含 4 个关键参数:

参数 类型 作用 本例中的值
observer id 观察者对象,谁要监听通知 self(当前对象)
selector SEL 收到通知后调用哪个方法 @selector(receiveText:)
name NSString 监听哪个通知名称 kTextFieldNotification
object id 限定发送者对象(过滤器) nil(不限定)

设置按钮事件, 创建视图控制器VCSecond 并且切换视图控制器

objc 复制代码
// VCFirst.m
    
- (void)pushToSecond {
    VCSecond *secondVC = [[VCSecond alloc] init];
    [self.navigationController pushViewController:secondVC animated:YES];
}

接受通知的方法, 收到通知调用的方法, 将接受到的字符串赋值给laebl,显示出来

objc 复制代码
// VCFirst.m

// 接收通知的方法
- (void)receiveText:(NSNotification *)notification {
    // 从 userInfo 中取出 text
    NSString *text = notification.userInfo[@"text"];
    // 更新 Label
    self.showLabel.text = [NSString stringWithFormat:@"收到:%@", text];
}

在对象销毁的时候移除观察者, 否则会导致野指针

objc 复制代码
// 移除观察者(重要)
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

给VCSecond 定义属性inputTextField和属性 sendButton , 用来输入要传值的内容和切换视图控制器, 同时定义通知名称

objc 复制代码
// VCSecond.m 
#import "VCSecond.h"

// 通知名称必须和 First 中一致
static NSString * const kTextFieldNotification = @"TextFieldNotification";

@interface VCSecond ()
@property (nonatomic, strong) UITextField *inputTextField;
@property (nonatomic, strong) UIButton *sendButton;
@end

通知名称本质上是发送方和接收方之间约定的字符串 ,需要在两端保持一致, 才能实现通信

因此,需要在需要发送和接受通知的视图控制器中都定义通知名称并且保持一致

创建VCSecond 的inputField 和 sendButton

objc 复制代码
// VCSecond.m   

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.view.backgroundColor = [UIColor whiteColor];
    self.title = @"VCSecond";
    
    // 创建TextField
    self.inputTextField = [[UITextField alloc] initWithFrame: CGRectMake(50, 250, 275, 44)];
    // 输入框风格
    self.inputTextField.borderStyle = UITextBorderStyleRoundedRect;
    self.inputTextField.placeholder = @"请输入文字";
    
    // 编辑时显示清除按钮
    self.inputTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
    [self.view addSubview: _inputTextField];
    
    // 创建发送按钮
    self.sendButton = [UIButton buttonWithType: UIButtonTypeSystem];
    self.sendButton.frame = CGRectMake(100, 320, 150, 44);
    [self.sendButton setTitle: @"发送并返回" forState: UIControlStateNormal];
    self.sendButton.backgroundColor = [UIColor systemBlueColor];
    [self.sendButton setTitleColor: [UIColor whiteColor] forState: UIControlStateNormal];
    [self.sendButton addTarget: self action: @selector(sendAndBack) forControlEvents: UIControlEventTouchUpInside];
    [self.view addSubview: _sendButton];
}

设置按钮事件: 发送通知 并 切换视图控制器

objc 复制代码
// VCSecond.m


- (void) sendAndBack {
    // 获取输入的文字
    NSString* str = self.inputTextField.text;
    
    // 如果文字为空, 给定默认值
    if (str.length == 0) {
        str =  @"空消息";
    } 
    // 发送通知
    [[NSNotificationCenter defaultCenter] postNotificationName: kTextFieldNotification object: self userInfo: @{@"text": str}];
    
    // 返回上一个界面
    [self.navigationController popViewControllerAnimated: YES];
}

发送通知:

[[NSNotificationCenter defaultCenter] postNotificationName: kTextFieldNotification object: self userInfo: @{@"text": str}]; 这段代码实现了发送通知的功能

  • [NSNotificationCenter defaultCenter] 获取通知中心的单例,

  • [NSNotificationCenter defaultCenter]: 通知的名称

  • object: 发送者

  • userInfo: 携带的数据, 这里是一个字典, 可以传递多个数据, 例如:

    objc 复制代码
    // 传递多个数据
    userInfo: @{
        @"text": str,
        @"color": [UIColor redColor],
        @"number": @100
    }

通知发送的对象

发送的消息是 NSNotification对象,

objc 复制代码
// postNotificationName:object:userInfo: 方法签名
- (void)postNotificationName:(NSNotificationName)name
                      object:(nullable id)object
                    userInfo:(nullable NSDictionary *)userInfo;

// 参数说明:
// name:     通知名称(字符串)
// object:   发送者对象(任意对象)
// userInfo: 数据字典(NSDictionary)

在接收消息的时候通过 userInfo 属性取字典

objc 复制代码
// 通过 userInfo 属性取字典
- (void)handleNotification:(NSNotification *)notification {
    NSString *text = notification.userInfo[@"text"];
}
相关推荐
周末也要写八哥1 小时前
编程学习中的记=记忆还是记录?
学习
随风,奔跑1 小时前
Git学习笔记
笔记·git·学习
ZC跨境爬虫1 小时前
跟着 MDN 学 HTML day_1:(全套原生Input+表单结构拆解)
前端·css·ui·html
慕容卡卡2 小时前
Claude 使用神器(web页面)--CloudCLI UI
java·开发语言·前端·人工智能·ui·spring cloud
咬_咬2 小时前
go语言学习(函数)
开发语言·学习·golang
2501_915106322 小时前
在Mac上搭建iOS开发环境的详细步骤与注意事项
ide·vscode·macos·ios·个人开发·swift·敏捷流程
豆瓣鸡2 小时前
Agent实战练习
java·python·学习
qq_452396232 小时前
第十四篇:《持续集成中的UI自动化:Jenkins/GitHub Actions集成》
ui·ci/cd·自动化
ZC跨境爬虫2 小时前
Apple官网复刻第二阶段day_6:(统一页脚模块封装+CSS公共复用体系落地)
前端·css·ui·重构·html