UICollectionViewCell与UIScrollView取消didSelectItemAtIndexPath

时间:2013-01-12 22:33:32

标签: uiscrollview uicollectionview uicollectionviewcell

我有UICollectionView水平滚动以一次显示一个UICollectionViewCell。每个UICollectionViewCell都有一个垂直滚动UIScrollView作为子视图,用于滚动单元格的内容。 UICollectionViewCell覆盖的UIScrollView内部只有90%左右 - 即单元格的外框未被覆盖。

事实证明,UICollectionViewCell所涵盖的UIScrollView部分会取消UICollectionView委托didSelectItemAtIndexPath。因此,当在UIScrollView内进行简单点击时,此方法被调用,而如果点击发生在单元格的外部,即UIScrollView之外,则此方法被调用。

有关如何实现可以调用didSelectItemAtIndexPath方法的设置的任何建议,即使在UIScrollView内进行点击也是如此?

4 个答案:

答案 0 :(得分:32)

我发现最有效的方法是窃取panGestureRecognizerUIScrollView公开,userInteraction停用scrollView。这样,您就可以获得scrollview的行为,但在集合视图上保持交互。在UICollectionViewCell子类:

self.scrollView.userInteractionEnabled = NO;
[self.contentView addGestureRecognizer:self.scrollView.panGestureRecognizer];

这是Apple在WWDC 2014会话235(高级滚动浏览和触摸处理技术)中推荐和演示的方法

答案 1 :(得分:4)

这是一个UIScrollView子类方法,它维护单元选择功能,并且还允许UIControl选择(按钮等)和&滚动视图之外。

Swift 3

class CellContentScrollView: UIScrollView {

  override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    let hitTargetView = super.hitTest(point, with: event)
    return hitTargetView as? UIControl ?? (hitTargetView == self ? nil : superview)
  }

  override func didMoveToSuperview() {
    superview?.addGestureRecognizer(panGestureRecognizer)
  }

}

Swift 2

class CellContentScrollView: UIScrollView {

    // MARK: - UIView override

    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
        let hitTargetView = super.hitTest(point, withEvent: event)
        return hitTargetView as? UIControl ?? (hitTargetView == self ? nil : superview)
    }

    override func didMoveToSuperview() {
        superview?.addGestureRecognizer(panGestureRecognizer)
    }
}

<强>目标C

@implementation CellContentScrollView

    #pragma mark - UIView override

    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        UIView *hitTargetView = [super hitTest:point withEvent:event];

        if ([hitTargetView isKindOfClass:UIControl.class]) {
            return hitTargetView;
        } else if (hitTargetView != self) {
            return self.superview;
        }

        return nil;
    }

    - (void)didMoveToSuperview {
        [self.superview addGestureRecognizer:self.panGestureRecognizer];
    }

@end

答案 2 :(得分:1)

点击UIScrollView用于查看是否应该滚动。

您应该catch the single tap on the UIScrollView本身并将其传递给周围的UICollectionViewCell

答案 3 :(得分:0)

在您的超级视图中添加点击手势

override func viewDidLoad() {
        super.viewDidLoad()
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapView(gesture:)))
        view.addGestureRecognizer(tapGesture)
    }

@objc func didTapView(gesture: UITapGestureRecognizer) {
    view.endEditing(true)
    let touchLocation:CGPoint = gesture.location(ofTouch: 0, in: self.collectionView)
    let indexPath = self.collectionView.indexPathForItem(at: touchLocation)
    if indexPath != nil {
        let cell = self.collectionView.cellForItem(at: indexPath!)
        if (cell?.isSelected)! {
            //PREFORM DESELECT
        } else {
            //PREFORM SELECT HERE
        }
    }
}