SwiftUI Tips:如何隐藏键盘

首先需要引入一个方法调用系统接口隐藏键盘:

extension UIApplication {
    func endEditing() {
        sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
}

// 也可以把辅助方法添加到 View 上
extension View {
    func endEditing() {
        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
  
    // 还有一种实现是通过获取 keyWindow 调用到 UIView 的 endEditing
    func endEditing() {
      UIApplication.shared.windows.filter {$0.isKeyWindow}.first?.endEditing(true)
    }
}

隐藏最简单的处理方式就是在键盘按 return 的时候隐藏键盘:

struct ContentView: View {
    @State private var name: String = ""
    
    var body: some View {
        TextField("名字:", text: $name)
            .onSubmit {
                UIApplication.shared.endEditing()
            }
    }
}

对键盘的常见处理方式还有点击空白处隐藏键盘。可以通过添加 Tap 手势来达到目的。

var body: some View {
    ZStack {
        Color.white
            .onTapGesture {
                UIApplication.shared.endEditing()
            }
        TextField("名字:", text: $name)
            .onSubmit {
                UIApplication.shared.endEditing()
            }
    }
}

如果点击隐藏键盘要全局处理,也可以把 TapGesture 直接加在 window 上:

@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
    }
}

在 iOS 15 中 SwiftUI 引入了@FocusState 来控制焦点,所以官方推荐的一个方案是通过设置焦点的值来控制键盘的弹出与隐藏。

AnimatedImage.gif

老实说系统推荐的焦点控制有一种清澈的愚蠢。

struct FocusStateView: View {
    @State private var name: String = ""
    @FocusState private var focusedField: Bool
    
    var body: some View {
        VStack {
            TextField("名字", text: $name)
                .focused($focusedField)
            HStack {
                Button("focus") {
                    focusedField = true
                }
                Button("dismiss") {
                    focusedField = false
                }
            }
        }
        .padding()
    }
}

还有一种常见的键盘处理方案是在键盘上面添加一个工具栏,增加一个完成按钮。在 SwiftUI 中也可以很容易的实现这个功能。

AnimatedImage.gif
struct ContentView: View {
    @State private var name: String = ""
    
    var body: some View {
        VStack {
            TextField("名字:", text: $name)
                .padding()
        }
        .toolbar {
            ToolbarItemGroup(placement: .keyboard) {
                Spacer()
                Button("完成") {
                    UIApplication.shared.endEditing()
                }
            }
        }
    }
}
全部评论

相关推荐

牛舌:如果我不想去,不管对方给了多少,我一般都会说你们给得太低了。这样他们就会给下一个offer的人更高的薪资了。
点赞 评论 收藏
分享
听说改名字就能收到offer哈:Radis写错了兄弟
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务