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
观察变化。请记住,您的 View
是 value 类型,而不是引用类型。 SwiftUI 在需要时创建它,并且可能存储它的多个副本,或者根本不存储副本。
【讨论】:
感谢您的回复。我明白你的意思。它适用于body
函数。但就我而言,我不是从View
继承的。相反,我继承自 UIViewRepresentable
。如果didSet
有效,对我来说会更容易。
UIViewRepresentable
是View
的子协议。任何符合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 出现构建错误)