SwiftUI 切换开关

Posted

技术标签:

【中文标题】SwiftUI 切换开关【英文标题】:SwiftUI toggle switches 【发布时间】: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() 【参考方案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 上)。

【讨论】:

谢谢,此代码有效。您介意详细说明您的最后一段吗?

以上是关于SwiftUI 切换开关的主要内容,如果未能解决你的问题,请参考以下文章

用一个开关切换所有开关

将按钮标签更改为关闭声音的开关,我想显示一个开关(对象,切换)

如何使用 [(ngModel)] 两种方式数据绑定在 Angular 4 中创建切换开关开关按钮

创建切换/开关以显示不同的信息

使用带有 angularjs 和 jquery mobile 的翻转切换开关

5g怎么切换4g