• 已经了解了 SwiftUI 如何通过使用 @State 属性包装器将变化的数据存储在结构体中,如何使用 $ 将状态绑定到 UI 控件的值,以及更改 @state 包装的属性时是如何自动让 SwiftUI 重新调用结构体的 body 属性的。
  • 所有这些结合在一起,可以编写如下代码:
struct ContentView: View {@State private var blurAmount: CGFloat = 0var body: some View {VStack {Text("Hello, World!").blur(radius: blurAmount)Slider(value: $blurAmount, in: 0...20)}}
}
  • 如果执行这些代码,将会发现左右拖动滑块可以完全按照预期调整文本标签的模糊量。现在,假设我们希望该绑定不仅仅是处理模糊效果的半径,想将其保存到 UserDefaults 中,运行一个方法,或者只是打印出该值以进行调试,可以尝试像这样更新属性:
@State private var blurAmount: CGFloat = 0 {didSet {print("New value is \(blurAmount)")}
}
  • 如果运行该代码,可能会出现失望的结果:当拖动滑块周围时,会看到模糊量的变化,但是不会看到我们的 print() 语句被触发,实际上什么都不会输出。
  • 为了了解这里的原因,可以考虑一下在使用 Core Data 时:使用 @FetchRequest 属性包装器查询我们的数据,以及如何直接使用 FetchRequest 结构体,以便可以更好地控制它是如何创建的。
  • 属性包装器具有该名称,因为它们将我们的属性包装在另一个结构体中。对于许多属性包装器而言,该结构体与包装器本身具有相同的名称,但是使用 @FetchRequest 时展示了实际上是如何实际读取其中的包装值,获取的结果,而不是请求本身。
  • 这意味着当使用 @State 来包装字符串时,最终得到的实际属性类型是 State。类似地,当使用 @Environment 和其他环境时,我们最终得到一个 Environment 类型的结构体,该结构体内部包含一些其他值。
  • 之前曾解释说,我们无法在视图中修改属性,因为它们是结构体,因此是固定的。但是,现在知道 @State 本身会生成一个结构体,因此面临一个难题:如何修改该结构体?
  • Xcode 有一个非常有用的命令,称为“快速打开”(使用 Cmd + Shift + O 进行访问),该命令可以在项目或已导入的任何框架中找到任何文件或类型。现在将其激活,然后输入 “State”,希望第一个结果在其下方显示 SwiftUI,但如果没有,请找到并选择它:

  • 将进入 SwiftUI 生成的界面,该界面实质上是 SwiftUI 向我们展示的所有的部分。那里没有实现代码,只有协议,结构体,修饰符等的许多定义。
  • 我们可以查看 state,因此应该被带到此行:
@propertyWrapper public struct State<Value> : DynamicProperty {
  • 该 @propertyWrapper 属性使它成为 @State 供我们使用,现在往下看几行,可以看到以下内容:
public var wrappedValue: Value { get nonmutating set }
  • 该包装值是我们要存储的实际值,例如字符串,这个生成的接口告诉我们,该属性可以读取(get)和写入(set),但是当设置该值时,它实际上不会更改结构体本身。在后台,它将值发送给SwiftUI以便存储在可以自由修改的位置,因此,结构体本身永不改变。
  • 现在知道了所有这些,让我们回到问题代码:
@State private var blurAmount: CGFloat = 0 {didSet {print("New value is \(blurAmount)")}
}
  • 在表面上,状态为“ 当blurAmount 更改时,打印出它的新值”。但是,由于 @State 实际上会包装其内容,因此实际上是说,当包装 blurAmount 的 State 结构体更改时,请打印出新的模糊量。
  • 还在这儿?现在让我们更进一步:已经看到 State 如何使用一个非可变的 setter 包装其值,这意味着 blurAmount 或包装它的 State 结构体都没有改变,我们的绑定直接改变了内部存储的值,这意味着属性观察者永远不会被触发。

SwiftUI之深入解析属性包装器如何处理结构体相关推荐

  1. Swift Property Wrapper 属性包装器

    @propertyWrapper属性包装器:在定义存储属性时添加一个分离层,代表该属性被包装起来,且在包装器内部可以做一些事情.把一些通用复用的代码放在了包装器中,比如线程安全检查或者数据存储到数据库 ...

  2. 深入解析JNA—模拟C语言结构体

