Swift didSet for var 使用 @Binding 在子级中更改
Posted
技术标签:
【中文标题】Swift didSet for var 使用 @Binding 在子级中更改【英文标题】:Swift didSet for var that gets changed in child with @Binding 【发布时间】:2020-05-30 14:23:12 【问题描述】:我有以下几点:
struct ContentView: View
@State var a = 0
didSet
print("Change detected in Parent")
var body: some View
VStack
Text(String(self.a))
Content2(a: self.$a)
struct Content2: View
@Binding var a: Int
didSet
print("Change detected in Child")
var body: some View
Text(String(a)).onTapGesture
if self.a == 1
self.a = 2
else
self.a = 1
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
为什么从未调用父级的didSet
?因为它显然在变化。如何确保以其他方式调用或通知它?
注意ContentView
的变化对我来说很重要,不要将其外包给PublishableObject
。因为一旦检测到此更改,我想对ContentView
进行进一步更改。在外包课程上捕获didSet
无济于事。
为了弄清楚我的用例如下:
我正在计算子视图上的 Int。一旦这个 Int 达到一定数量,它应该在 ParentView 上触发一个新的 Firebase getDocuments
函数。
【问题讨论】:
这能回答你的问题吗? How can I run an action when a state changes? @Asperi 或者更确切地说是@State
的一个功能。它适用于常规的旧属性包装器。
不,这个问题没有帮助。如前所述,我需要注意 didSet
上的 ContentView
结构而不是外包类。这是因为我想对ContentView
中的didSet
采取行动。或者有没有办法让我告诉ObservableObject class
调用ContentView
上的函数?
@Simon,视图应该是轻量级的哑静态对象,仅描述视图组合。视图模型(例如实现为 ObservableObject)应该是对事件做出反应并更改模型的模型。
【参考方案1】:
这是您的用例的解决方案
struct ContentView_: View
@State var a = 0
var body: some View
let counterBinding = Binding( // << proxy biding
get: self.a ,
set:
self.a = $0 // decision case below
// if $0 > CONSTANT
// // ... call getDocuments here
//
)
return VStack
Text(String(self.a))
Content2(a: counterBinding) // inject proxy !!
struct Content2: View
@Binding var a: Int
var body: some View
Text(String(a)).onTapGesture
if self.a == 1
self.a = 2
else
self.a = 1
【讨论】:
以上是关于Swift didSet for var 使用 @Binding 在子级中更改的主要内容,如果未能解决你的问题,请参考以下文章
已发布值上的 SwiftUI toggle() 函数停止使用 Swift 5.2 触发 didSet
在 Swift 数组上使用 didSet 和 private(set)
Swift 中 willSet 和 didSet 的作用是啥?