如何在SwiftUI中使用UserDefaults保存选择器数据?

时间:2019-12-09 22:02:30

标签: swiftui picker userdefaults

我正在尝试从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())
    }
  }
}

SettingsStore类:

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扩展名中有一些错误。我不知道如何保存多个字符串选择以及如何显示默认选择。

3 个答案:

答案 0 :(得分:1)

在固定代码下查找...经过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)
        }
    }
}

答案 1 :(得分:1)

从 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")
   }

答案 2 :(得分:0)

您必须保存枚举的原始值,即字符串。

吸气剂有点广泛但很安全

// 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) }
}