gpt4 book ai didi

ios - SwiftUI 中的 UserDefaults 与 Toggle 绑定(bind)

转载 作者:行者123 更新时间:2023-12-03 04:05:46 24 4
gpt4 key购买 nike

我正在尝试找出构建绑定(bind)到 UserDefaults 的简单设置屏幕的最佳方法。

基本上,我有一个切换开关,我想要:

  • 每次更改此切换时要保存的 UserDefault 值(UserDefault 应该是事实来源)
  • 切换以始终显示 UserDefault 的值

Settings screen with Toggle

我观看了许多 SwiftUI WWDC session ,但我仍然不确定应该如何使用合并和 SwiftUI 中提供的不同工具来设置一切。我目前的想法是我应该使用 BindableObject,这样我就可以使用 hat 来封装许多不同的设置。

我认为我很接近,因为它几乎按预期工作,但行为不一致。

当我在设备上构建并运行它时,我打开它并打开切换,然后如果我上下 ScrollView 一点,开关就会关闭(就好像它实际上没有将值保存在 UserDefaults 中一样) .

但是,如果我打开开关,离开应用程序,然后再回来,它仍然打开,就像它记住了设置一样。

有什么建议吗?我发布此内容是希望它能帮助其他刚接触 SwiftUI 和 Joint 的人,因为我找不到与此主题相关的任何类似问题。

import SwiftUI
import Combine

struct ContentView : View {

@ObjectBinding var settingsStore = SettingsStore()

var body: some View {
NavigationView {
Form {
Toggle(isOn: $settingsStore.settingActivated) {
Text("Setting Activated")
}
}
}.navigationBarTitle(Text("Settings"))
}
}

class SettingsStore: BindableObject {

var didChange = NotificationCenter.default.publisher(for: .settingsUpdated).receive(on: RunLoop.main)

var settingActivated: Bool {
get {
UserDefaults.settingActivated
}
set {
UserDefaults.settingActivated = newValue
}
}
}

extension UserDefaults {

private static var defaults: UserDefaults? {
return UserDefaults.standard
}

private struct Keys {
static let settingActivated = "SettingActivated"
}

static var settingActivated: Bool {
get {
return defaults?.value(forKey: Keys.settingActivated) as? Bool ?? false
}
set {
defaults?.setValue(newValue, forKey: Keys.settingActivated)
}
}
}

extension Notification.Name {
public static let settingsUpdated = Notification.Name("SettingsUpdated")
}

最佳答案

更新

-------- iOS 14 及更高版本:--------

从 iOS 14 开始,现在有一种非常非常简单的方法来读取和写入 UserDefaults。

使用名为@AppStorage的新属性包装器

以下是它的使用方法:

import SwiftUI

struct ContentView : View {

@AppStorage("settingActivated") var settingActivated = false

var body: some View {
NavigationView {
Form {
Toggle(isOn: $settingActivated) {
Text("Setting Activated")
}
}.navigationBarTitle(Text("Settings"))
}
}
}

就是这样!这非常简单而且非常直接。您的所有信息都将从 UserDefaults 中保存和读取。

-------- iOS 13:---------

Swift 5.1 发生了很多变化。 BindableObject 已完全弃用。此外,PassthroughSubject 也发生了重大变化。

对于任何想让它发挥作用的人,下面是相同的工作示例。我重用了“gohnjanotis”的代码以使其变得简单。

import SwiftUI
import Combine

struct ContentView : View {

@ObservedObject var settingsStore: SettingsStore

var body: some View {
NavigationView {
Form {
Toggle(isOn: $settingsStore.settingActivated) {
Text("Setting Activated")
}
}.navigationBarTitle(Text("Settings"))
}
}
}

class SettingsStore: ObservableObject {

let willChange = PassthroughSubject<Void, Never>()

var settingActivated: Bool = UserDefaults.settingActivated {
willSet {

UserDefaults.settingActivated = newValue

willChange.send()
}
}
}

extension UserDefaults {

private struct Keys {
static let settingActivated = "SettingActivated"
}

static var settingActivated: Bool {
get {
return UserDefaults.standard.bool(forKey: Keys.settingActivated)
}
set {
UserDefaults.standard.set(newValue, forKey: Keys.settingActivated)
}
}
}

关于ios - SwiftUI 中的 UserDefaults 与 Toggle 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56827808/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com