iOS多界面传值

embedded/2024/9/19 17:22:17/ 标签: ios, cocoa, macos

iOS多界面传值

文章目录

  • iOS多界面传值
    • 属性传值
    • 协议传值
    • Block传值
    • 通知传值
    • KVO传值
      • 概述
      • 使用步骤
    • 总结

属性传值

这个传值方式和他的名字一样,我们主要还是通过属性对值进行一个传递,主要应用场景是前一个页面向后一个页面传值

首先我们先要设置一个属性

@interface secondViewController : UIViewController
@property (nonatomic, assign) NSInteger tag; //tag就是我们设置的一个属性
@end

其次我们需要在某一个地方触发传值的事件,然后通过事件进行一个传递,这里我设置一个button来触发传值事件

-(void)press {secondViewController* second = [[secondViewController alloc] init];second.tag = _num;[self.navigationController pushViewController:second animated:YES];
}

然后我们这新的页面就拿到了这个数值,可以对然后就可以对这个数值进行一个相应的处理了

- (void)viewDidLoad {····self.label.text = [NSString stringWithFormat:@"%ld", _tag];NSLog(@"%ld", _tag);····// Do any additional setup after loading the view.
}

属性传值比较简单,就是这些内容,重点是前一个页面通过属性向后一个页面传值。

协议传值

协议传值是通过代理来实现的,主要的应用场景是一个后一个页面向前一个页面传值。

第一步

首先设置一个协议,注意是在后一个页面设置这个协议

@protocol VCFourthDelegte <NSObject>
-(void)ChangeImageView:(NSInteger)tag;
@end

第二步

在后面这个页面设置属性用作代理

@property (nonatomic, weak) id<VCFifthDelegate> delegate; //这里尽量采用weak作为修饰符

第三步

在某一个位置触发代理事件,将需要传递的数据向前传递。

[self.delegate changeImageView:tap.view.tag];
[self.navigationController popViewControllerAnimated:YES];

第四步

在前一个视图控制器中间遵循协议并实现代理方法,以接收传递过来的数据。

- (void)changeImageView:(NSInteger)tag {self.tag = tag;[self.tableView reloadData];
}

第五步

不要忘了在前一个视图控制器推出下一个视图控制器的时候将后者的代理设置成自己

 ViewController5* vc5 = [[ViewController5 alloc] init];vc5.delegate = self;[self.navigationController pushViewController:vc5 animated:YES];

我们主要是要将后面的视图控制器作为前一个视图控制器的代理,让后者为前者完成一些底层的内容从而改变前者的内容。

Block传值

block传值同样用于后一个页面向前一个页面传值。

第一步

在后一个页面中定义一个Block属性

@property (nonatomic, copy) void(^reutnblock)(NSString* temp, NSInteger num);

第二步

设置一个事件来触发返回上一级视图控制器的时候,使用第一步定义的Block,把需要传递的值放在^Block中间

- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = [UIColor whiteColor];self.label = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 40)];self.label.textColor = [UIColor whiteColor];self.label.text = @"123412342";NSLog(@"%ld", _tag);_btn1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];\self.btn1.frame = CGRectMake(100, 100, 100, 100);self.view.backgroundColor = [UIColor whiteColor];self.btn1.backgroundColor = [UIColor redColor];[self.btn1 setTitle:@"state" forState:UIControlStateNormal];[self.view addSubview:self.btn1];[self.btn1 addTarget:self action:@selector(press) forControlEvents:UIControlEventTouchUpInside];self.label.backgroundColor = UIColor.redColor;[self.view addSubview:_label];// Do any additional setup after loading the view.
}
-(void)press{self.reutnblock(self.label.text, --_tag); // 重点部分[self.navigationController popViewControllerAnimated:YES];}

第三步

在前一个页面跳转到后一个页面的事件函数中,调用后一个页面中的Block这个属性

-(void)press {secondViewController* second = [[secondViewController alloc] init];second.reutnblock = ^(NSString * _Nonnull temp, NSInteger num) {self.label.text = temp;self.num = num;};[self.navigationController pushViewController:second animated:YES];
}

下面给出一个通过Block实现的一个效果图,这里我们通过这段代码将后一个页面的label中的文字传到了前一个视图控制器中,从而实现了一个从后向前传值的一个效果。

请添加图片描述

通知传值

通知传值主要是通过一个通知中心进行传值,可以跨域多个页面进行一个传值。我在实现一个深色模式的时候采用了这种传值方式,通过一个通知中心将一个全局变量传给其他几个页面,一般也是从后面的页面传给前面的页面。

第一个步骤

创建并且发送通知

[[NSNotificationCenter defaultCenter] postNotificationName:@"notice" object:nil userInfo:@{@"first":@"123"}];

现在介绍一下这个方法的几个参数:
NSNotificationCenter: NSNotificationCenter 是一个单例对象,用于在应用程序内传递消息。它允许一个对象发布通知,其他对象可以注册为该通知的观察者,以便在通知发布时收到消息。
defaultCenter: 这是 NSNotificationCenter 的类方法,返回应用程序的默认通知中心实例。
postNotificationName:object:userInfo:: 这是 NSNotificationCenter 的实例方法,用于发布通知。
postNotificationName: 要发布的通知的名称。在这里,通知的名称是 “notice”。
object: 通知的发送者,可以是任何对象。这里传入 nil,表示没有特定的发送者。
userInfo: 一个字典,包含通知的附加信息。在这里,字典包含一个键值对 @“first”: @“123”。

第二个步骤

注册一个观察者

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receive:) name:@"notice" object:nil];

