在 tableview 滚动时拦截 UITableView 中的 TouchUpInside 事件
Posted
技术标签:
【中文标题】在 tableview 滚动时拦截 UITableView 中的 TouchUpInside 事件【英文标题】:Intercept TouchUpInside event in UITableView while tableview scrolls 【发布时间】:2013-05-21 00:01:52 【问题描述】:我正在构建一个 UITableView,它在 tableview 的部分标题中有一个按钮,因此当用户向下滚动屏幕时,该按钮被固定在屏幕顶部。
问题在于,当 UITableView 移动时,节标题按钮的触摸事件没有注册。如果 tableview 不滚动,按钮只会获取触摸事件。
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
if (!_sectionHeaderView)
_sectionHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)];
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
backButton.frame = CGRectMake(0, 0, 50, 50);
[backButton setImage:[UIImage imageNamed:@"upArrow"] forState:UIControlStateNormal];
[backButton addTarget:self action:@selector(scrollToTop:) forControlEvents:UIControlEventTouchUpInside];
[_sectionHeaderView addSubview:backButton];
return _sectionHeaderView;
目前,发生的情况是: - 如果 tableview 没有滚动,按钮会按预期执行:点击它,按钮会获得 TouchUpInside 手势。 - 如果 tableview 正在滚动,则按钮不会获得 TouchUpInside 手势 - 相反,tableview 会停止在原地。
我尝试将 UITableView 子类化并查看 touchesBegan: 方法等,但没有成功。我看到了相同的模式:手势仅在 tableview 不移动时显示。
更新: 这不是可用性问题 - 虽然我无法显示我正在处理的设计的屏幕截图,但在部分标题中使用按钮和控件是一个有效的用例。
这里有一个简单的草图来解释原因:
【问题讨论】:
这会导致糟糕的用户体验,正如@Undo 已经提到的,我强烈建议不要这样做。 @Stunner 我已经用图片更新了问题,以阐明用户体验 啊,我明白了……现在更有意义了。 【参考方案1】:想通了!您需要做的就是继承UITableView
,并覆盖hitTest:withEvent:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
if ([[super hitTest:point withEvent:event] isKindOfClass:[UIButton class]])
UIButton *buttonThatWasTapped = (UIButton *)[super hitTest:point withEvent:event];
[buttonThatWasTapped sendActionsForControlEvents:UIControlEventTouchUpInside];
return [super hitTest:point withEvent:event];
以下是这段代码的作用:如果触摸了 tableview,并且触摸发生在 UIButton 的边界内,则 tableview 会将触摸事件转发给 UIButton。
这里有一个警告:触摸事件可能会多次发送到 UIButton(我看到每次触摸都会进行 3 次调用)。此代码足以满足我的需求,但如果您在应用中使用此代码,请注意该问题 - 您可能需要修改上述代码以解决此问题。
【讨论】:
【参考方案2】:这是应该发生的。
用户已经习惯了这种行为——当他们看到他们想要触摸的东西时,它允许他们停止表格视图的滚动。
想象一下,我正在滚动一个表格以查找“独角兽”行,而我滚动的速度非常快(因为它是一张大桌子,我不确定独角兽在哪里)。当“独角兽”出现在我的视野中时,我会本能地停下桌子来选择它。
使用当前系统,我可以点击表格视图上的任意位置,它会停止。如果按照您的方式实现表格视图,我会点击“地下rockchucks”来停止表格,突然间我正在查看有关rockchucks的信息 - 我想要有关独角兽的信息。
我现在变成了一个心怀不满的用户,把你的应用退回给 Apple,然后拿回我的 0.99 美元。
您不希望用户这样做。
【讨论】:
这种设计没有 HIG 问题 - 我有一个 UITableView 部分,因此部分标题始终浮动在屏幕顶部。虽然我很欣赏这些反馈,但它不适用于我的设计。以上是关于在 tableview 滚动时拦截 UITableView 中的 TouchUpInside 事件的主要内容,如果未能解决你的问题,请参考以下文章
tableView和scrollView滚动起冲突,tableview不能滚动
iOS:滚动 UITableView 时应用程序崩溃/内存被填充