【问题标题】:How can I detect when TextField is tapped? (SwiftUI on MacOS)如何检测何时点击 TextField? (MacOS 上的 SwiftUI)
【发布时间】:2019-11-22 04:40:54
【问题描述】:

如何检测何时点击了 TextField? (MacOS 上的 SwiftUI)

import SwiftUI

struct ContentView: View {
  @State var field: String = "TextField"
  
  var body: some View {
    TextField("Fill in Text", text: $field)
      .onTapGesture {
        print("Textfield pressed")
    }
  }
}

当文本字段被点击时,它不会打印“按下文本字段”。 我猜这是因为在 TextField 手势检测到之前,TextField 会拾取点击。

【问题讨论】:

    标签: swift swiftui touch textfield gesture


    【解决方案1】:

    新方法(不向后兼容)

    有一个名为@FocusState 的新包装器,它控制键盘和焦点键盘('aka' firstResponder)的状态。

    检测焦点状态

    你可以用.onChange修饰符观察@FocusState变量的变化

    成为第一响应者(专注)

    如果在文本字段上使用focused修饰符,可以使它们变为焦点,例如,可以在代码中设置focusedField属性,使绑定的文本字段变为活动状态:

    辞去第一响应者(关闭键盘)

    或通过将变量设置为 nil 来关闭键盘:

    不要忘记观看来自 WWDC2021 的 Direct and reflect focus in SwiftUI 会议


    旧方法(向后兼容和向前兼容)

    您可以检测TextField 何时在onEditingChanged 内部轻松聚焦,而不是Taping:

    TextField("Fill in Text", text: $field, onEditingChanged: { focused in
        print(focused ? "focused" : "unfocused")
    }
    

    【讨论】:

    • 这是错误的,用这种方法你检测到onEditingChanged 而没有别的。如果您只点击文本字段,则不会触发。
    【解决方案2】:

    .simultaneousGesture 修饰符可以满足您的需要。

    这是一个例子:

    struct TestTextTap: View {
        @State var field: String = "TextField"
    
        var body: some View {
          TextField("Fill in Text", text: $field)
            .simultaneousGesture(TapGesture().onEnded {
              print("Textfield pressed")
            })
        }
    }
    

    【讨论】:

    • 感谢 Asperi 的回复。在我的机器上,这适用于 iOS 模拟器,但不能作为我需要的 macOS 应用程序运行!
    • 有没有办法获取textfield的部分文本?
    【解决方案3】:

    我能够得到预期的结果,但是在 macOS 可以在文本字段中注册一个点击之前,感觉有点笨拙。

    我在 TextField 顶部覆盖了一个几乎透明的矩形。如果此时感应到点击,则 TextField 将无法选择,但在 SwiftUI 中,您可以使用 @FocusState 布尔值使其成为焦点。

    所以当感应到 onTapGesture 时,它​​会将@FocusState 变量更改为 true,这将让用户在 TextField 中键入。

    macOS 中让一切变得如此复杂的微小差异有时令人抓狂。

        @State var field: String = "TextField"
        @FocusState private var textFieldIsFocused: Bool
    
        var body: some View {
            TextField("Fill in Text", text: $field)
                .focused($textFieldIsFocused)
                .overlay((Color.white.opacity(0.0001)))
                .onTapGesture {
                    self.textFieldIsFocused = true
                    print("Textfield pressed")
                }
        }
    

    抱歉,已编辑,因为我意识到我没有包含 .focused 方法!

    【讨论】:

      猜你喜欢
      • 2021-02-15
      • 1970-01-01
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-04
      相关资源
      最近更新 更多