场景:
页面用UIScrollView布局,ScrollView上添加各种控件,其中有UITextField输入框,输入内容完毕之后,期望是点击ScrollView上的空白区域,键盘能收回。
方案:
1、ScrollView添加UIControl,UIControl的大小跟ScrollView一致,在UIControl绑定touchUpInside方法,即
// 开发语言为Swift5.0语法。布局,这里用的SnapKit。
// 注意:布局不要用 make.left.right.top.bottom.equalTo(bgScrollView),会导致UIControl不能正常加载。
control.snp.makeConstraints({ (make) in
make.top.equalTo(bgScrollView)
make.width.equalTo(ScreenWidth)
make.centerX.equalTo(bgScrollView)
make.height.equalTo(view.height)
})
// 绑定
control.addTarget(self, action: #selector(resignKeyBoard), for: .touchUpInside)
// Action 其中,MainWindow = UIApplication.shared.windows.first
@objc func resignKeyBoard() {
MainWindow?.endEditing(true)
}
结论:这种方案确实可以解决点击空白区域,让键盘收起问题。但新的问题来了,当屏幕内容视图超过一屏时,我们修改完bgScrollView的contentSize
之后,必须要同时更新control的height
,不然点击超过一屏的空白区域,不会执行resignKeyBoard()
方法,相对比较麻烦。
2、ScrollView添加UITapGestureRecognizer手势,即:
// cancelsTouchesInView属性是为了防止手势点击事件与ScrollView上其他控件的点击事件出现冲突。
// 比如说UITableView(继承于UIScrollView)上的didSelectRowAt事件。
_ = UITapGestureRecognizer(target: self, action: #selector(resignKeyBoard)).then({ (g) in
bgScrollView.addGestureRecognizer(g)
g.cancelsTouchesInView = false
})
// Action 其中,MainWindow = UIApplication.shared.windows.first
@objc func resignKeyBoard() {
MainWindow?.endEditing(true)
}
结论:该方案相对比较简洁,建议采纳。不过目前也发现了新问题,如果是输入状态下,点击输入框右边的清除按钮x
,无法清除输入框内容,而是收起键盘,也就是添加的点击手势覆盖了清除事件。
Tips:如果对交互体验要求比较高,建议采取方案1
,虽然代码量多点,但基本上不会影响ScrollView上其他控件的交互。如果对体验要求不是特别高,可以采取方案2
,毕竟有效减少代码量。