视图不会在 SwiftUI 的 ForEach 内部更新

Views do not update inside the ForEach in SwiftUI

我正在使用 ForEach 来解析模型列表并为每个模型创建一个视图,每个视图包含一个 Button 和一个 TextButton 切换应隐藏文本并更改按钮标题的可见性状态 (Invisible/Visible)。

struct ContentView: View {

    var colors: [MyColor] = [MyColor(val: "Blue"), MyColor(val: "Yellow"), MyColor(val: "Red")]

    var body: some View {

        ForEach(colors, id: \.uuid) { color in
            ButtonColorView(color: color.val)
        }

    }
}

struct ButtonColorView: View {

    var color: String

    @State var visible = true

    var body: some View {

        if visible {
            return AnyView(  HStack {
                Button("Invisible") {
                    self.visible.toggle()
                }
                Text(color)
            })
        } else {
            return AnyView(
                Button("Visible") {
                    self.visible.toggle()
                }
            )
        }
    }
}



class MyColor: Identifiable {
    let uuid = UUID()
    let val: String

    init(val: String) {
        self.val = val
    }
}

不幸的是它不起作用,按下 ButtonForEach 内的视图不会改变。我用 ButtonColorView(color: colors[0].val) 替换了 Foreach 并且它似乎有效,所以我想说问题出在 ForEach.

我也在 ButtonColorView 中尝试了断点,看起来当按钮被触发时视图被调用 return 在正确的视图中,无论如何视图不会在屏幕上更新。

那么,我是否以错误的方式使用了 ForEach

这个问题出现在一个更复杂的应用程序中,但我试图在这个小例子中提取它。总结一下:我需要 ButtonColorView 到 return 不同的视图,具体取决于其状态(在本例中为可见性)

PS:我正在使用 Xcode 11 Beta 6

您正确使用了 ForEach。我认为是 ButtonColorView 主体中的 if 语句导致了问题。试试这个:

struct ButtonColorView: View {

    var color: String

    @State var visible = true

    var body: some View {
        HStack {
            Button(visible ? "Invisible" : "Visible") {
                self.visible.toggle()
            }
            if visible {
                Text(color)
            }
        }
    }
}

您也可以尝试这样的操作:

struct ButtonColorView: View {

    var color: String

    @State var visible = true

    var body: some View {
        HStack {
            if visible {
                HStack {
                    Button("Invisible") {
                        self.visible.toggle()
                    }
                    Text(color)
                }
            } else {
                Button("Visible") {
                    self.visible.toggle()
                }
            }
        }
    }

}