UserDefaults 未在 SwiftUI 中第一次保存和更新
UserDefaults not being saved and update after first time in SwiftUI
我创建了一个简单的系统来根据 UserDefaults 值在屏幕上导航,我有一个键 ”rootStatus” 那个键我放在枚举里面。我使用 @属性Wrapper 来存储用户默认值。
将 UserDefaults Key 放入枚举中。
enum UserDefaultKey: String {
case rootStatus = "rootStatus"
}
使用 属性 包装器在用户默认值中保存数据。
//MARK: UserDefault:- storage template to occupies the memory in the local Database.
@propertyWrapper
struct UserDefault<T> {
//Key: to storing the value in the userDefault in with name of specific key.
let key: String
//defaultValue:- to storing the data in any format in the UserDefault.
let defaultValue: T
//Update value when use a UserDefaultStorage inside the Project.
init(_ key: String, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}
// To Wrapping the Data inside the Project
var wrappedValue: T {
get{
// Read value from UserDefaults
return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
}
set{
// Set value to UserDefaults.
UserDefaults.standard.set(newValue, forKey: key)
}
}
}
要存储在 UserDefaults 中的枚举值。
enum ScreenSwitch: String {
case lauched
case logIn
case dashboard
case withoutlogin
case none
}
使用 ObservableObject 属性 包装器获取和设置 UserDefaults 值。
final class ScreenSwitchSettings: ObservableObject {
let objectWillChange = PassthroughSubject<Void, Never>()
@UserDefault(UserDefaultKey.rootStatus.rawValue, defaultValue: ScreenSwitch.lauched.rawValue)
var screenSwitch: String {
willSet {
objectWillChange.send()
}
}
}
TO 在 SwiftView 中使用
struct SwitchRootView: View {
@ObservedObject var screenSwitchSettings = ScreenSwitchSettings()
var body: some View {
containedView()
}
func containedView() -> AnyView?{
switch screenSwitchSettings.screenSwitch {
//// Introduction is a SwiftUIView for Navigation.
case ScreenSwitch.lauched.rawValue : return AnyView(IntroductionView())
// LoginView is a SwiftUIView for Navigation.
case ScreenSwitch.logIn.rawValue: return AnyView(LoginView())
// DashboardTabView is a SwiftUIView for Navigation.
case ScreenSwitch.withoutlogin.rawValue: return AnyView(DashboardTabView())
// DashboardTabView is a SwiftUIView for Navigation.
case ScreenSwitch.dashboard.rawValue: return AnyView(DashboardTabView())
// EmptyView is a SwiftUIView for Navigation.
case ScreenSwitch.none.rawValue: return AnyView(EmptyView())
default : return AnyView(EmptyView())
}
}
}
// 当应用程序第一次启动时,我最初设置了用户默认值。
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
@ObservedObject var screenSwitchSettings = ScreenSwitchSettings()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let contentView = SwitchRootView()
screenSwitchSettings.screenSwitch = ScreenSwitch.lauched.rawValue
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
}
更改 SwiftUIView 中的值
struct ContentView: View {
//MARK: Properties
@ObservedObject var screenSwitchSettings = ScreenSwitchSettings()
var body: some View {
NavigationView{
Button(action: {
// here i change Userdefault Value.
self.screenSwitchSettings.screenSwitch = ScreenSwitch.logIn.rawValue
}) {
NavigationLink(destination: SwitchRootView()) {
Text("Get Started")
}
}
}
}
}
在 ContentView 中,我更改了按钮选择上的用户默认值,但它没有更新。
可能是什么问题?
尝试以下而不是您的
final class ScreenSwitchSettings: ObservableObject {
@UserDefault(UserDefaultKey.rootStatus.rawValue, defaultValue: ScreenSwitch.lauched.rawValue)
var screenSwitch: String {
willSet { // or even maybe on didSet
self.objectWillChange.send()
}
}
}
and... 当您在其中放置导航 link 时按钮不起作用,因为后者会消耗点击手势,因此请使用类似以下内容的方式进行测试
@State private var isActive = false
...
NavigationView{
Button(action: {
// here i change Userdefault Value.
self.screenSwitchSettings.screenSwitch = ScreenSwitch.logIn.rawValue
self.isActive.toggle()
}) {
Text("Get Started")
}
NavigationLink(destination: SwitchRootView(), isActive: $isActive) {
EmptyView()
}
}
我创建了一个简单的系统来根据 UserDefaults 值在屏幕上导航,我有一个键 ”rootStatus” 那个键我放在枚举里面。我使用 @属性Wrapper 来存储用户默认值。
将 UserDefaults Key 放入枚举中。
enum UserDefaultKey: String {
case rootStatus = "rootStatus"
}
使用 属性 包装器在用户默认值中保存数据。
//MARK: UserDefault:- storage template to occupies the memory in the local Database.
@propertyWrapper
struct UserDefault<T> {
//Key: to storing the value in the userDefault in with name of specific key.
let key: String
//defaultValue:- to storing the data in any format in the UserDefault.
let defaultValue: T
//Update value when use a UserDefaultStorage inside the Project.
init(_ key: String, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}
// To Wrapping the Data inside the Project
var wrappedValue: T {
get{
// Read value from UserDefaults
return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
}
set{
// Set value to UserDefaults.
UserDefaults.standard.set(newValue, forKey: key)
}
}
}
要存储在 UserDefaults 中的枚举值。
enum ScreenSwitch: String {
case lauched
case logIn
case dashboard
case withoutlogin
case none
}
使用 ObservableObject 属性 包装器获取和设置 UserDefaults 值。
final class ScreenSwitchSettings: ObservableObject {
let objectWillChange = PassthroughSubject<Void, Never>()
@UserDefault(UserDefaultKey.rootStatus.rawValue, defaultValue: ScreenSwitch.lauched.rawValue)
var screenSwitch: String {
willSet {
objectWillChange.send()
}
}
}
TO 在 SwiftView 中使用
struct SwitchRootView: View {
@ObservedObject var screenSwitchSettings = ScreenSwitchSettings()
var body: some View {
containedView()
}
func containedView() -> AnyView?{
switch screenSwitchSettings.screenSwitch {
//// Introduction is a SwiftUIView for Navigation.
case ScreenSwitch.lauched.rawValue : return AnyView(IntroductionView())
// LoginView is a SwiftUIView for Navigation.
case ScreenSwitch.logIn.rawValue: return AnyView(LoginView())
// DashboardTabView is a SwiftUIView for Navigation.
case ScreenSwitch.withoutlogin.rawValue: return AnyView(DashboardTabView())
// DashboardTabView is a SwiftUIView for Navigation.
case ScreenSwitch.dashboard.rawValue: return AnyView(DashboardTabView())
// EmptyView is a SwiftUIView for Navigation.
case ScreenSwitch.none.rawValue: return AnyView(EmptyView())
default : return AnyView(EmptyView())
}
}
}
// 当应用程序第一次启动时,我最初设置了用户默认值。
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
@ObservedObject var screenSwitchSettings = ScreenSwitchSettings()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let contentView = SwitchRootView()
screenSwitchSettings.screenSwitch = ScreenSwitch.lauched.rawValue
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
}
更改 SwiftUIView 中的值
struct ContentView: View {
//MARK: Properties
@ObservedObject var screenSwitchSettings = ScreenSwitchSettings()
var body: some View {
NavigationView{
Button(action: {
// here i change Userdefault Value.
self.screenSwitchSettings.screenSwitch = ScreenSwitch.logIn.rawValue
}) {
NavigationLink(destination: SwitchRootView()) {
Text("Get Started")
}
}
}
}
}
在 ContentView 中,我更改了按钮选择上的用户默认值,但它没有更新。
可能是什么问题?
尝试以下而不是您的
final class ScreenSwitchSettings: ObservableObject {
@UserDefault(UserDefaultKey.rootStatus.rawValue, defaultValue: ScreenSwitch.lauched.rawValue)
var screenSwitch: String {
willSet { // or even maybe on didSet
self.objectWillChange.send()
}
}
}
and... 当您在其中放置导航 link 时按钮不起作用,因为后者会消耗点击手势,因此请使用类似以下内容的方式进行测试
@State private var isActive = false
...
NavigationView{
Button(action: {
// here i change Userdefault Value.
self.screenSwitchSettings.screenSwitch = ScreenSwitch.logIn.rawValue
self.isActive.toggle()
}) {
Text("Get Started")
}
NavigationLink(destination: SwitchRootView(), isActive: $isActive) {
EmptyView()
}
}