介绍一下这个函数的内容

第三个步骤

接收者对象需要实现一个方法,用于处理接收到的通知。这个方法是在观察者注册时通过selector参数指定的。当通知被发送时,通知中心会调用这个方法,并传递相关的信息给观察者。

-(void)receive:(NSNotification*) send {NSLog(@"接受通知");NSLog(@"%@", send.userInfo[@"first"]);self.label.text = send.userInfo[@"first"];
}

第四个步骤

在接收者对象被销毁之前,需要将其从通知中心中移除,避免出现潜在的内存泄漏。可以使用NSNotificationCenter的removeObserver:系列方法来移除观察者。

-(void)dealloc {[[NSNotificationCenter defaultCenter] removeObserver:self];
}

下面就是相关的一个实现效果,我将字符串123传递到前一个Label中,成功实现了一个通知传值

请添加图片描述

KVO传值

概述

KVO全称KeyValueObserve也就是观察者模式,是apple提供的一套事件通知机制.允许对象监听另一个对应特殊属性的改变,并在改变时接受到该事件.一般继承自NSObject的对象都默认是支持KVO。

KVO(Key-Value-Observing,键值观察),即观察关键字的值的变化。首先在子页面中声明一个待观察的属性,在返回主页面之前修改该属性的值。在主页面中提前分配并初始化子页面,并且注册对子页面中对应属性的观察者。在从子页面返回主页面之前,通过修改观察者属性的值,在主页面中就能自动检测到这个改变,从而读取子页面的数据。KVO只对属性发生作用。

传递方向

主要也是从后往前。

这里我们主要演示的是一个从A页面通过KVO来监听B页面的一个值,下面来看具体的实现流程。

使用步骤

第一步

注册观察者

同样和上面的通知传值一样,在触发事件的函数中注册我们的观察者。

@property (nonatomic, strong) secondViewController* second; //这里现在第一个页面中设置第二个页面作为自己的一个属性
- (void)press { //这里我才用了一个按钮来触发事件//[self willChangeValueForKey:@"ary"];self.second = [[secondViewController alloc] init];[self.second addObserver:self forKeyPath:@"userName" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];[self.navigationController pushViewController:self.second animated:YES];
}

这里解释一下这几个参数的含义:

P1: 观察者,该对象必须实现 该对象必须实现 observeValueForKeyPath:ofObject:change:context: 方法。
P2:要观察的属性。
P3:选择监听返回的值的类型:enum {
NSKeyValueObservingOptionNew 接收方法中使用change参数传入变化后的新值
NSKeyValueObservingOptionOld 接收方法中使用change参数传入变化前的旧值
NSKeyValueObservingOptionInitial change参数内容会包含新值
NSKeyValueObservingOptionPrior 如果加入这个参数,接收方法会在变化前后分别调用一次,共两次,变化前的通知change参数
};

P4: 传入任意类型的对象,在接受消息回调的代码中可以接受这个对象

第二步

