为什么在SwiftUI ObservableObject中不会触发@Published值?

时间:2020-08-20 07:04:51

标签: ios swiftui

我创建了以下人为设计的示例来演示我的问题。在这段代码中,我期望将TextField初始化为“ Test Company X”,其中X是基于ObservableObject ViewModel的视图深度。这是正确的,并且仅适用于第一个视图。后续视图在初始出现时未获得发布的值。但是,当您浏览视图和onAppear触发器时,它确实会初始化。为什么在第二个及后续视图中未正确初始化TextField?

class TestViewModel: ObservableObject {
    @Published var companyName: String = ""
    
    func load(_ viewDepth: Int) {
        debugPrint("load: \(viewDepth)")
        
        // Mimic a network request to get data
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            debugPrint("publish: \(viewDepth)")
            self.companyName = "Test Company \(viewDepth)"
        }
    }
}

struct TestFormView: View {
    
    var viewDepth: Int
    @Binding var companyName: String
    @State private var navigateToNextView: Bool = false
    
    var body: some View {
        VStack(alignment: .leading, spacing: 3) {
            
            TextField("Company name", text: $companyName)
                .padding()
                .background(
                    RoundedRectangle(cornerRadius: 5)
                        .strokeBorder(Color.primary.opacity(0.5), lineWidth: 3)
                )
            
            Button.init("NEXT") {
                self.navigateToNextView = true
            }
            .frame(maxWidth: .infinity)
            .foregroundColor(Color.primary)
            .padding(10)
            .font(Font.system(size: 18,
                        weight: .semibold,
                        design: .default))
                .background(Color.secondary)
            .cornerRadius(Sizes.cornerRadius)
            
            NavigationLink(destination: TestView(viewDepth: viewDepth + 1), isActive: $navigateToNextView) {
                EmptyView()
            }
            .isDetailLink(false)
            
            Spacer()
        }
    }
}

struct TestView: View {
    @ObservedObject var viewModel = TestViewModel()
    var viewDepth: Int
    
    var body: some View {
        VStack {
            TestFormView(viewDepth: viewDepth, companyName: $viewModel.companyName)
        }
        .onAppear(perform: {
            self.viewModel.load(self.viewDepth)
        })
        .navigationBarTitle("View Depth \(viewDepth)")
        .padding()
    }
}

struct TestNavigationView: View {
    
    @State private var begin: Bool = false
    
    var body: some View {
        NavigationView {
            VStack {
                if begin {
                    TestView(viewDepth: 1)
                } else {
                    Button.init("BEGIN") {
                        self.begin = true
                    }
                    .frame(maxWidth: .infinity)
                    .foregroundColor(Color.primary)
                    .padding(10)
                    .font(Font.system(size: 18,
                                weight: .semibold,
                                design: .default))
                        .background(Color.secondary)
                    .cornerRadius(Sizes.cornerRadius)
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您的模型已重新创建(由于 NavigationLink 的当前性质)

SwiftUI 2.0

修复很简单-为此目的专门使用StateObject

demo

struct TestView: View {
    @StateObject var viewModel = TestViewModel()

   // .. other code