当前位置: 首页 > news >正文

【iOS】多界面传值(五大传值方式)

【iOS】多界面传值(五大传值方式)

文章目录

  • 【iOS】多界面传值(五大传值方式)
    • 属性传值(Property)
    • 协议传值(Delegation)
    • 通知传值(NSNotification)
    • Block传值
    • 单例(Singleton)
    • 总结

属性传值(Property)

属性传值是一种正向传值的方式,即通过访问后一个视图控制器的属性,通过这个属性从前一个界面向后一个界面进行传值

我们直接讲解其步骤:

  1. 首先在后一个界面的.h文件定义属性

    @interface TargetViewController : UIViewController@property NSString* PropertyRecieved;@end
    
  2. 之后在前一个界面对当后一个界面将弹出时对这个属性进行复刻

    TargetViewController *targetVC = [[TargetViewController alloc] init];
    targetVC.PropertyRexieved = @"Hello, World!";
    [self.navigationController pushViewController:targetVC animated:YES];
    

协议传值(Delegation)

也称作代理传值,与属性传值相反,这是一种反向传值的方法,将后一个界面传值给前一个界面,本质是用协议中定义的方法来进行传值的

  1. 先要在后一个界面定义一个用于传值的协议与其代理属性

    // BViewController.h@protocol BViewControllerDelegate <NSObject>
    - (void)didReceiveData:(NSString *)data;
    @end@interface BViewController : UIViewController@property (nonatomic, weak) id<BViewControllerDelegate> delegate;@end
    
  2. 在前一个视图中遵守协议,设置代理并实现代理的方法,在后一个界面触发回调

    // AViewController.h
    #import "BViewController.h"@interface AViewController : UIViewController <BViewControllerDelegate>
    @end// AViewController.m
    BViewController *bVC = [[BViewController alloc] init];
    bVC.delegate = self;
    [self.navigationController pushViewController:bVC animated:YES];- (void)didReceiveData:(NSString *)data {NSLog(@"收到数据:%@", data);
    }
    
    // BViewController.m (传值的时候触发)
    if ([self.delegate respondsToSelector:@selector(didReceiveData:)]) {[self.delegate didReceiveData:@"我是传回来的数据"];
    }
    

通知传值(NSNotification)

通知传值是通过NSNotificationCenter实现的广播机制,一处发出了消息,任何监听这个消息的地方都可以收到,一般适合多个界面或者模块之间的状态同步

  1. 注册监听者,一旦有人发出名为"DarkModeChanged"的通知,就执行selector中的方法

    [[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(handleDarkModeChange:)name:@"DarkModeChanged"object:nil];
    
  2. 发送通知,在源视图中进行通知的发送,userInfo即为所要传的数据(是一个字典)

    [[NSNotificationCenter defaultCenter] postNotificationName:@"DarkModeChanged"object:niluserInfo:@{@"isDark": @(YES)}];
    
  3. 响应通知,处理所传来的值。执行相关的操作

    - (void)handleDarkModeChange:(NSNotification *)notification {NSDictionary *info = notification.userInfo;BOOL isDark = [info[@"isDark"] boolValue];// 根据是否是暗黑模式,更新界面self.view.backgroundColor = isDark ? [UIColor blackColor] : [UIColor whiteColor];
    }
    
  4. 移除监听(可选)

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

    防止内存泄漏,当视图销毁时移除监听,不然系统还会给已经释放的对象发消息,导致崩溃

Block传值

Block传值的用途与协议传值有点相似,主要都是用于从后一个控制器向前一个控制器传值

Block 传值是通过在一个控制器中定义一个 Block(类似函数),另一个控制器在跳转前将 Block 实现赋值,最终在需要的时候回调它,从而实现传值。

  1. 在后一个控制器声明一个Block属性(发出方)

    // BViewController.h@interface BViewController : UIViewController@property (nonatomic, copy) void (^dataBlock)(NSString *data);@end
    
  2. 在前一个视图控制器设置Block的实现(接收方)

    // AViewController.mBViewController *bVC = [[BViewController alloc] init];
    bVC.dataBlock = ^(NSString *data) {NSLog(@"收到回传数据:%@", data);
    };
    [self.navigationController pushViewController:bVC animated:YES];
    
  3. 在后一个视图控制器需要时调用Block(回调传值)

    // BViewController.mif (self.dataBlock) {self.dataBlock(@"这是B传给A的值");
    }
    [self.navigationController popViewControllerAnimated:YES];
    

