繁体   English   中英

SwiftUI 应用程序在进入后台时似乎会自行更改 StateObject 的值

[英]SwiftUI App seems to change value of StateObject by itself when it goes to background

在构建我的应用程序时,我偶然发现了一个让我彻夜难眠的错误。 我有一个视图,它有一个按钮,按下该按钮时应该更改 StateObject 字段的值,该字段应该激活 NavigationLink。 到目前为止,应用程序按预期工作。 但是,当我在 navigationLink 指向的视图中时,我通过退出并再次打开应用程序将其置于后台,导航视图会弹回根视图。 此外,我设置了一个 onReceive 以在“isShowingFocusView”(激活 NaigationLink 的字段)更改时打印。 退出时,它显示值自行更改为 false,从而停用 navigationLink。

这是视图 model ,其中包含作为我的问题核心的字段。

class OverlayButtonViewModel: ObservableObject {
@Published var isShowingFocusView: Bool

init() {
    isShowingFocusView = false
}
}

这是我定义 ViewModel 并将其作为参数传递给 buttonView 按下激活 NavigationLink 的地方。

struct OverlayButtonView: View {
@StateObject var viewModel = OverlayButtonViewModel()

// some view hierarchy

HStack {
              Spacer()
                    
              OverlayFocusButtonView(show: $viewModel.isShowingFocusView)
                    .offsetToPositionIfNot(self.showingButtons, self.homeLocation)
                    .opacityIfNot(self.showingButtons, 0)
                    .padding(.trailing, 45)
                    .onChange(of: viewModel.isShowingFocusView) { value in
                            print("Current value \(value)")
                        }
       }

以下是我如何定义包含有问题的 NavigationLink 的视图:

struct OverlayFocusButtonView: View {
@Binding var show: Bool

var body: some View {

    NavigationLink(destination: FocusView(show: $show), isActive: $show) {
        Circle()
            .foregroundColor(Color("IdestBlue"))
            .frame(width: 60, height: 60)
            .overlay(Image("FocusModeIcon")
                        .resizable()
                        .renderingMode(.template)
                        .foregroundColor(.white)
                        .frame(width: 30, height: 30, alignment: .center)
            )
    }.onTapGesture {
        show = true
    }
}
}

最后,这是我停用 NavigationLink 的视图部分

struct FocusView: View {
@Binding var show: Bool

HStack{
           Image(systemName: "arrow.backward")
               .foregroundColor(.black)
               .font(.system(size: 20, weight: .bold))
               .padding(.leading, 20)
               .padding(.top, 10)
               .onTapGesture {
                   show = false
               }
           Spacer()
       }
       }

我对该主题的理解是,为了让应用程序在重新加载视图时不重新启动字段,它必须是 State 属性,这就是我正在做的事情,但仍然会发生值变化。

需要明确的是:我希望当我 go 回到我的应用程序时,我会看到与我退出时看到的相同的视图。

提前谢谢你的帮助。 我真的看不出我在这里做错了什么,所以如果您知道什么可能不正确,请帮助:)

我相信,问题在于您创建 state object 的地方。 初始化视图时,您正在创建 object。 但是,SwiftUI 可能会出于某些原因重新实例化 object,例如后台应用程序。

相反,我会将@StateObject的创建提升到您的{AppName}App.swift文件中,并将其作为环境 object 传递给那里。

@main
struct MyApp: App {
    
    @StateObject var viewModel = OverlayButtonViewModel()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(viewModel)
        }
    }

}


struct OverlayButtonView: View {
    @EnvironmentObject var viewModel: OverlayButtonViewModel
    
    var body: some View {
        SomeContent($viewModel)
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM