【发布时间】:2020-02-26 10:50:48
【问题描述】:
我有这样一个简单的复选标记 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 关闭/回调保存了更改,并且刷新正常。
但是在外部刷新(如推送通知刷新底层模型)之后,此视图的核心数据刷新不会正确更改 @State 属性 isChecked。
在 init() 中,我得到了 isChecked 的新值,并使用 State(initialValue: ) 重新初始化了 @State。但是在正文中,我从旧的 @State 属性中获取了 isChecked 的旧值。所以视图确实有错误的图像。
这是一种解决方法,即仅依赖 let isChecked 属性和 onCheck 回调。但是现在我的视图中不能有状态,我只能依赖外部数据源的变化。也许它更合适,因为这样我有一个没有本地 @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")
}
}
}
【问题讨论】:
-
看起来您回答了自己的问题...
-
是的,但我不明白为什么第一个解决方案不起作用。是因为 View 的每个实例都创建了新的@State,但 View 使用的是旧的?如果是这样,那么我如何改变这种状态(以及我是否应该尝试改变它?)你的意思是为什么我会有两个真相来源?
标签: swift swiftui swiftui-state