接受通知,使用方法observeValueForKeyPath:ofObject:change:context:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {if ([keyPath isEqualToString:@"userName"]) {self.label.text = self.second.userName;NSLog(@"old text:%@   new text:%@", [change objectForKey:NSKeyValueChangeOldKey], [change objectForKey:NSKeyValueChangeNewKey]);}
}

第三步

删除KVO

- (void)dealloc {[self removeObserver:self forKeyPath:@"userName"];
}

这样就可以实现我们的KVO传值的效果,这里就可以看到我们在的子页面修改值后,主页面的UILabel出现了一个改变,这样我们就实现了一个传值。

请添加图片描述

tips

  • 这种方式不可以实现对于数组元素的一个监听,因为KVO是对于setter方法的监听,而数组的addObject方法并不是setter方法的内容,所以无法通过上述方法实现对于数组的一个监听。
  • 不使用时要移除KVO。

总结

iOS多界面传值主要就是通过这五种方式来实现,笔者这里只是简单学习了如何使用这几种传值方式的用法


http://www.ppmy.cn/embedded/90403.html

相关文章

【C++】数组案例 五只小猪称体重

题目&#xff1a;给出五只小猪体重&#xff0c;找出最大的体重的值并打印 思路&#xff1a;利用数组写入五只小猪的体重&#xff0c;让每一个元素都赋值给一个整型变量并每赋值一次就于下一个数组中的元素比&#xff0c;若是大就继续赋值给这个变量&#xff0c;若是小则不赋值…

NSSCTF-Web题目27(Nginx漏洞、php伪协议、php解析绕过)

