【问题标题】:Passing state between 2 pages SwiftUI在 2 个页面 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类的内容贴出来吗?

标签: swift swiftui


【解决方案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 是我在上面初始化的绑定变量

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

【讨论】:

  • 不,这不是我要问的哈哈,但谢谢。查看接受的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 2017-07-19
  • 2017-11-06
  • 2016-04-29
相关资源
最近更新 更多