swift 为什么传入的@State值在子视图中没有改变?

46scxncf  于 2023-05-27  发布在  Swift
关注(0)|答案(1)|浏览(128)

View 1和View 2都从父级ContentView获取参数text。但是在View 1中使用@Binding,而View 2使用@State。点击View 1按钮将改变text值。但是,单击后,只有ContentView Text()更新,但View 2的Text没有更新?为什么会这样呢?
在打印输出中,view 1和view 2都使用新值 “View 1 Text” 调用init。
将View 2更改为使用@Binding将在更新View 2时更新View 2的文本。
下面是示例代码:
ContentView.swift

import SwiftUI

struct ContentView: View {
    @State var showView1: Bool = false
    @State var showView2: Bool = false
    @State var text: String = "Hello World"

    init() {
        print("init ContentView")
    }

    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("\(text)")

            HStack {
                if showView1 {
                    View1($text)
                }
                if showView2 {
                    View2(text)
                }
            }
            .border(.black)
            HStack {
                Button("View1") { showView1.toggle() }
                Button("View2") { showView2.toggle() }
            }
        }
        .padding()
    }
}

View1.swift

struct View1: View {
    @Binding var text: String
    init(_ text: Binding<String>) {
        self._text = text
        print("init View1  \(self.text)")
    }

    var body: some View {
        Button("Click") {
            print("Click view1 button")
            self.text = "View 1 Text"
        }
    }
}

View2.swift

struct View2: View {
    @State var text: String

    init(_ text: String) {
        self.text = text
        print("init View2  \(self.text)")
    }

    var body: some View {
        VStack {
            Button("Click") {
                print("Click view2 button")
            }
            Text("view2 text : \(text)")
        }
    }
}
cgfeq70w

cgfeq70w1#

View2中的@State是错误的,应该是let,例如

struct View2: View {
    let text: String

@State var声明了真值的来源,let向下传递读访问,@Binding var向下传递读/写(绑定只是一对get/set闭包)。无论哪种情况,当传入的值与上次不同时,都会调用body。如果要转换传入的值,请在子View中创建一个计算属性。使用View层次结构将丰富的模型类型转换为可以轻松预览的简单类型。

相关问题