【问题标题】:How I can save picker data with UserDefaults in SwiftUI?如何在 SwiftUI 中使用 UserDefaults 保存选择器数据?
【发布时间】:2020-04-03 01:19:41
【问题描述】:

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

【问题讨论】:

    标签: swiftui picker userdefaults


    【解决方案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】:

      找到以下固定代码...使用 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)
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

        • 感谢您的回复,但振动强度值仍处于“正常”状态。我不知道为什么。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-18
        • 2020-11-08
        • 2020-01-22
        • 2020-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多