【问题标题】:Changing @State variable does not update the View in SwiftUI更改 @State 变量不会更新 SwiftUI 中的视图
【发布时间】:2020-04-10 09:43:22
【问题描述】:

我有以下观点(去掉了不相关的部分):

struct Chart : View {
    var xValues: [String]
    var yValues: [Double]
    @State private var showXValues: Bool = false

    var body = some View {
        ...
        if showXValues {
            ...
        } else {
            ...
        }
        ...
    }
}

然后我想添加一种从外部修改这个值的方法,所以我添加了一个函数:

func showXValues(show: Bool) -> Chart {
    self.showXValues = show
    return self
}

所以我像这样从外部构建图表视图:

Chart(xValues: ["a", "b", "c"], yValues: [1, 2, 3])
    .showXValues(true)

但它的工作原理就好像该值仍然为假一样。我究竟做错了什么?我认为更新 @State 变量应该更新视图。总的来说,我对 Swift 很陌生,对 SwiftUI 更是如此,我是否错过了某种应该在这里使用的特殊技术?

【问题讨论】:

标签: ios swift swiftui


【解决方案1】:

正如在提到的 cmets 中,@Binding 是要走的路。

这是一个用您的代码展示概念的最小示例:

struct Chart : View {
    var xValues: [String]
    var yValues: [Double]
    @Binding var showXValues: Bool

    var body: some View {
        if self.showXValues {
            return Text("Showing X Values")
        } else {
            return Text("Hiding X Values")
        }
    }
}

struct ContentView: View {
    @State var showXValues: Bool = false

    var body: some View {
        VStack {
            Chart(xValues: ["a", "b", "c"], yValues: [1, 2, 3], showXValues: self.$showXValues)
            Button(action: {
                self.showXValues.toggle()
            }, label: {
                if self.showXValues {
                    Text("Hide X Values")
                }else {
                    Text("Show X Values")
                }
            })
        }
    }
}

【讨论】:

  • 但是我有 20 个可选参数,例如 showXValues,我不想一直修改它们,我想要一个构建器模式之类的东西 - 正如我的示例 func 所示。我不想写一个 20 参数的初始化程序。例如。用户可以告诉我他们是否想显示 X 值,但我默认隐藏它们。
  • 您可以将所有这些变量打包到@ObservedObject 中吗?并给他们一个标准值@iSpain17
  • 我觉得这种方法不令人满意。只有Chart 应该关注showXValues,而不是ContentView。我不想将视图状态的定义推到其父级中。
  • 即使我不觉得这是正确的方法,如果孩子没有更新值,那么父母不应该将它作为绑定传递。 SwiftUI 会在您更新父级中的状态后重新渲染并将更新后的值传递给子级。
【解决方案2】:

好吧,答案很愚蠢。

无需创建func-s。我所要做的就是不要将属性标记为私有,而是给它们一个初始值,所以它们将在构造函数中成为可选的。所以用户可以指定它们,也可以不关心。像这样:

var showXLabels: Bool = false

这样构造函数要么是Chart(xLabels:yLabels)要么是Chart(xLabels:yLabels:showXLabels)

问题与@State 无关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 2021-10-19
    • 1970-01-01
    相关资源
    最近更新 更多