0

我有这样一个简单的复选标记 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")

        }

    }
}
4

1 回答 1

1

isChecked作为一个@State变量你的真相的来源。这意味着当某些底层数据模型(如 CoreData)发生变化时,这无关紧要。您的观点只是查看本地@State版本的isChecked.

但是看看你的看法。对我来说,它不应该拥有自己的状态。为什么?因为这个视图作为复选标记视图没有语义意义。它的父级似乎拥有该状态(因此有onCheck回调)。相反,这应该使用@Binding没有回调的 a:

struct RoundedCheckmark: View {
    @Binding var isChecked: Bool

    var body: some View {
        Button(action: { isChecked.toggle() }) {
            Image(isChecked ? "CheckedCheckmark" : "UncheckedCheckmark")
        }
    }

现在你的父母拥有这个状态,你可以推断出它的语义:

struct CheckmarkOwner: View {
    @State var showFavoritesOnly = false

    var body: some View {
        // content

        RoundedCheckmark(isChecked: $showFavoritesOnly)

        // and now something else will get notified when `showFavoritesOnly` gets toggled
        if showFavoritesOnly {
             // toggleable content
        }

        // more content
    }
}
于 2020-02-26T16:43:03.400 回答