在Swift中didSet用于@Binding var

时间:2019-09-16 08:33:32

标签: swift swiftui combine

通常我们可以迅速使用didSet来监视变量的更新。但这对@Binding变量不起作用。例如,我有以下代码:

@Binding var text {
   didSet {
       ......
   }
}

但是didSet从未被调用过。有什么想法吗?谢谢。

2 个答案:

答案 0 :(得分:5)

您始终可以使用 didSet (iOS 13+) 或 onReceive (iOS 14+) 代替 onChange

import Combine
import SwiftUI

struct ContentView: View {
    @State private var counter = 1
    
    var body: some View {
        ChildView(counter: $counter)
        Button("Increment") {
            counter += 1
        }
    }
}

struct ChildView: View {
    @Binding var counter: Int
    
    var body: some View {
        Text(String(counter))
            .onReceive(Just(counter)) { value in
                print("onReceive: \(value)")
            }
            .onChange(of: counter) { value in
                print("onChange: \(value)")
            }
    }
}

答案 1 :(得分:3)

didSet上不需要@Binding观察者。

如果您想要didSet是因为您想计算text更改时要显示的其他内容,则只需对其进行计算即可。例如,如果要显示text中的字符数:

struct ContentView: View {
    @Binding var text: String

    var count: Int { text.count }

    var body: some View {
        VStack {
            Text(text)
            Text(“count: \(count)”)
        }
    }
}

如果由于要对数据模型进行其他更改而要观察text,则从View观察更改是错误的。您应该从模型的其他地方或在控制器对象中观察变化,而不是从View观察变化。请记住,您的View类型,而不是引用类型。 SwiftUI会在需要时创建它,并且可能会存储它的多个副本,或者根本不存储任何副本。