我正在构建一个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;
}
目前,会发生什么: - 如果桌面视图没有滚动,则按钮按预期执行:点击它,按钮将获得TouchUpInside手势。 - 如果桌面视图正在滚动,则该按钮不会获得TouchUpInside手势 - 相反,桌面视图就会停止。
我已经尝试了子类化UITableView并查看touchesBegan:方法等,但是没有用。我看到相同的模式:只有/当桌面视图没有移动时,手势才会出现。
更新 这不是一个可用性问题 - 虽然我无法显示我正在进行的设计的截图,但它是使用按钮和放大器的有效用例。节标题中的控件。
这是一个快速草图来解释原因:
答案 0 :(得分:6)
想出来!您需要做的只是子类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次电话)。此代码足以满足我的需求,但如果您在应用中使用此代码,请注意该问题 - 您可能需要修改上述代码才能解决此问题。
答案 1 :(得分:2)
用户习惯于这种行为 - 它允许他们在看到他们想要触摸的内容时停止表格视图的滚动。
想象一下,我正在滚动表格寻找行'独角兽',我正在快速滚动 (因为它是一张大桌子,我不确定独角兽在哪里)。当'独角兽'穿过我的视线时,我会本能地停止桌子选择它。
使用当前系统,我可以点击表格视图中的任何位置,它将停止。如果表格视图是按照你的方式实现的,我会点击“地下rockchucks”来阻止桌子,突然间我正在查看关于rockchucks的信息 - 我想了解有关Unicorns的信息。
我现在变成了一个心怀不满的用户,将你的应用程序返还给Apple,并获得0.99美元。
您不希望用户这样做。