Objective-C 11英寸iPad Pro侧边菜单点击无响应问题
问题描述
项目集成的侧边滑出菜单(Side Out Menu)在除11英寸iPad Pro之外的所有设备上均可正常运行;但在11英寸iPad Pro设备上,UITableView的其他相关方法均能正常执行,唯独didSelectRowAtIndexPath行点击回调方法无法触发,暂未定位到问题根因。
相关代码片段
AppDelegate.m 实现
[[ApplicationDelegate window] setRootViewController: [storyboard instantiateInitialViewController]]; [[SlideNavigationController sharedInstance] initWithRootViewController:destinationViewController]; // SlideNavigation Width int num = isTargetedSize ? 3 : 2; CGFloat portraitSlideOffset = [UIScreen mainScreen].bounds.size.width / num; // SlideNavigation UIViewController *viewController = (SlideOutMenuViewController *)[storyboard instantiateViewControllerWithIdentifier: @"SlideOutMenuViewController"]; [[SlideNavigationController sharedInstance] setLeftMenu: viewController]; [[SlideNavigationController sharedInstance] setMenuRevealAnimationDuration: 0.25f]; [[SlideNavigationController sharedInstance] setEnableSwipeGesture:YES]; [[SlideNavigationController sharedInstance] setPortraitSlideOffset:portraitSlideOffset];
SlideOutMenuViewController.m 中viewDidLoad实现
- (void)viewDidLoad { [super viewDidLoad]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; modulesArray = [defaults objectForKey:@"modulesArray"]; NSLog(@"viewDidLoad_Slide"); [self mapAuthModules]; // Auto resize table view cell self.tableView.rowHeight = UITableViewAutomaticDimension; // self.tableView.rowHeight = 44; // self.tableView.cancelsTouchesInView = false serviceGroup = dispatch_group_create(); }
排查与解决步骤
11英寸iPad Pro是首款全面屏iPad,Safe Area布局逻辑、屏幕点尺寸和非全面屏iPad存在差异,这类设备独有的点击失效问题基本都是布局错位、手势冲突、属性配置遗漏导致,按以下顺序排查即可:
- 检查菜单容器点击区域是否被遮挡
侧边菜单父容器很容易因为frame计算偏差,出现实际可交互区域没有覆盖TableView Cell位置的问题:- 调试时给
SlideOutMenuViewController的根视图、tableView分别加上不同颜色的边框,展开菜单后打印两个视图的frame值,确认是否存在tableView的frame超出父视图bounds的情况 - 核对
portraitSlideOffset计算逻辑:当前代码通过屏幕宽度除以2/3得到偏移量,11英寸iPad Pro竖屏状态下屏幕宽度点值为834,计算出的偏移量为417,需要确认菜单控制器的视图实际宽度和这个偏移量完全匹配,避免菜单视图实际宽度大于偏移量、部分Cell在可见区域但落在屏幕外无法响应点击的问题
- 调试时给
- 检查手势冲突
当前代码开启了setEnableSwipeGesture:YES,11英寸iPad Pro的系统边缘返回手势、第三方侧边栏的滑动手势优先级可能和TableView的点击手势冲突:- 临时关闭侧滑手势测试点击是否恢复,如果确认是手势问题,打开代码中注释的
self.tableView.cancelsTouchesInView = false,同时给SlideNavigation的侧滑手势设置cancelsTouchesInView = NO,避免手势拦截Cell的点击事件 - 用Xcode的视图层级调试工具查看点击Cell位置的最上层视图,排查是否有透明的遮挡View盖在TableView上方打断点击事件,这类透明View大多是Safe Area适配逻辑异常生成的
- 临时关闭侧滑手势测试点击是否恢复,如果确认是手势问题,打开代码中注释的
- 检查TableView自身配置
- 确认
self.tableView.allowsSelection属性值为YES,排查其他代码逻辑是否针对iPad类型修改过该属性 - 检查自动算高逻辑:当前代码只设置了
rowHeight = UITableViewAutomaticDimension,没有配置estimatedRowHeight,部分iOS版本在全面屏iPad上会因为预估高度缺失,出现Cell可见但实际点击命中区域和显示位置错位的问题。临时把rowHeight固定为44(即代码中注释的那行)测试,如果固定高度后点击恢复,补全预估高度配置即可:self.tableView.estimatedRowHeight = 44; self.tableView.rowHeight = UITableViewAutomaticDimension; - 核对
didSelectRowAtIndexPath的方法签名,确认没有拼写错误、参数符合系统方法定义
- 确认
- 检查视图交互属性
逐层检查菜单根视图、TableView父视图的userInteractionEnabled属性是否为YES,部分第三方侧边栏组件在全面屏设备适配时会动态修改菜单容器的交互开关,导致子视图无法响应点击。
高概率快速修复方案
优先尝试以下两个改动,绝大多数同类问题都是这两个原因导致:
- 打开注释的
self.tableView.cancelsTouchesInView = false;,同时补全TableView的estimatedRowHeight配置 - 调整
portraitSlideOffset计算逻辑,将Safe Area宽度纳入计算,不要直接用全屏幕宽度做除法:
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; if (@available(iOS 11.0, *)) { UIWindow *mainWindow = [UIApplication sharedApplication].delegate.window; CGFloat safeAreaWidth = mainWindow.safeAreaLayoutGuide.layoutFrame.size.width; screenWidth = safeAreaWidth > 0 ? safeAreaWidth : screenWidth; } CGFloat portraitSlideOffset = screenWidth / num;
内容的提问来源于stack exchange,提问作者fares
相关产品推荐
相关产品推荐