    原帖:http://blog.csdn.net/shendl/article/details/3599849 深入解析JNA-模拟C语言结构体 前言 前几天写<JNA--JNI终结者>一文 ...

  3. SwiftUI之深入解析@StateObject、@ObservedObject和@EnvironmentObject的联系和区别

    一.@State 属性包装器 ① 什么是 @State 属性包装器? 状态在任何现代应用程序中都是不可避免的,但在 SwiftUI 中,重要的是所有的视图都是它们状态的简单函数,我们不需要直接改变视图 ...

  4. NSValue包装自定义结构体

    typedef struct {int year;int month;int day; }Date;void value(){Date date = {2013,9,30},//void *代表任何类 ...

  5. SwiftUI之深入解析如何处理特定的数据和如何在视图中适配数据模型对象

    一.前言 阅读了我的前两篇博客的朋友,应该都熟练掌握了 SwiftUI 如何创建一个任何相关信息的展示视图和各个视图之间的相互组合,以及动态生成一个展示相关信息的可滚动列表,用户可以点击列表项去查看其 ...

  6. SwiftUI之深入解析如何创建列表展示视图和列表如何导航跳转新页面

    一.前言 地标详情页视图已经创建完成,我们需要提供一种方式让用户可以查看完整的地标列表,并且可以查看每一个地标的详情.地标详情页视图的创建,请参考我的博客:SwiftUI之深入解析如何创建和组合视图. ...

  7. 【Kotlin】属性 与 幕后字段 ( 属性声明 | 属性初始化器 | 属性访问器 | field 属性幕后字段 | lateinit 延迟初始化属性 )

    文章目录 I . 属性 字段 总结 II . 属性声明 III . 属性初始化器 IV . get / set 属性访问器 V . 属性幕后字段 field VI . 变量和常量的区别 VII . 延 ...

  8. java包装器类_Java中的基本类型和包装类

    Java中基本数据类型与包装类型有 基本类型 包装器类型 boolean Boolean char Character int Integer byte Byte short Short long L ...

  9. SwiftUI之深入解析高级动画的几何效果GeometryEffect

    一.前言 在我的博客 SwiftUI之深入解析高级动画的路径Paths 中,已经了解了 Animatable 的协议,以及如何使用它来动画路径.接下来,我们将使用相同的协议来动画变换矩阵,使用一个新的 ...

最新文章

  1. android升级gradle到3.4.1
  2. 消防验收找问题,一般就是这些了!
  3. 018.Zabbix维护时间和模板导入
  4. GitHub 发布了一款重量级产品,可直接运行代码
  5. Google Guava多集
  6. 攻防世界 适合做桌面_空间“狭小”的二人世界,适合情侣们做浪漫的事情
  7. 基于阿里云ECS+ 宝塔面板(bt) + WordPress 搭建个人主页(以独立博客为例)
  8. bzoj千题计划227:bzoj1486: [HNOI2009]最小圈
  9. Web浏览器已经限制此文件显示
  10. java网上在线考试系统代码_Java+JavaWeb在线考试系统
  11. 知网下载论文CAJ格式转为PDF格式
  12. uni-app 无网络图标不显示问题解决
  13. 一加七pro计算机没有记录了,尽享速度与激情:一加7T Pro 迈凯伦版评测
  14. C++基础面试问题总结
  15. GPS GLONASS数据文件类型解析
  16. 区块链技术应用将迎来多场景布局
  17. ipad显示连接不到商店服务器,iPad无法连接App Store 打不开怎么办
  18. PS出现“不能完成存储为命令,因为没有足够的内存RAM” 设置性能时“要求96和8之间的整数。已插入最接近的数值”
  19. UVALive 4394 String painter——dp
  20. 【蓝桥杯嵌入式备赛】10.拓展板数码管、ADC按键及光敏电阻

热门文章

  1. Oracle数据块原理深入剖析
  2. 程序员删数据库事件引发的个人思考
  3. 具体knn算法概念参考knn代码python实现
  4. stm32 之引脚和各功能模块间关系
  5. 通过监测DLL调用探测Mimikatz
  6. C# - 简单介绍TaskScheduler
  7. 凄怆与悲凉(灾区现场最新照片)
  8. 山工kw什么意思_【山工装载机故障灯KW什么意思】专区-山工-装载机-铁甲网
  9. python怎么和sql一起用_自己写的Python数据库连接类和sql语句拼接方法
  10. java文本框默认格式化,XJL:Swing中的格式化文本框