自定义UITableViewCell控件阻挡回调不到didSelectRowAtIndexPath的解决办法
作为常用的控件,UITableView
出现在了很多iOS App的各个地方,近期开发时遇到了一个问题,自定义Cell中嵌套了其他具有交互事件的控件,阻挡了Cell,导致无法回调didSelectRowAtIndexPath
方法,最终得出解决办法。
一句话方案
将可能影响到Tap事件的控件的userInteractionEnabled
属性设置为NO
。
|
|
问题引出
为了在一个Cell中展示多个item,并且为了方便做分页处理,用UIScrollView
再合适不过了,由于需要,只能将这个UIScrollView
设置为全尺寸(scrollView的size和cell的size相同),由于scrollView
本身具备events,所以点击cell的时候,tableView
的didSelectRowAtIndexPath
无法响应。
像UIScrollView类似会引发这个问题的控件还有UITableView
、UICollectionView
、UITextField
等等,当子视图的尺寸覆盖了整个cell,你就会发现无法回调didSelectRowAtIndexPath
了。(当然如果子视图能不完全覆盖cell的话,点击未覆盖部分,还是可以正常回调的)。
原理
userInteractionEnabled
是一个布尔类型值,当设置为YES的时候,控件可以接收交互事件,同一位置的交互事件,其父控件无法接收交互事件。正是由于iOS对交互事件如此的处理方式,才导致了Cell无法回调didSelectRowAtIndexPath
的问题。当这个布尔值为NO
时,交互事件由其父视图来处理,如果直到根视图都无法处理这个交互,则抛弃这个交互,除非某一视图能够处理这个交互。
后记
其实这还不是最好的解决方法,原因是,很多情况下,我们既需要父视图来响应交互事件,又希望子视图处理一些交互事件,可这个解决方案直接把子视图的交互一棒子打死了。例如,我们在Cell上加了一个ScrollView,我们希望当用户tap的时候,回调didSelectRowAtIndexPath
,当swipe的时候,滚动scrollView
。所以在这里加一个TODO:完美的解决方案『子视图与父视图分别处理不同交互』。