【问题标题】:SwiftUI pass data to subviewSwiftUI 将数据传递给子视图
【发布时间】:2020-10-05 09:45:12
【问题描述】:

所以我已经阅读了很多关于 swiftUI 的内容,但我很困惑。我了解@State 以及它如何更新幕后视图。我无法理解的是为什么当我在顶视图/结构中的状态发生变化时自动更新此示例中的子视图,因为在子视图上 var subname 不是 @State 属性。我希望这不会被更新。有人可以请教我吗?

import SwiftUI

struct SwiftUIView: View {
    @State private var name = "George"
    var body: some View {
        VStack{
            SubView(subName: name).foregroundColor(.red)
            Button(action: {
                self.name = "George2"
            }) {
                Text("Change view name")
            }
        }
    }
}

struct SubView: View {
    var subName:String
    var body: some View {
        Text(subName)
    }
}

struct SwiftUIView_Previews: PreviewProvider {
    static var previews: some View {
        SwiftUIView()
    }
}

PS。 如果我将子视图更改为

struct SubView: View {
    @State var subName:String
    var body: some View {
        Text(subName)
    }
}

当我按下按钮时它没有更新。

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    var subName: 字符串

    struct SubView: View {
        var subName: String
        // ...
    }
    

    在上面的示例中,您实际上并没有状态。当父视图中的subName 属性发生变化时,整个SubView 被重新绘制,从而为subName 属性提供了一个新值。它基本上是一个常数(尝试将其更改为let,您将得到相同的结果)。

    @State var subName: 字符串

    struct SubView: View {
        @State var subName: String
        // ...
    }
    

    这里你确实有一个@State 属性,它被初始化一次(SubView 第一次创建)并且即使在重绘视图时也保持不变。每当您更改父视图中的subName 变量时,在子视图中它会保持不变(可以在子视图中进行修改,但不会更改父视图的变量)。

    @Binding var subName: 字符串

    struct SubView: View {
        @Binding var subName: String
        // ...
    }
    

    如果您有@Binding 属性,您可以直接访问父级的@State 变量。每当它在父视图中发生更改时,它都会在子视图中更改(反之亦然)——这就是为什么它被称为 binding

    【讨论】:

      【解决方案2】:

      每当View@State 属性更改时,视图就会刷新,这意味着它的整个body 会重新计算。由于SubViewSwiftUIViewbody 的一部分,因此每当SwiftUIView 刷新自身时,它都会使用其@State name 属性的新值重绘其SubView

      【讨论】:

        猜你喜欢
        • 2019-12-24
        • 1970-01-01
        • 2019-11-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-16
        • 1970-01-01
        • 2022-11-23
        相关资源
        最近更新 更多