UIScrollView 内的 UITableView 滚动后未收到第一次点击 [英] UITableView inside UIScrollView not receiving first tap after scrollling

查看:35
本文介绍了UIScrollView 内的 UITableView 滚动后未收到第一次点击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 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 when scrollViewDidScroll 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