SwiftUI:手动发布 ObservableObject 更改
符合ObservableObject
协议的类可以使用SwiftUI的@Published
属性包装器自动声明对属性的更改,以便使用该对象的所有视图都可以重新调用其body
属性,并与数据保持同步。在很多时候,这确实非常有效,但是有时您需要更多的控制权,而SwiftUI的解决方案称为objectWillChange
。
每个符合ObservableObject
的类都会自动获得一个名为objectWillChange
的属性。这是一个发布者,这意味着它执行与@Published
属性包装器相同的工作:它通知正在观察该对象的所有视图一些重要的更改。顾名思义,此发布者应在我们进行更改之前立即触发,这使SwiftUI可以检查UI的状态并为动画更改做准备。
为了演示这一点,我们将构建一个可更新10次的ObservableObject
类。您已经认识到DispatchQueue.main.async()
是将工作推送到主线程的一种方式,但是在这里,我们将使用一种称为DispatchQueue.main.asyncAfter()
的类似方法。这使我们可以指定何时运行附加的闭包,这意味着我们可以说“在1秒钟后执行此工作”,而不是“立即执行此工作”。
在此测试用例中,我们将在1到10的循环内使用asyncAfter()
,因此我们将整数增加10个值。该整数将使用@Published
进行包装,因此更改公告将发送到所有正在观看它的视图。
在您的代码中的某处添加此类:
class DelayedUpdater: ObservableObject {
@Published var value = 0
init() {
for i in 1...10 {
DispatchQueue.main.asyncAfter(deadline: .now() + Double(i)) {
self.value += 1
}
}
}
}
要使用它,我们只需要在ContentView
中添加一个@ObservedObject
属性,然后在我们的主体中显示该值,如下所示:
struct ContentView: View {
@ObservedObject var updater = DelayedUpdater()
var body: some View {
Text("Value is: (updater.value)")
}
}
运行该代码时,您会看到该值一直递增,直到达到10,这正是您所期望的。
现在,如果删除@Published
属性包装,您将看到UI不再更改。在后台,所有的asyncAfter()
工作仍在进行,但不会导致UI刷新,因为没有发出更改通知。
尝试将value
属性更改成如下内容:
var value = 0 {
willSet {
objectWillChange.send()
}
}
现在,您将再次恢复原来的行为——用户界面将像以前一样计数为10。除了这次,我们有机会在willSet
观察器中添加额外的功能。也许您想要记录一些东西,也许您想要调用另一个方法,或者您想要钳制整数内部值,以使它永远不会超出范围——现在所有这些都在我们的控制之下。
- 一、爬虫基本原理
- python 中__setattr__, __getattr__,__getattribute__, __call__使用方法
- 量子技术与人工智能:同时进化的双生子
- TCP协议三次握手与四次挥手通俗解析
- Silverlight/aspx/ajax/mvc的UI自动化测试
- Office Open XML学习(1)-创建excel文档,并向单元格中插入字符串
- PyMC3和Theano代码构建贝叶斯深度网络,61页PPT探索贝叶斯深度学习以及实现
- 男程序员是不是都不会和女生表达交流?程序员的回答歪了
- Silverlight Telerik控件学习:主题Theme切换
- Silverlight自定义类库实现应用程序缓存
- Silverlight Telerik控件学习:TreeView数据绑定并初始化选中状态、PanelBar的Accordion效果、TabPanel、Frame基本使用
- 这或许是对小白最友好的python入门了吧——4,列表
- 每个人都应该知道的十个机器学习常识
- 重新带你了解React.js
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- zabbix入门学习
- 突击并发编程JUC系列-ReentrantReadWriteLock
- Qt音视频开发33-ffmpeg安卓版
- Vue.js|Nuxt仿制探探堆叠滑动|vue仿Tinder卡片效果
- Elasticsearch:透彻理解 Elasticsearch 中的 Bucket aggregation
- html+js开发模拟考试在线评分系统
- iOS音视频接入 - TRTC接入实时视频通话
- LRU缓存淘汰机制C++实现
- ant-design-vue运行时动态切换主题色
- 使用electron将vue-cli3.x项目打包为桌面应用
- Ubuntu 16.04下安装服务器端Shadowsocks
- 解决vue cli3.x打包上线静态资源找不到路径问题
- Ant-design-vue+vue-i18n实现前端国际化
- Mac OSX终端安装主题(oh my zsh)
- 谷歌浏览器油猴插件安装教程,让你的浏览器更加强大