如何为UINavigationBar右上角添加可限制响应区域的手势识别器
解决方案
你现有代码的核心问题是多嵌套了一层navigationController,导致宽度取值错误,计算出来的目标区域覆盖了整个导航栏范围,所以任意位置点击都会触发回调。按以下步骤修正即可:
- 修正手势回调内的坐标计算逻辑,直接基于导航栏自身的尺寸计算目标响应区域:
- (void)handleGestureForTopRightBarButtonItem:(UIGestureRecognizer *)gestureRecognizer { CGPoint p = [gestureRecognizer locationInView:self.navigationController.navigationBar]; CGFloat navBarWidth = self.navigationController.navigationBar.bounds.size.width; CGFloat navBarHeight = self.navigationController.navigationBar.bounds.size.height; // 自定义右上角响应区域,可根据实际需求调整宽高偏移 CGRect targetRegion = CGRectMake(navBarWidth - 120, 0, 100, navBarHeight); if (CGRectContainsPoint(targetRegion, p)) { NSLog(@"点击了目标右上角区域"); } else { NSLog(@"点击了导航栏其他区域"); } }
- 如果需要彻底避免非目标区域触发手势回调,可以搭配手势代理提前过滤,性能更优:
- 初始化手势时设置代理:
tapGesture.delegate = self; - 实现UIGestureRecognizerDelegate代理方法:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { CGPoint p = [touch locationInView:self.navigationController.navigationBar]; CGFloat navBarWidth = self.navigationController.navigationBar.bounds.size.width; CGFloat navBarHeight = self.navigationController.navigationBar.bounds.size.height; CGRect targetRegion = CGRectMake(navBarWidth - 120, 0, 100, navBarHeight); return CGRectContainsPoint(targetRegion, p); }
- 适配优化建议:如果右上角是自定义UIBarButtonItem,可以直接获取item对应view的frame作为判断区域,不用硬编码尺寸,适配横竖屏、不同设备尺寸的效果更好。
内容的提问来源于stack exchange,提问作者stefanosn
相关产品推荐
相关产品推荐

