UIScrollView 内的 UITableView 滚动后未收到第一次点击 [英] UITableView inside UIScrollView not receiving first tap after scrollling
问题描述
我在 UIScrollView
中遇到了 UITableView
的问题.当我滚动外部 scrollView
时,table
在第一次触摸时不会收到 willSelect/didSelect
事件,但在第二次触摸时会收到.更奇怪的是,即使 delegate
没有.
I am having an issue with a UITableView
inside a UIScrollView
. When I scroll the external scrollView
, the table
does not receive the willSelect/didSelect
event on the first touch, but it does on the second one. What is even more strange, the cell itself gets the touches and the highlighted state, even when the delegate
does not.
我的视图层次结构:
UIView
- UIScrollView (outerscroll)
- Some other views and buttons
- UITableView (tableView)
在滚动视图中,我有一些额外的视图可以动态展开/关闭.表格视图需要与视图的其他一些元素一起固定"在顶部,所以这就是我创建这个布局的原因,它允许我以类似于 Apple 推荐的方式轻松移动元素,当使用转换时滚动发生.
Inside the scroll view I have some extra views that get expanded/closed dynamically. The table view needs to get "fixed" on top, together with some other elements of the view, so that is why I created this layout, that allows me to easily move elements in a similar way than Apple recommends by the use of transformations when the scroll happens.
当outerscroll像这样移动时,tableView就变成了平移效果:
The table View is transformed with a translation effect when the outerscroll moves like this:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == self.outerScrollView) {
CGFloat tableOffset = scrollView.contentOffset.y - self.fixedHeaderFrame.origin.y;
if (tableOffset > 0) {
self.tableView.contentOffset = CGPointMake(0, tableOffset);
self.tableView.transform = CGAffineTransformMakeTranslation(0, tableOffset);
}
else {
self.tableView.contentOffset = CGPointMake(0, 0);
self.tableView.transform = CGAffineTransformIdentity;
}
// Other similar transformations are done here, but not involving the table
}
在我的单元格中,如果我实现这些方法:
In my cell, if I implement these methods:
- (void)setSelected:(BOOL)selected {
[super setSelected:selected];
if (selected) {
NSLog(@"selected");
}
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
[super setHighlighted:highlighted animated:animated];
if (highlighted) {
NSLog(@"highlighted");
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
NSLog(@"touchesBegan");
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesEnded:touches withEvent:event];
NSLog(@"touchesEnded");
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesCancelled:touches withEvent:event];
NSLog(@"touchesCancelled");
}
失败时你可以看到这个输出(第一次点击):
Y can see this output when fails (first tap):
2014-02-10 13:04:40.940 MyOrderApp[5588:70b] highlighted
2014-02-10 13:04:40.940 MyOrderApp[5588:70b] touchesBegan
2014-02-10 13:04:40.978 MyOrderApp[5588:70b] touchesEnded
这个在工作时(第二次点击):
And this one when works (second tap):
2014-02-10 13:05:30.359 MyOrderApp[5588:70b] highlighted
2014-02-10 13:05:30.360 MyOrderApp[5588:70b] touchesBegan
2014-02-10 13:05:30.487 MyOrderApp[5588:70b] touchesEnded
2014-02-10 13:05:30.498 MyOrderApp[5588:70b] expanded
在第一次和第二次点击之间没有进行其他帧更改、动画或任何其他视图交互.此外,只有在大量滚动时才会出现错误,但仅滚动几个像素时,一切都会按预期工作.
No other frame change, animation or any other view interaction is done between the first and the second tap. Also, only when scrolling large amounts the bug appears, but with scrollings of just a few pixels everything keeps working as expected.
我也尝试过更改一些属性,但没有成功.我做过的一些事情:
I experimented changing some properties as well, but with no luck. Some of the things I did:
- 从除滚动和表格之外的视图中删除
userInteractionEnabled
- 在
scrollViewDidScroll
发生时,在表格、滚动和主视图上添加对setNeedsLayout
的调用. - 从表中删除转换(仍然发生)
- Remove
userInteractionEnabled
from views other than the scroll and table - Add a call to
setNeedsLayout
on the table, scroll and main view whenscrollViewDidScroll
occurs. - Remove the transformations from the table (still happens)
我看到了一些关于在 UIScrollViews
中嵌入 UITableViews
的意外行为的评论,但我在 Apple 的官方文档中看不到这样的警告,所以我期待它工作.
I have seen some comments about the unexpected behaviour of embedding UITableViews
inside UIScrollViews
but I can not see such a warn in the official documentation by Apple, so I am expecting it to work.
该应用仅适用于 iOS7+.
The app is iOS7+ only.
有没有人遇到过类似的问题?为什么会这样,我该如何解决?我认为我可以拦截单元格上的点击手势并使用自定义委托或类似方式传递它,但是我希望表格接收正确的事件,所以我的 UITableViewDelegate
按预期接收.
Has anyone experienced similar issues? Why is this and how can I solve it? I think that I could be able to intercept the tap gesture on the cell and pass it with a custom delegate or similar, but I would like the table to receive the proper events and so my UITableViewDelegate
receives it as expected.
- 我尝试按照评论中的建议禁用单元格重用,但它仍然以相同的方式发生.
推荐答案
保留内部 UITableView 的 scrollEnabled
属性设置为 YES
.这让内部 UITableView
知道正确处理 UIScrollView
上与滚动相关的触摸.
leave the inner UITableView's scrollEnabled
property set as YES
. this lets the inner UITableView
know to handle scroll-related touches on the UIScrollView
correctly.
这篇关于UIScrollView 内的 UITableView 滚动后未收到第一次点击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!