【问题标题】:SwiftUI toggle switchesSwiftUI 切换开关
【发布时间】:2020-03-03 11:55:46
【问题描述】:

我正在尝试实现一个简单的切换开关,但我无法保存新的切换/开关状态,因为当我更改视图并返回设置时,它默认为关闭开关。你能告诉我我做错了什么吗?

struct StudyMode: View {
      @State private var overdueFirst = UserDefaults.standard.bool(forKey: "Overdue First")
      @EnvironmentObject var settings: UserSettings

      var body: some View {
        VStack {
          HStack {
            Toggle(isOn: $overdueFirst) {
              Text("Overdue cards first")
            }
            .onTapGesture {
              var newSwitch = false

              if self.overdueFirst == false {
                newSwitch = true
              }

              UserDefaults.standard.set(newSwitch, forKey: "Overdue First")
            }
          }

          Spacer()
          Text("By enabling this option, the cards will be ordered such that you will revise all overdue cards before you start learning new words.")
            .font(.system(size: 12))
        }
      }
    }

【问题讨论】:

  • 尝试从onAppear() 中的用户默认值加载值并调试以查看发生了什么。麻生onTapGuesture可以降为self.overdueFirst.toggle()

标签: swiftui watchos


【解决方案1】:

您的.onTapGesture 超过Toggle 不会被调用,因为后者不允许它(自己处理点击,甚至.simultaneousGesture 也无济于事)

这是实现目标的可能方法(使用 Xcode 11.2 / iOS 13.2 测试)

...
// define proxy binding, wrapping direct work with UserDefaults
private let overdueFirst = Binding<Bool>(
    get: { UserDefaults.standard.bool(forKey: "Overdue First") },
    set: { UserDefaults.standard.set($0, forKey: "Overdue First") })

var body: some View {
  VStack {
    HStack {
      Toggle(isOn: overdueFirst) { // use proxy binding directly
        Text("Overdue cards first")
      }
    }
    ...

不过,我建议将此 Toggle 直接与您的 UserSettings 对应属性绑定,并在那里处理与 UserDefaults 的同步(例如在 didSet 上)。

【讨论】:

  • 谢谢,此代码有效。您介意详细说明您的最后一段吗?
猜你喜欢
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
  • 2021-12-01
  • 1970-01-01
  • 2013-01-24
  • 2021-02-02
  • 2020-05-21
  • 2018-09-28
相关资源
最近更新 更多