在 2 个页面 SwiftUI 之间传递状态

Posted

技术标签:

【中文标题】在 2 个页面 SwiftUI 之间传递状态【英文标题】:Passing state between 2 pages SwiftUI 【发布时间】:2020-10-12 14:27:31 【问题描述】:

我正在尝试使用新的 SwiftUI 重新创建我的 Onboarding 设置的旧版本,当我尝试共享状态以使视图发生变化时,它根本不知道发生了什么变化,这就是我我在做:

在主 .swift 结构 (不是 ContentView.swift) 我这样定义页面:

@main
struct AnotherAPP: App 
    
    @ObservedObject var onBoardingUserDefaults = OnBoardingUserDefaults()
    
    let persistenceController = PersistenceController.shared
    
    var body: some Scene 
        WindowGroup 
            // Onboarding screen
            if (onBoardingUserDefaults.isOnBoardingDone == false) 
                OnboardingPageView()
             else 
                UserLoginView()
            
        
    

因此,当我单击按钮进入登录页面时,在 onBoarding 页面上,它会存储它,但实际上并没有刷新视图。那里(在 OnboardingPageView.swift 中)我这样称呼 UserDefaults:

@ObservedObject private var onBoardingUserDefaults = OnBoardingUserDefaults()

在按钮上,我将其更改为:

self.onBoardingUserDefaults.isOnBoardingDone = true
UserDefaults.standard.synchronize()

那么发生了什么?

我知道,例如,如果我在 @main 上创建一个 @State 并将其绑定到 OnboardingPageView 它就可以工作,只要我点击那个按钮,它就会把我带到那里。

【问题讨论】:

你能把你OnBoardingUserDefaults类的内容贴出来吗? 【参考方案1】:

您可以使用AppStorage 在多个视图中管理UserDefaults 变量:

@main
struct TestApp: App 
    @AppStorage("isOnBoardingDone") var isOnBoardingDone = false
    
    var body: some Scene 
        WindowGroup 
            if !isOnBoardingDone 
                OnboardingPageView(isOnBoardingDone: $isOnBoardingDone)
             else 
                UserLoginView()
            
        
    


struct OnboardingPageView: View 
    @Binding var isOnBoardingDone: Bool

    var body: some View 
        Button("Complete") 
            isOnBoardingDone = true
        
    

【讨论】:

效果很好,谢谢。我不知道新的@AppStorage。我将如何从另一个视图中读取该值?会是:UserDefaults.standard.bool(forKey: "isOnBoardingDone") == false @Arturo AppStorage 只是UserDefaults 之上的一个包装器(仍然可以以正常 方式访问)。你可以在这里阅读更多:What is @AppStorage property wrapper【参考方案2】:

如果我理解正确,您是在尝试将内容视图中的状态变量的值传递给同一应用程序中的另一个视图。为简单起见,假设您的变量在 ContentView 中初始化如下:

@State private var countryIndex = 0 //Assuming the name of the variable is countryIndex  

现在,要传输值,请在内容视图(或变量最初所在的任何位置)中写入以下内容:

//Other code 

NavigationLink(destination: NextPage(valueFromContentView: $countryIndex)) 
                                Text("Moving On")
                  //In this case, the variable that will store the value of countryIndex in the other view is called valueFromContentView

//Close your VStacks and your body and content view with a '' 

在您的第二个视图或另一个视图中,使用以下方法初始化一个名为 valueFromContentView 的绑定变量:

@Binding var valueFromContentView: Int

然后,向下滚动到创建预览的代码。仅供参考,这是另一个 struct,名为 ViewName_Previews: PreviewProvider ...

如果您没有更改任何内容,它将是:

struct NextPage_Previews: PreviewProvider 
    static var previews: some View 
       
    

记住,我的第二个视图叫做 NextPage。

在预览大括号内,输入代码:

 NextPage(valueFromContentView: .constant(0))

因此,为您的应用程序创建预览的代码现在如下所示:

struct NextPage_Previews: PreviewProvider 
    static var previews: some View 
        NextPage(valueFromContentView: .constant(0)) //This is what you add
    

记住,NextPage 是我的视图的名称,valueFromContentView 是我在上面初始化的绑定变量

像这样,您现在可以将一个视图中的变量值传输到另一个视图。

【讨论】:

不,这不是我要问的哈哈,但谢谢。查看接受的答案

以上是关于在 2 个页面 SwiftUI 之间传递状态的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 应用生命周期中更改状态栏样式?

SwiftUI 导航回上层但不是根视图

在 SwiftUI 中的兄弟姐妹之间从父级共享状态

SwiftUI / 在两个模型之间组合传递数据

SwiftUI 在视图之间共享模型数据

我们如何在 SwiftUi 的另一个视图中传递布尔状态