Block传值的方法更简洁,更适合用于一次性回调的方式

单例(Singleton)

单例传值是一种更为高级的数据传递方式,适用于在多个界面之间传递数据。通过创建一个全局唯一的共享对象(单例类)来实现多个界面共享和访问同一个数据的方式。

主要适用于多个界面中进行数据的共享,而无需在每个界面中进行传递

  1. 创建一个单例类(数据中心)

    // AppManager.h
    @interface AppManager : NSObject@property (nonatomic, strong) NSString *username; // 可传其他类型,如 BOOL isDarkMode+ (instancetype)sharedManager;@end
    
    // AppManager.m
    @implementation AppManager+ (instancetype)sharedManager {static AppManager *manager = nil;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{manager = [[AppManager alloc] init];});return manager;
    }@end
    

    这是一个全局对象,每次返回的都是同一个实例,可以放任何想共享的数据

  2. 在一个界面中设置数据

    [AppManager sharedManager].username = @"小明";
    

    在任何地方设置值,其他页面都能访问

  3. 在其他界面读取数据

    NSString *name = [AppManager sharedManager].username;
    NSLog(@"读取到用户名:%@", name);
    
  4. 在整个运行周期存在,除非app关闭或者手动删除

    [AppManager sharedManager].username = nil;
    

总结

多界面传值是UI中相当重要且常见的一个知识点,要根据具体情况进行方法的选择,有时甚至需要结合起来使用,比如通知与单例结合起来使用等 ,多加使用,才能更熟练

http://www.dtcms.com/a/290353.html

相关文章:

  • PHP高级进阶:突破编程边界,开启技术新征程
  • GaussDB alter table的用法
  • Charles 抓包工具中文版完整指南 提升 API 调试与性能调优
  • Netty实现单通道并发读写,即多路复用
  • 神经网络——线性层
  • 混合遗传粒子群算法在光伏系统MPPT中的应用研究
  • imx6ull-系统移植篇15——U-Boot 图形化配置(下)
  • 蚂蚁数科AI数据产业基地正式投产,携手苏州推进AI产业落地
  • 使用Python绘制专业柱状图:Matplotlib完全指南
  • 《Linux服务与安全管理》| 安装拼音输入法
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 主页布局实现
  • “hidden act“:“gelu“在bert中作用
  • 经典神经网络(vgg resnet googlenet)
  • 家庭网络怎么进行公网IP获取,及内网端口映射外网访问配置,附无公网IP提供互联网连接方案
  • 03-虚幻引擎蓝图类的各父类作用讲解
  • el-table固定高度,数据多出现滚动条,表头和内容对不齐
  • Eltable tree形式,序号列实现左对齐,并且每下一层都跟上一层的错位距离拉大
  • 深入解析Hadoop MapReduce Shuffle过程:从环形缓冲区溢写到Sort与Merge源码
  • VMware Workstation Pro克隆虚拟机导致网络异常解决方法
  • 深度学习 pytorch图像分类(详细版)
  • 【设计模式】观察者模式 (发布-订阅模式,模型-视图模式,源-监听器模式,从属者模式)
  • HTTP性能优化:打造极速Web体验的关键策略
  • 从实践出发--探究C/C++空类的大小,真的是1吗?
  • 西门子 S7-1500 信号模块硬件配置全解析:从选型到实战
  • 如何快速比较excel两列,拿出不同的数据
  • 在.NET Core API 微服务中使用 gRPC:从通信模式到场景选型
  • 用 STM32 的 SYSTICK 定时器与端口复用重映射玩转嵌入式开发
  • 大模型高效适配:软提示调优 Prompt Tuning
  • The Survey of Few-shot Prompt Learning on Graph
  • AI Agent开发学习系列 - langchain之LCEL(3):Prompt+LLM