首页 > 解决方案 > SwiftUI:为什么当您在此导航流中与 TextField 交互时,EnvironmentalObject 会重新初始化?

问题描述

在我的应用程序中,您会在注册期间完成入职培训。这完美无缺。但是,您可以通过个人资料页面再次浏览它。

有问题的个人资料页面代码如下所示(当然嵌入在顶级 NavigationView 中)

                        NavigationLink(destination:
                                        EndDateView().environmentObject(OnboardingVM(coordinator: viewModel.appCoordinator))
                        ) {
                            HStack {
                                Image(systemName: "chart.pie.fill")
                                    .font(.title)
                                Text("Edit Spending Plan")
                                    .fontWeight(.bold)
                                    .scaledFont("Avenir", 20)
                            }
                        }
                        .buttonStyle(ButtonWithIcon())

这会将您带到一个屏幕,您可以在其中通过日期选择器设置日期。在这一点上一切都很好。

当您导航到此流程的第三页(Profile -> Datepicker -> Set Income)并与 SwiftUI TextField 交互时,@EnvironmentObject 会重新初始化自身。

下面您将看到代码片段,这些代码片段显示了我们如何导航/传递 env 对象

DatePicker 导航代码

            NavigationLink(destination: SetIncomeView().environmentObject(onboardingVM)) {
                PurpleNavigationButton(buttonText: onboardingVM.continueButton)
            }

设置收入代码

struct SetIncomeView: View {
    @EnvironmentObject var onboardingVM: OnboardingVM
    @ObservedObject var setIncomeVM = SetIncomeVM()

    var body: some View {
        VStack {
            HStack {
                CustomHeader1(text: SetIncomeContent.title)
                Button(action: {
                    setIncomeVM.info.toggle()
                }) {
                    Image(systemName: "info.circle")
                }
            }
            .alert(isPresented: $setIncomeVM.info) {
                Alert(title: Text(SetIncomeContent.title),
                      message: Text(SetIncomeContent.header),
                      dismissButton: .default(Text(SetIncomeContent.dismiss)))
            }.padding()
            Spacer()
            ScrollView {
                HStack {
                    CustomHeader2(text: SetIncomeContent.income)
                    TextField("", text: $onboardingVM.expectedIncomeAmount)
                        .keyboardType(.numberPad)
                        .frame(width: 100, height: 35, alignment: .center)
                        .scaledFont("Avenir", 20)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                }
                HStack {
                    CustomHeader2(text: SetIncomeContent.onBasis)
                    Picker(selection: $onboardingVM.selectedBasis, label: Text("")) {
                        ForEach(0 ..< self.onboardingVM.basis.count) {
                            Text(self.onboardingVM.basis[$0])
                        }
                    }
                    .frame(width: 100)
                    .clipped()
                    CustomHeader2(text: SetIncomeContent.basis)
                }
                Button(action: {
                    setIncomeVM.otherIncome.toggle()
                }) {
                    if setIncomeVM.otherIncome {
                        Image(systemName: "minus.circle")
                    } else {
                        Image(systemName: "plus.circle")
                    }
                    Text(SetIncomeContent.anotherSource)
                        .foregroundColor(.black)
                        .underline()
                        .fixedSize(horizontal: false, vertical: true)
                        .padding()
                }
                //TODO: I am getting a bug where if i type or scroll it closes the view below
                HStack {
                    CustomHeader2(text: SetIncomeContent.income)
                    TextField("", text: $onboardingVM.additionalIncome)
                        .keyboardType(.numberPad)
                        .frame(width: 100, height: 35, alignment: .center)
                        .scaledFont("Avenir", 20)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                }.isHidden(!setIncomeVM.otherIncome)
                HStack {
                    CustomHeader2(text: SetIncomeContent.onBasis)
                    Picker(selection: $onboardingVM.additionalBasis, label: Text("")) {
                        ForEach(0 ..< self.onboardingVM.basis.count) {
                            Text(self.onboardingVM.basis[$0])
                        }
                    }
                    .frame(width: 100)
                    .clipped()
                    CustomHeader2(text: SetIncomeContent.basis)
                }.isHidden(!setIncomeVM.otherIncome)
            }
            Spacer()
            NavigationLink(destination: SetSavingsView().environmentObject(onboardingVM),
                           isActive: $setIncomeVM.savingsLink1Active) {
                Button(action: {
                    setIncomeVM.savingsLink1Active.toggle()
                }) {
                    Text(SetIncomeContent.noIncome)
                        .foregroundColor(.black)
                        .underline()
                        .fixedSize(horizontal: false, vertical: true)
                        .padding()
                }
            }
            NavigationLink(destination: SetSavingsView().environmentObject(onboardingVM), isActive: $setIncomeVM.savingsLink2Active) {
                Button(action: {
                        self.onboardingVM.saveIncomeBasis()
                        if !setIncomeVM.savingsLink2Active {
                            setIncomeVM.savingsLink2Active.toggle()
                        }
                }) {
                    PurpleNavigationButton(buttonText: onboardingVM.continueButton)
                }
            }
        }
        Spacer()
    }
}

知道为什么会这样吗?

标签: iosswiftswiftui

解决方案


推荐阅读