SwiftUI:如何在init方法中为@StateObject传入Binding初始化对象
问题分析与解决方案
原代码无法正常工作的核心原因:
@State属性的Binding($showColor)在视图init阶段尚未被SwiftUI完成初始化,此时传递的Binding无法同步状态变更。@StateObject的生命周期由SwiftUI全权管理,手动在init中赋值_myClass会绕过其生命周期逻辑,导致状态不同步。
方案一:将状态托管到ObservableObject(推荐)
把showColor的状态转移到MyClass中,用@Published属性管理,让MyClass作为唯一状态源,避免Binding传递的生命周期问题:
class MyClass: ObservableObject { @Published var showColor: Bool = false func doSomething() { self.showColor.toggle() } } struct ContentView: View { @StateObject private var myClass = MyClass() var body: some View { VStack { if myClass.showColor { Image(systemName: "globe") .resizable() .foregroundColor(.accentColor) .frame(width: 50, height: 50) } Button { myClass.doSomething() } label: { Text("Do Something") .padding() .background(Color.blue) .foregroundColor(.white) .cornerRadius(10) } } .padding() } }
方案二:保留ContentView的@State状态,延迟传递Binding
如果必须保留ContentView的@State变量,可改用@ObservedObject,并在视图出现后(此时@State的Binding已有效)初始化MyClass:
class MyClass: ObservableObject { @Binding var showColor: Bool init(showColor: Binding<Bool>) { self._showColor = showColor } func doSomething() { self.showColor.toggle() } } struct ContentView: View { @State private var showColor: Bool = false @ObservedObject private var myClass: MyClass! var body: some View { VStack { if showColor { Image(systemName: "globe") .resizable() .foregroundColor(.accentColor) .frame(width: 50, height: 50) } Button { myClass.doSomething() } label: { Text("Do Something") .padding() .background(Color.blue) .foregroundColor(.white) .cornerRadius(10) } } .padding() .onAppear { myClass = MyClass(showColor: $showColor) } } }
内容的提问来源于stack exchange,提问作者neldierto
相关产品推荐
相关产品推荐

