SwiftUI 3 (iOS 15+)
(键盘上方的完成按钮)
从 iOS 15 开始,我们现在可以使用 @FocusState 来控制应该关注哪个字段(请参阅 this answer 以查看更多示例)。
我们也可以直接在键盘上方添加ToolbarItems。
组合在一起时,我们可以在键盘正上方添加一个Done 按钮。这是一个简单的演示:
struct ContentView: View {
private enum Field: Int, CaseIterable {
case username, password
}
@State private var username: String = ""
@State private var password: String = ""
@FocusState private var focusedField: Field?
var body: some View {
NavigationView {
Form {
TextField("Username", text: $username)
.focused($focusedField, equals: .username)
SecureField("Password", text: $password)
.focused($focusedField, equals: .password)
}
.toolbar {
ToolbarItem(placement: .keyboard) {
Button("Done") {
focusedField = nil
}
}
}
}
}
}
SwiftUI 2 (iOS 14+)
(点击任意位置隐藏键盘)
这是 SwiftUI 2 / iOS 14 的更新解决方案(最初由 Mikhail 提出 here)。
它不使用AppDelegate 或SceneDelegate,如果您使用 SwiftUI 生命周期,则缺少这些:
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onAppear(perform: UIApplication.shared.addTapGestureRecognizer)
}
}
}
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)
}
}
extension UIApplication: UIGestureRecognizerDelegate {
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true // set to `false` if you don't want to detect tap during other gestures
}
}
如果您想检测其他手势(不仅是tap 手势),您可以使用 AnyGestureRecognizer,如 Mikhail 的 answer:
let tapGesture = AnyGestureRecognizer(target: window, action: #selector(UIView.endEditing))
这是一个如何检测除长按手势以外的同时手势的示例:
extension UIApplication: UIGestureRecognizerDelegate {
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return !otherGestureRecognizer.isKind(of: UILongPressGestureRecognizer.self)
}
}