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 在子级中更改的主要内容,如果未能解决你的问题,请参考以下文章

Swift 中 @Binding 变量的 didSet

已发布值上的 SwiftUI toggle() 函数停止使用 Swift 5.2 触发 didSet

在 Swift 数组上使用 didSet 和 private(set)

Swift 中 willSet 和 didSet 的作用是啥?

Swift 中的 Getter 和 Setter - 改用 WillSet 和 DidSet 有意义吗?

DidSet在init函数swift 3中不起作用