【问题标题】:How to disable TextField with Toogle in SwiftUI?如何在 SwiftUI 中使用 Toggle 禁用文本字段?
【发布时间】:2022-01-10 12:00:31
【问题描述】:

在 swiftUI 中使用 Toogle 时应该如何正确禁用 TextField?如果我们禁用其中输入了某些值的 TextField,以下简单示例会在控制台中引发警告,删除它也不能解决问题。

struct ContentView: View {
@State var isToogleOn = false
@State var textFieldValue = ""

var body: some View {
    HStack {
        TextField("Placeholder", text: $textFieldValue)
            .disabled(!isToogleOn)
        Toggle("Activate textField", isOn: $isToogleOn)
        }
    }
}

文本框关闭时的警告:

=== AttributeGraph:通过属性 160396 检测到循环 === 2022-01-08 15:27:46.182588+0100 CrochetIo[15460:1558507] [SwiftUI] 在视图更新期间修改状态,这将导致未定义的行为

【问题讨论】:

    标签: ios swift swiftui textfield


    【解决方案1】:

    实际上是苹果的日志,所以我们不应该在意它们,但如果它们打扰到你,那是有可能解决的,因为它们被发布是因为TextField在禁用期间仍然是焦点。

    可能的方法是在切换时使用代理绑定并注入预设的副作用。

    使用 Xcode 13.2 / iOS 15.2 测试

    struct ContentViewTestToggleText: View {
        @State var isToogleOn = false
        @State var textFieldValue = ""
    
        var body: some View {
            HStack {
                TextField("Placeholder", text: $textFieldValue)
                    .disabled(!isToogleOn)
    
                let onToggle = Binding(
                    get: { self.isToogleOn },
                    set: {
                        if !$0 {
                            UIApplication.shared.endEditing()     // << here !!
                        }
                        
                        self.isToogleOn = $0
                    }
                )
                Toggle("Activate textField", isOn: onToggle)
            }
        }
    }
    
    extension UIApplication {
        func endEditing() {
            sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
        }
    }
    

    【讨论】:

      【解决方案2】:

      @Asperi 给出的原因是正确的,但我会建议其他解决方案。当关闭Toogle 时,让我们将焦点放在TextField 上,然后才将其禁用。

          @State var isToogleOn = false
          @State var textFieldIsDisabled = false
          @State var textFieldValue = ""
          
          @FocusState private var focusField: Field?
          
          var body: some View {
              HStack {
                  TextField("Placeholde", text: $textFieldValue)
                      .focused($focusField, equals: .textField1)
                      .disabled(textFieldIsDisabled)
                  Toggle("Activate textField", isOn: $isToogleOn)
                      .onChange(of: isToogleOn) { newValue in
                          focusField = nil
                          textFieldIsDisabled = !newValue
                      }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2022-01-21
        • 2019-08-17
        • 1970-01-01
        • 2011-01-25
        • 1970-01-01
        • 1970-01-01
        • 2021-07-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多