目录 [HNCTF 2022 WEEK2]easy_include 1、题目 2、知识点 3、思路 [NSSRound#8 Basic]MyDoor 4、题目 5、知识点 6、思路 [HNCTF 2022 WEEK2]easy_include 1、题目 2、知识点 nginx日志漏洞执行系统命令 3、思路 打开题目&#xff0c;出现源码 题目要我们上传一个fi…

学习笔记-JWT 保持登录状态

目录 一、解析 token 1. 在 JWT 工具类添加解析 token 的方法 2. 在 Controller 添加获取用户数据的方法 二、获取用户信息 1. 发起 axios 请求用户信息 2. 在路由守卫中调用方法 3. 使用 三、token 时效性 1. 设置 token 过期时间 2. 判断 token 是否过期 3. 在拦截…

GraphSAGE (SAmple and aggreGatE)知识总结

1.前置知识 inductive和transductive 模型训练&#xff1a; Transductive learning在训练过程中已经用到测试集数据&#xff08;不带标签&#xff09;中的信息&#xff0c;而Inductive learning仅仅只用到训练集中数据的信息。 模型预测&#xff1a; Transductive learning只能…

用户看广告获取密码访问网页内容流量主模式源码

简介&#xff1a; 全开源付费进群流量主模式&#xff0c;用户看广告获取密码访问网页内容&#xff0c;网站生成内容&#xff0c;用户需要浏览内容跳转至小程序&#xff0c;观看广告后获取密码&#xff0c;输入密码查看网页内容。 与之前得9.9付费进群区别就是内容体现在了网页…

PHP中如何声明数组

数组是一种数据结构&#xff0c;用于存储一系列的值或对象&#xff0c;这些值或对象可以通过索引&#xff08;或键&#xff09;来访问。在PHP中&#xff0c;数组是一种复合类型的数据结构&#xff0c;可以存储多个值&#xff0c;这些值可以是整型、字符串、布尔值&#xff0c;甚…

《深入浅出WPF》学习笔记四.提高效率,code snippets的使用

《深入浅出WPF》学习笔记四.提高效率,code snippets的使用 背景 再跟着视频教程学习Wpf的过程中,发现这个小技巧。很惭愧好几年开发经验&#xff0c;没用过这个东西。 这个信息差还是很让人头疼的&#xff0c;特别在此分享。 code snippets是什么 Code Snippets是插入代码…

算法学习day28

一、寻找右区间(二分法) 题意&#xff1a;题目很容易理解 但是转换为二分法有点晦涩 给你一个区间数组 intervals &#xff0c;其中 intervals[i] [starti, endi] &#xff0c;且每个 starti 都 不同 。区间 i 的 右侧区间 可以记作区间 j &#xff0c;并满足 startj > e…

ansible 配置yum源

ansible配置yum源 有两种方式&#xff0c;一种是可以写好sh脚本&#xff0c;然后ansible去执行sh文件 另外一种就是使用yum_repository库 本文讲使用库的方式 本文使用的环境是centos7 &#xff0c;配置也是按照7去配置的&#xff0c;没有写动态配置 直接上代码 [rootvm-2 ~…

大数据-59 Kafka 高级特性 消息发送03-自定义拦截器、整体原理剖析

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

C#编写软件发布公告2——服务端

简单说明 框架&#xff1a;.NET 6.0 MVC 数据库&#xff1a;sqlLite3(当然这是为考虑本地数据简单&#xff0c;可以考虑使用大型数据库) 一、界面效果展示 1、启动主页面 2、记录摘要界面 3、对应版本详细 二、实现代码逻辑 1、启动主页面 //关联日志文件写 builder.Loggi…

使用Rust编写一个web todolist应用

使用rust编写一个web服务不如使用java提供的spring boot一样简单&#xff0c;需要手工去添加依赖&#xff0c;目前rust web生态已趋近成熟&#xff0c;可以尝试进行web开发。 本次开发的服务使用的依赖有 axum&#xff1a;一个专注于生态和模块化的web应用开发框架serde&…

selenium自动化输入用户名和密码和验证码并登陆成功

#本文供学习交流之用 注意&#xff1a;图形验证码的识别from selenium.webdriver import Chrome from selenium.webdriver.common.by import By from chaojiying import Chaojiying_Client import time web Chrome() web.maximize_window() web.get("https://www.chaojiy…

【Mode Management】CanNm处于PBS状态下接收到一帧诊断报文DCM会响应吗

目录 前言 正文 1.CanNm从RSS状态切换到PBS状态行为分析 1.1.CanNm动作 1.2.ComM动作 1.3.DCM动作 1.4 小结 2.CanNM在PBS状态下收到一帧诊断报文行为分析 2.1.DCM动作1 2.2. ComM动作 2.3. DCM动作2 2.3. CanNm动作 2.4 问题 2.5 分析 3.总结 前言 我们知道EC…

aspeed2600 GPIO分析与适配ipmitool power status, ipmitool power on/off

1.说明 本节以x86-power-control/src/power_control.cpp为基础&#xff0c;分析整个GPIO的调用流程&#xff0c;实现简单的ipmitool power on/off,ipmitool power status的管理。 1.资源:x86-power-control:https://github.com/openbmc/x86-power-control2.相关文件: meta-ph…

【C++】STL-哈希表封装unorder_set和unordered_map

目录 1、实现哈希表的泛型 2、unordered_set和unordered_map的插入 3、迭代器 3.1 operator 3.2 const迭代器 4、find 5、unordered_map的operator[] 6、对于无法取模的类型 7、介绍unordered_set的几个函数 7.1 bucket_count 7.2 bucket_size 7.3 bucket 7.4 rese…

大厂面试必备的软件测试八股文【附答案】

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 前言 最近有很多粉丝问我&#xff0c;有什么方法能够快速提升自己&#xff0c;通过阿里、腾讯、字节跳动、京东等互联网大厂的面试&#xff0c;我觉得短时间提升…

【深度学习】【框架】【基本结构】transformer

论文地址:https://arxiv.org/pdf/1706.03762 1. 整体结构 2. 内部结构 3. 公式 Transformer工作原理四部曲:Embedding(向量化)、Attention(注意力机制)、MLPs(多层感知机)和Unembedding(模型输出)。

被遗忘的哑终端 —— 键盘键位演变的启发者

注&#xff1a;机翻&#xff0c;未校对。 The Forgotten World of Dumb Terminals 被遗忘的哑终端世界 A quick journey through the lost age of “glass teletypes.” 快速穿越失落的“玻璃电传打字机”时代。 From the earliest days of digital computers, researchers o…

【C语言】Top K问题【建小堆】

前言 TopK问题&#xff1a;从n个数中&#xff0c;找出最大&#xff08;或最小&#xff09;的前k个数。 在我们生活中&#xff0c;经常会遇到TopK问题 比如外卖的必吃榜&#xff1b;成单的前K名&#xff1b;各种数据的最值筛选 问题分析 显然想开出40G的空间是不现实的&#…