滚动 UICollectionView 时忽略嵌入式 UIButtons 的触摸事件

Posted

技术标签:

【中文标题】滚动 UICollectionView 时忽略嵌入式 UIButtons 的触摸事件【英文标题】:Ignoring Touch Events of embedded UIButtons when scrolling UICollectionView 【发布时间】:2014-03-03 23:00:20 【问题描述】:

我有一个自定义 UICollectionViewCell,其中包含一些自定义 UIView 对象。这些 UIView 中的每一个都有一个 UIButton,它响应 IBActions 链接的 Touch Down 和 Touch Up Inside。基本上,我希望这些按钮在按下时缩小并在松开时弹回原来的大小。我可以通过控件轻松完成此操作,并且按下和按下即可。但是,我面临的问题是在将滚动引入混合时发生的。这些单元格所在的 UICollectionView 是滚动的。如果我在开始滚动时碰巧触摸了一个按钮,则会触发 Touch Down 事件以及 UICollectionView 的滚动事件。如果我没记错的话,ios7 之前的情况并非如此。当滚动事件开始时,UIButton 事件没有被触发,我认为它与 delaysContentTouches 有关。这看起来现在被打破或改变了。它实际上仍然可以在 iPhone 上正常运行,只是在 iPad 上不行。如果我在 iPad 上滚动视图,在嵌入式 UIButton 内开始触摸,按钮将缩小,按钮操作将被触发。

所以,我尽可能简单地重申这个问题:在滚动发生时是否有忽略嵌入式 UIButtons 的触摸?当没有触发滚动时,触摸工作正常,如果用户确实在滚动,我只是不希望事件触发。有什么解决办法吗?

如果您需要任何更具体的细节,我很乐意帮助您理解。

【问题讨论】:

你解决过这个问题吗?我遇到了完全相同的问题。 【参考方案1】:

你需要继承scrollView(collectionView或tableView)并覆盖

- (BOOL)touchesShouldCancelInContentView:(UIView *)view 
if ([view isKindOfClass:UIButton.class]) 
    return YES;

return [super touchesShouldCancelInContentView:view];

迅速

override func touchesShouldCancelInContentView(view: UIView) -> Bool if view is UIButton return true return super.touchesShouldCancelInContentView(view)

就是这样,您现在可以滚动按钮而不丢失按钮点击事件。

【讨论】:

【参考方案2】:

在我的 UICollectionView 中,即使 UICollectionView 仍在减速,UICollectionViewCells 内的按钮也注册了 TouchUpInside-taps,这听起来与您遇到的问题类似。我创建了一个覆盖 beginTrackingWithTouch:withEvent 的 UIButton 子类,如果它包含的 UIScrollView 正在减速或拖动,它将返回 NO。

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event

    UIView *superView = self;
    while((superView = [superView superview])) 
        if ([superView isKindOfClass:UIScrollView.class]) 
            UIScrollView *scrollView = (UIScrollView *)superView;

            if (scrollView.isDecelerating || scrollView.isDragging) 
                return NO;
            
        
    

    return [super beginTrackingWithTouch:touch withEvent:event];

【讨论】:

【参考方案3】:

想到的最简单的尝试是检查触发按钮操作时UIScrollView(您的UICollectionView)是否正在滚动或拖动。

if(! self.collectionView.dragging && ! self.collectionView.decelerating)

  // do action because we are not moving

你试过了吗?

【讨论】:

好吧,动作是从 UICollectionViewCell 内的 UIView 内的 UIButton 触发的。因此,我尝试将 CollectionView 作为超级视图访问,并根据它是减速还是拖动来确定是否应该执行该操作,CollectionView 返回它没有拖动或减速,即使它是。 您可以创建一个示例项目,我可以下载来尝试一下吗?

以上是关于滚动 UICollectionView 时忽略嵌入式 UIButtons 的触摸事件的主要内容,如果未能解决你的问题,请参考以下文章

iOS 10 GM 嵌入 UITableView 和 UICollectionView contentSize 错误且滚动指示器不显示

在 UITableView 中嵌入的自定义 UICollectionView 中执行 Segue

在 UIScrollView 中嵌入 UITableView/UICollectionView

向上滚动时保持 UICollectionView 中的滚动位置

向下滚动时 UICollectionView 出错

滚动时 UICollectionView 的滞后