如何在 SwiftUI 中使用 UserDefaults 保存选择器数据?
How I can save picker data with UserDefaults in SwiftUI?
我试图在 SwiftUI 的 UserDefault 中保存用户选择器组件的选择,但与简单的切换相反,我被阻止了。
我的看法:
import SwiftUI
enum VibrationType: String, CaseIterable {
case low = "Faible"
case normal = "Normal"
case hight = "Fort"
}
struct CompassSettings: View {
@ObservedObject var settingsStore: SettingsStore = SettingsStore()
@State var vibrationIntensityIndex = 1
var body: some View {
VStack {
Toggle(isOn: $settingsStore.vibrationActivate) {
Text("Activer la vibration")
.font(.system(size: 18))
.foregroundColor(Color("TextDark"))
}
.padding(.top, 6)
Picker("Intesité de la vibration", selection: self.$settingsStore.vibrationIntensity) {
ForEach(0..<self.vibrationIntensity.count) { intensity in
Text(self.vibrationIntensity[intensity]).tag(intensity)
}
}
.pickerStyle(SegmentedPickerStyle())
}
}
}
设置商店class:
import SwiftUI
import Combine
final class SettingsStore: ObservableObject {
let vibrationIsActivate = PassthroughSubject<Void, Never>()
let intensityOfVibration = PassthroughSubject<Void, Never>()
// Vibration
var vibrationActivate: Bool = UserDefaults.vibrationActivated {
willSet {
UserDefaults.vibrationActivated = newValue
vibrationIsActivate.send()
}
}
// Vibration intensity
var vibrationIntensity: VibrationType = .normal {
willSet {
UserDefaults.vibrationIntensity = newValue
print(UserDefaults.vibrationIntensity)
intensityOfVibration.send()
}
}
}
UserDefault 扩展名:
extension UserDefaults {
private struct Keys {
static let vibrationActivated = "vibrationActivated"
static let vibrationIntensity = "vibrationIntensity"
}
// Vibration
static var vibrationActivated: Bool {
get { return UserDefaults.standard.bool(forKey: Keys.vibrationActivated) }
set { UserDefaults.standard.set(newValue, forKey: Keys.vibrationActivated) }
}
// Vibration intensity
static var vibrationIntensity: VibrationType {
get { return UserDefaults.standard.object(forKey: Keys.vibrationIntensity) as!
VibrationType ?? "normal" }
set { UserDefaults.standard.set(newValue, forKey: Keys.vibrationIntensity) }
}
}
所以我的 UserDefaults 扩展中有一些错误。我不知道如何保存多个字符串选项以及如何显示默认选项。
您必须保存枚举的原始值,即字符串。
getter 有点广泛但安全
// Vibration intensity
static var vibrationIntensity: VibrationType {
get {
if let vibrationRawValue = UserDefaults.standard.string(forKey: Keys.vibrationIntensity),
let type = VibrationType(rawValue: vibrationRawValue) {
return type
} else {
return VibrationType(rawValue: "Normal")!
}
}
set { UserDefaults.standard.set(newValue.rawValue, forKey: Keys.vibrationIntensity) }
}
在下面找到固定代码...使用 Xcode 11.2 / iOS 13.2.
测试
enum VibrationType: String, CaseIterable {
case low = "Faible"
case normal = "Normal"
case hight = "Fort"
}
struct CompassSettings: View {
@ObservedObject var settingsStore: SettingsStore = SettingsStore()
@State var vibrationIntensityIndex = 1
@State var vibrationIntensity: [VibrationType] = [.low, .normal, .hight]
var body: some View {
VStack {
Toggle(isOn: $settingsStore.vibrationActivate) {
Text("Activer la vibration")
.font(.system(size: 18))
.foregroundColor(Color("TextDark"))
}
.padding(.top, 6)
Picker("Intesité de la vibration", selection: self.$settingsStore.vibrationIntensity) {
ForEach(self.vibrationIntensity, id: \.self) { intensity in
Text(intensity.rawValue).tag(intensity)
}
}
.pickerStyle(SegmentedPickerStyle())
}
}
}
final class SettingsStore: ObservableObject {
let vibrationIsActivate = PassthroughSubject<Void, Never>()
let intensityOfVibration = PassthroughSubject<Void, Never>()
// Vibration
var vibrationActivate: Bool = UserDefaults.vibrationActivated {
willSet {
UserDefaults.vibrationActivated = newValue
vibrationIsActivate.send()
}
}
// Vibration intensity
var vibrationIntensity: VibrationType = UserDefaults.vibrationIntensity {
willSet {
UserDefaults.vibrationIntensity = newValue
print(UserDefaults.vibrationIntensity)
intensityOfVibration.send()
}
}
}
extension UserDefaults {
private struct Keys {
static let vibrationActivated = "vibrationActivated"
static let vibrationIntensity = "vibrationIntensity"
}
// Vibration
static var vibrationActivated: Bool {
get { return UserDefaults.standard.bool(forKey: Keys.vibrationActivated) }
set { UserDefaults.standard.set(newValue, forKey: Keys.vibrationActivated) }
}
// Vibration intensity
static var vibrationIntensity: VibrationType {
get {
if let value = UserDefaults.standard.object(forKey: Keys.vibrationIntensity) as? String {
return VibrationType(rawValue: value)!
}
else {
return .normal
}
}
set {
UserDefaults.standard.set(newValue.rawValue, forKey: Keys.vibrationIntensity)
}
}
}
从 iOS 14,使用 onChange()
@State private var index = UserDefaults.standard.integer(forKey: "YourKey")
Picker(...)
.onChange(of: index) { newValue in
// Run code to save
UserDefaults.standard.set(newValue, forKey: "YourKey")
}
我试图在 SwiftUI 的 UserDefault 中保存用户选择器组件的选择,但与简单的切换相反,我被阻止了。
我的看法:
import SwiftUI
enum VibrationType: String, CaseIterable {
case low = "Faible"
case normal = "Normal"
case hight = "Fort"
}
struct CompassSettings: View {
@ObservedObject var settingsStore: SettingsStore = SettingsStore()
@State var vibrationIntensityIndex = 1
var body: some View {
VStack {
Toggle(isOn: $settingsStore.vibrationActivate) {
Text("Activer la vibration")
.font(.system(size: 18))
.foregroundColor(Color("TextDark"))
}
.padding(.top, 6)
Picker("Intesité de la vibration", selection: self.$settingsStore.vibrationIntensity) {
ForEach(0..<self.vibrationIntensity.count) { intensity in
Text(self.vibrationIntensity[intensity]).tag(intensity)
}
}
.pickerStyle(SegmentedPickerStyle())
}
}
}
设置商店class:
import SwiftUI
import Combine
final class SettingsStore: ObservableObject {
let vibrationIsActivate = PassthroughSubject<Void, Never>()
let intensityOfVibration = PassthroughSubject<Void, Never>()
// Vibration
var vibrationActivate: Bool = UserDefaults.vibrationActivated {
willSet {
UserDefaults.vibrationActivated = newValue
vibrationIsActivate.send()
}
}
// Vibration intensity
var vibrationIntensity: VibrationType = .normal {
willSet {
UserDefaults.vibrationIntensity = newValue
print(UserDefaults.vibrationIntensity)
intensityOfVibration.send()
}
}
}
UserDefault 扩展名:
extension UserDefaults {
private struct Keys {
static let vibrationActivated = "vibrationActivated"
static let vibrationIntensity = "vibrationIntensity"
}
// Vibration
static var vibrationActivated: Bool {
get { return UserDefaults.standard.bool(forKey: Keys.vibrationActivated) }
set { UserDefaults.standard.set(newValue, forKey: Keys.vibrationActivated) }
}
// Vibration intensity
static var vibrationIntensity: VibrationType {
get { return UserDefaults.standard.object(forKey: Keys.vibrationIntensity) as!
VibrationType ?? "normal" }
set { UserDefaults.standard.set(newValue, forKey: Keys.vibrationIntensity) }
}
}
所以我的 UserDefaults 扩展中有一些错误。我不知道如何保存多个字符串选项以及如何显示默认选项。
您必须保存枚举的原始值,即字符串。
getter 有点广泛但安全
// Vibration intensity
static var vibrationIntensity: VibrationType {
get {
if let vibrationRawValue = UserDefaults.standard.string(forKey: Keys.vibrationIntensity),
let type = VibrationType(rawValue: vibrationRawValue) {
return type
} else {
return VibrationType(rawValue: "Normal")!
}
}
set { UserDefaults.standard.set(newValue.rawValue, forKey: Keys.vibrationIntensity) }
}
在下面找到固定代码...使用 Xcode 11.2 / iOS 13.2.
测试enum VibrationType: String, CaseIterable {
case low = "Faible"
case normal = "Normal"
case hight = "Fort"
}
struct CompassSettings: View {
@ObservedObject var settingsStore: SettingsStore = SettingsStore()
@State var vibrationIntensityIndex = 1
@State var vibrationIntensity: [VibrationType] = [.low, .normal, .hight]
var body: some View {
VStack {
Toggle(isOn: $settingsStore.vibrationActivate) {
Text("Activer la vibration")
.font(.system(size: 18))
.foregroundColor(Color("TextDark"))
}
.padding(.top, 6)
Picker("Intesité de la vibration", selection: self.$settingsStore.vibrationIntensity) {
ForEach(self.vibrationIntensity, id: \.self) { intensity in
Text(intensity.rawValue).tag(intensity)
}
}
.pickerStyle(SegmentedPickerStyle())
}
}
}
final class SettingsStore: ObservableObject {
let vibrationIsActivate = PassthroughSubject<Void, Never>()
let intensityOfVibration = PassthroughSubject<Void, Never>()
// Vibration
var vibrationActivate: Bool = UserDefaults.vibrationActivated {
willSet {
UserDefaults.vibrationActivated = newValue
vibrationIsActivate.send()
}
}
// Vibration intensity
var vibrationIntensity: VibrationType = UserDefaults.vibrationIntensity {
willSet {
UserDefaults.vibrationIntensity = newValue
print(UserDefaults.vibrationIntensity)
intensityOfVibration.send()
}
}
}
extension UserDefaults {
private struct Keys {
static let vibrationActivated = "vibrationActivated"
static let vibrationIntensity = "vibrationIntensity"
}
// Vibration
static var vibrationActivated: Bool {
get { return UserDefaults.standard.bool(forKey: Keys.vibrationActivated) }
set { UserDefaults.standard.set(newValue, forKey: Keys.vibrationActivated) }
}
// Vibration intensity
static var vibrationIntensity: VibrationType {
get {
if let value = UserDefaults.standard.object(forKey: Keys.vibrationIntensity) as? String {
return VibrationType(rawValue: value)!
}
else {
return .normal
}
}
set {
UserDefaults.standard.set(newValue.rawValue, forKey: Keys.vibrationIntensity)
}
}
}
从 iOS 14,使用 onChange()
@State private var index = UserDefaults.standard.integer(forKey: "YourKey")
Picker(...)
.onChange(of: index) { newValue in
// Run code to save
UserDefaults.standard.set(newValue, forKey: "YourKey")
}