iOS 14+

Github: RickeyBoy

当用户输入完毕,经过点击空白处,方便完成键盘收起;一起也不影响其他正常的交互操作。这个需求的场景应该非常常见,大部分涉及键盘输入的时候,都会需求完成上述的功能。

先回顾一下 UIKit 中躲藏键盘的办法,本质上是需求获取到承载键盘的视图:

// 办法一:
textField.resignFirstResponder()
​
// 办法二:
view.endEditing(true)

那么其实关于 SwiftUI 来说,尽管没有之前 View 的概念了,但是相同能够获取到整个 App 的 window,然后调用 endEditing。为了方便,咱们直接给 UIApplication 添加 Extension:

extension UIApplication {
  func addTapGestureRecognizer() {
    guard let window = windows.first else { return }
    let tapGesture = UITapGestureRecognizer(target: window, action: #selector(UIView.endEditing))
    tapGesture.requiresExclusiveTouchType = false
    tapGesture.cancelsTouchesInView = false
    tapGesture.delegate = self
    window.addGestureRecognizer(tapGesture)
  }
}

需求留意的是,下面两个参数需求配置正确:

  • requiresExclusiveTouchType:默认为 true。这个属性是指是否答应多种手势输入,这儿的多种包含触摸、遥控器、触控笔等,所以能够配置成 false(当然不配置也不会有太大影响)
  • cancelsTouchesInView:默认为 true。这儿设置为 false,首要为了不影响其他手势的辨认。当前的 tap 手势被辨认出来之后,也不会触发 UITouch 的 cancel 办法,因而就不会中止 UITouch 的传递。

当然,为了不影响其他手势的辨认,还需求完成下面这个办法:

extension UIApplication: UIGestureRecognizerDelegate {
    public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true // 能够一起响应多个手势
    }
}

最后咱们只需求在整个 App 初始化时加上手势辨认就能够了:

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear(perform: UIApplication.shared.addTapGestureRecognizer)
        }
    }
}