我是您的助手,以下是翻译结果,仅保留 HTML 标签:
我有一个非常简单的 SwiftUI 查看器。它显示在列表中,可以通过点击进行切换,或者在从数据源(例如核心数据)刷新时进行切换。
我的第一次实现是:
struct RoundedCheckmark: View {
@State var isChecked : Bool
let onCheck: (Bool) -> Void
func toggle() { isChecked = !isChecked; onCheck(isChecked) }
init(isChecked: Bool, onCheck: @escaping (Bool) -> Void = { _ in }) {
self._isChecked = State(initialValue: isChecked)
self.onCheck = onCheck
}
var body: some View {
Button(action: toggle) {
Image(isChecked ? "CheckedCheckmark" : "UncheckedCheckmark")
}
}
}
看起来它可以工作,我可以切换它并且它可以正确加载。在切换时,我通过onCheck闭包/回调保存更改,并且它可以正常刷新。
但是,在像推送通知这样的外部刷新(例如Core Data底层模型的刷新)之后,此视图的刷新不会正确更改@State属性isChecked。
在init()中,我获取了isChecked的新值,并使用State(initialValue:)重新初始化了@State。但是在body中,我从旧的@State属性中获取了isChecked的旧值,因此视图具有错误的图像。
这里有一个解决方法,即仅依赖于let isChecked属性和onCheck回调。但是现在我不能在我的View内部拥有状态,我只能依赖于外部数据源的更改。也许这更合适,因为这样我就有了单一的真相来源,而无需本地@State存储。
struct RoundedCheckmark: View {
let isChecked: Bool
let onCheck: (Bool) -> Void
func toggle() { onCheck(isChecked) }
init(isChecked: Bool, onCheck: @escaping (Bool) -> Void = { _ in }) {
self.isChecked = isChecked
self.onCheck = onCheck
}
var body: some View {
Button(action: toggle) {
Image(isChecked ? "CheckedCheckmark" : "UncheckedCheckmark")
}
}
}