Swift 中 @Binding 变量的 didSet

Posted

技术标签:

【中文标题】Swift 中 @Binding 变量的 didSet【英文标题】:didSet for a @Binding var in Swift 【发布时间】:2020-01-17 01:41:19 【问题描述】:

通常我们可以在 swift 中使用didSet 来监控变量的更新。但它不适用于@Binding 变量。例如,我有以下代码:

@Binding var text 
   didSet 
       ......
   

但是didSet 从未被调用过。知道吗?谢谢。

【问题讨论】:

您能提供更多代码吗?一直使用didSet。问题在于您没有提供的代码。 DidSet 不会在 @Binding 上被调用,因为绑定没有被设置。改变的是绑定在绑定中的值。你能解释一下你想在 didSet 中实现什么吗? 看这个答案:***.com/questions/56550713/… UIViewRepresentable吗?然后你可以使用updateUIView。每次绑定或状态更改时都会调用updateUIView 【参考方案1】:

您始终可以使用 onReceive (ios 13+) 或 onChange (iOS 14+),而不是 didSet

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)")
            
    

【讨论】:

【参考方案2】:

@Binding 上不需要 didSet 观察者。

如果您想要一个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 观察变化。请记住,您的 Viewvalue 类型,而不是引用类型。 SwiftUI 在需要时创建它,并且可能存储它的多个副本,或者根本不存储副本。

【讨论】:

感谢您的回复。我明白你的意思。它适用于body 函数。但就我而言,我不是从View 继承的。相反,我继承自 UIViewRepresentable。如果didSet 有效,对我来说会更容易。 UIViewRepresentableView 的子协议。任何符合UIViewRepresentable 的类型都符合View 这不允许您在绑定变量的值更改时刷新视图的情况。在上面的 sn-p 中,“count”需要发布,但您不能在计算属性上使用 Published 包装器。 (回复:我之前的评论,我指的是“text”绑定变量和“count”计算变量在 ViewModel 中管理的情况) 不,count 不需要是 Published,因为它完全根据 SwiftUI 跟踪的值按需计算。 count getter 调用text getter,所以当程序访问count 时,SwiftUI 会注意到对text 的依赖。

以上是关于Swift 中 @Binding 变量的 didSet的主要内容,如果未能解决你的问题,请参考以下文章

Swift3,展开 Optional<Binding>(在 SQLite.swift 中)

使用 SwiftUI @Binding 预览崩溃:与应用程序的通信中断

Swift didSet for var 使用 @Binding 在子级中更改

让 swift @Binding 接受任何符合 `BinaryFloatingPoint` 的值?

在按钮功能Swift中访问indexPath.row [重复]

Swift / SwiftUI:如何检查环境 /binding var 是不是为空字符串(.isEmpty 出现构建错误)