Why is my child SwiftUI view not updating?

倖福魔咒の 提交于 2021-02-10 08:44:05

问题


I have a Swift ui view with a child witch gets values from a @State variable. When i update my @State variable the view rebuilds but the child stays the same.

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)  
  }  
}  

回答1:


Use in it @Binding instead of @State. Modified complete snapshot provided below. Tested as-is & works with 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)
  }
}



回答2:


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)
  }
}

You don't need any state property wrapper in your ChildView. Once msg changed, SwiftUI know, that every View depending on its value should be "reloaded".

In your example, you "fixed" it by wrapping initial value to its state property wrapper. SwiftUI will not reload it, because @State property wrapper means, the value is stored outside of the ChildView. @State property wrapper in not part of View state. It is the opposite, once the @State wrapped property change, SwiftUI will reevaluate View's body computed property. To "reset" @State property wrapped value, you need "recreate" it, which means the state property will be reset to its initial value too.



来源:https://stackoverflow.com/questions/60266856/why-is-my-child-swiftui-view-not-updating

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!