Почему мой дочерний вид SwiftUI не обновляется? - PullRequest
0 голосов
/ 17 февраля 2020

У меня представление Swift с пользовательским интерфейсом, которое получает значения из переменной @State. Когда я обновляю переменную @State, представление перестраивается, но дочерний элемент остается прежним.

struct ContentView: View {  
  @State var msg: String = ""  
  var body: some View {  
    VStack {  
      Button(action: {  
        self.msg = "Hallo World"  
      }, label: { Text("Say Hallo")})  

      ChildView(msg: msg).padding().background(Color.orange)  
      Text(msg).padding().background(Color.green)  
    }.frame(maxWidth: .infinity, maxHeight: .infinity)  
  }  
}  

struct ChildView: View {  
  @State var msg: String  

  var body: some View {  
    Text(msg)  
  }  
}  

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

Используйте в нем @Binding вместо @State. Модифицированный полный снимок представлен ниже. Протестировано как есть и работает с Xcode 11.2 / iOS 13.2.

struct ContentView: View {
  @State var msg: String = ""
  var body: some View {
    VStack {
      Button(action: {
        self.msg = "Hallo World"
      }, label: { Text("Say Hallo")})

      ChildView(msg: $msg).padding().background(Color.orange)
      Text(msg).padding().background(Color.green)
    }.frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}

struct ChildView: View {
  @Binding var msg: String

  var body: some View {
    Text(msg)
  }
}
0 голосов
/ 18 февраля 2020
import SwiftUI

struct ContentView: View {
  @State var msg: String = ""
  var body: some View {
    VStack {
      Button(action: {
        self.msg += "Hallo World "
      }, label: { Text("Say Hallo")})

      ChildView(msg: msg).padding().background(Color.orange)
      Text(msg).padding().background(Color.green)
    }.frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}

struct ChildView: View {
  var msg: String

  var body: some View {
    Text(msg)
  }
}

Вам не требуется никакой оболочки свойств состояния в вашем ChildView. Как только msg изменилось, SwiftUI знает, что каждое представление в зависимости от его значения должно быть «перезагружено».

В вашем примере вы «исправили» его, поместив начальное значение в оболочку его свойства состояния, SwiftUI не будет перезагружать его, поскольку обертка свойства @State означает, что значение хранится вне ChildView. Оболочка свойства @State не является частью состояния View. Напротив, после изменения свойства @State SwiftUI переоценивает вычисляемое тело свойства View. Чтобы «сбросить» обернутое значение свойства @State, вам необходимо «воссоздать» его, что означает, что свойство состояния также будет сброшено до его начального значения.

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...