SwiftUI передает данные в подпредставление

#swift #swiftui

#swift #swiftui

Вопрос:

Итак, я много читал о 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)
    }
}
  

он не обновляется, когда я нажимаю кнопку.

Ответ №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 переменной. Всякий раз, когда он изменяется в родительском элементе, он изменяется в SubView (и наоборот) — вот почему это называется привязкой.

Ответ №2:

Всякий @State раз, когда свойство View изменяется, представление обновляется, что означает, что все его body содержимое пересчитывается. Поскольку SubView является частью body of SwiftUIView , всякий SwiftUIView раз, когда обновляется, он перерисовывает его SubView , используя новое значение своего @State name свойства.