如何让超出祖父视图frame范围的UIButton可正常响应点击事件
iOS超父视图范围按钮无法响应点击解决方案
问题根因
你之前的实现存在两个核心错误:
hitTest重写位置错误:超出自身frame范围的视图默认不会接收到点击事件,你把hitTest写在超出祖父视图的圆形小父视图上,系统根本不会把点击事件传递给这个父视图,重写逻辑永远不会触发- 坐标判断错误:
hitTest输入的point是当前视图的本地坐标系,你直接用按钮的frame(相对于其直接父视图的坐标)判断匹配,坐标体系不一致导致判断失效
解决方案
最优方案:在祖父视图中重写hitTest方法
点击事件会优先传递给最上层的根响应视图,你在承载圆形小UIView的祖父视图中重写该方法,手动判断点击位置是否落在目标按钮上,直接返回按钮作为响应者即可。
代码示例:
// 承载圆形小UIView的祖父视图类中添加以下重写 override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { // 先将当前点击坐标转换为圆形小父视图的本地坐标系 let convertPoint = self.convert(point, to: 你的圆形小UIView实例) // 判断坐标是否落在两个按钮范围内 if let rightBtn = rightLastNodeButton, rightBtn.frame.contains(convertPoint) { return rightBtn } if let leftBtn = leftLastNodeButton, leftBtn.frame.contains(convertPoint) { return leftBtn } // 不匹配则走默认响应逻辑 return super.hitTest(point, with: event) }
额外检查项
- 确认所有上层视图的
isUserInteractionEnabled属性均为true,没有被禁用交互 - 确认按钮的层级没有被其他透明视图遮挡
- 若你之前的代码是直接把按钮加到外层视图而非圆形小UIView内,需要先把按钮添加到圆形小UIView中,再将圆形小UIView添加到祖父视图
内容的提问来源于stack exchange,提问作者Noah Iarrobino
相关产品推荐
相关产品推荐

