通过触摸关闭iOS键盘:反模式及3个Swift实用解决方案

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么键盘不会自动关闭?

\n

你好,开发者同行!如果你曾经在iOS上编写过登录表单、搜索栏或即时通讯应用,那么你一定遇到过这种情况:用户输入了文本,但键盘却固执地停留在屏幕上。用户没有按下“完成”按钮,而是点击空白区域,但什么也没有发生。经典问题。

\n\n

这是Stack Overflow上最热门的话题之一,其中问题"使用Swift通过任意位置点击关闭iOS键盘"获得了数千次浏览。问题不在于实现困难,而在于新手(甚至不止新手)常常选择错误或“不优雅”的方法。让我们先分析3个最常见的错误,然后再看三种正确且实用的解决方案。

\n\n

今天我们讨论的是Swift和UIKit。如果你使用SwiftUI,也请参考一下,原理是相似的。

\n\n

错误#1:“在所有地方添加点击手势”

\n

最常见的错误是在UIView上添加UITapGestureRecognizer,但忘记禁用cancelsTouchesInView。结果导致按钮和表格无法响应点击。用户点击“发送”按钮,但触发的是键盘关闭,而不是表单提交。

\n\n

错误代码示例:

\n
override func viewDidLoad() {\n    super.viewDidLoad()\n    let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))\n    view.addGestureRecognizer(tap)\n}\n\n@objc func dismissKeyboard() {\n    view.endEditing(true)\n}
\n\n

乍一看,似乎没问题。但实际上,如果你有UITableView或UIButton,它们的点击可能会被这个手势“吞掉”。当你将这样的手势添加到scrollView上时,这一点尤其明显。

\n\n

如何修复:

\n

添加一行代码tap.cancelsTouchesInView = false。这将允许其他界面元素接收触摸事件。

\n\n
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))\ntap.cancelsTouchesInView = false\nview.addGestureRecognizer(tap)
\n\n

但即使这样,如果你的界面复杂,这也不是一个完美的解决方案。

\n\n

错误#2:“点击空白区域破坏表格”

\n

第二个常见问题是与UIScrollView或UITableView的错误交互。如果你在包含表格的view上添加UITapGestureRecognizer,那么点击单元格时,手势和didSelectRow方法可能会同时触发。更糟糕的是,手势可能会拦截触摸,导致单元格无法被选中。

\n\n

解决方案:使用UIGestureRecognizerDelegate

\n

实现gestureRecognizer(_:shouldReceive:)方法,并检查点击是否发生在文本字段或其他元素上。如果触摸发生在UITextField或UITextView上,则不要拦截手势。

\n\n
extension ViewController: UIGestureRecognizerDelegate {\n    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {\n        // 如果触摸发生在文本字段上,则不拦截\n        if touch.view is UITextField || touch.view is UITextView {\n            return false\n        }\n        return true\n    }\n}
\n\n

现在,手势只会在点击空白区域时触发,而文本字段仍保持可交互状态。

\n\n

错误#3:“忘记处理键盘返回键”

\n

许多开发者实现了点击关闭键盘,但忘记了键盘上的“Return”(回车)按钮。用户可能会按下“完成”并期望键盘关闭。如果不这样做,将会带来糟糕的用户体验。

\n\n

如何修复:

\n

遵循UITextFieldDelegate协议并实现textFieldShouldReturn方法:

\n\n
class View                

博客

书籍推荐