iOS应用中UIScrollView交互式收起键盘功能失效问题排查
解决UIScrollView嵌套UITextView时交互式收起键盘无响应的问题
兄弟,我太懂这个坑了!你遇到的问题核心原因很简单:UITextView本身自带滚动功能,当你在它上面滑动时,滑动手势直接被它自己拦截处理了,根本没传到父级的UIScrollView那里,所以你开的「Dismiss Interactively」自然就没反应了。
下面给你几个实用的解决方案,按需选就行:
方法一:禁用UITextView的滚动(适合不需要它滚动的场景)
如果你的UITextView内容不会超出显示范围,直接把它的滚动功能关掉就完事了:
- 在Storyboard里选中UITextView,找到「Scrolling Enabled」选项取消勾选;
- 或者用代码设置:
这样UITextView就不会抢手势了,父级UIScrollView的交互式键盘收起就能正常工作。textView.isScrollEnabled = false
方法二:保留UITextView滚动,让手势同时被识别
要是你的UITextView必须支持滚动,那就得让滑动手势同时被UITextView和UIScrollView处理:
- 自定义一个UIScrollView子类,实现手势代理:
class CustomScrollView: UIScrollView, UIGestureRecognizerDelegate { override init(frame: CGRect) { super.init(frame: frame) panGestureRecognizer.delegate = self } required init?(coder: NSCoder) { super.init(coder: coder) panGestureRecognizer.delegate = self } func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { // 允许UITextView的滚动手势和自身的pan手势同时识别 if otherGestureRecognizer.view is UITextView { return true } return false } } - 把Storyboard里的UIScrollView替换成这个自定义类,这样滑动UITextView时,UIScrollView也能收到手势事件,触发交互式键盘收起。
方法三:监听UITextView滚动,手动触发键盘收起
如果上面两种方法都不符合你的需求,还可以通过监听UITextView的滚动状态,手动触发键盘收起:
- 给UITextView添加滚动监听:
textView.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil) - 在监听方法里判断滑动动作:
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { guard keyPath == "contentOffset", let textView = object as? UITextView else { return } // 当textView已经滚到顶部,还继续向下拉时,收起键盘 if textView.contentOffset.y < -15 { // 阈值可以根据需求调整 view.endEditing(true) } } - 记得在控制器销毁时移除监听:
deinit { textView.removeObserver(self, forKeyPath: "contentOffset") }
另外补充一句:确认下你的UIScrollView的contentInsetAdjustmentBehavior设置是否正常,确保键盘弹出后它的布局能正确调整,不过这一般不是导致手势无响应的核心问题。
内容的提问来源于stack exchange,提问作者Laurent Crivello
相关产品推荐
相关产品推荐

