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()
                }
            }
        }
    }
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
今天 13:54
点赞 评论 收藏
分享
叶扰云倾:进度更新,现在阿里云面完3面了,感觉3面答得还行,基本都答上了,自己熟悉的地方也说的比较细致,但感觉面试官有点心不在焉不知道是不是不想要我了,求阿里收留,我直接秒到岗当阿里孝子,学校那边的房子都退租了,下学期都不回学校,全职猛猛实习半年。这种条件还不诱人吗难道 然后现在约到了字节的一面和淘天的复活赛,外加猿辅导。华为笔试完没动静。 美团那边之前投了个base广州的,把我流程卡麻了,应该是不怎么招人,我直接简历挂了,现在进了一个正常的后端流程,还在筛选,不知道还有没有hc。
点赞 评论 收藏
分享
小叮当411:应该是1-3个月吧
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务