UICollectionViewCell与UIScrollView取消didSelectItemAtIndexPath

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UICollectionViewCell与UIScrollView取消didSelectItemAtIndexPath相关的知识,希望对你有一定的参考价值。

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

事实证明,UICollectionViewCell覆盖的UIScrollView部分UICollectionView代表didSelectItemAtIndexPath。因此,当在UIScrollView内发生简单抽头时,不调用该方法,而如果抽头发生在单元的外部,即在UIScrollView之外,则调用该方法。

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

答案

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

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

另一答案

我发现最有效的方法是窃取由panGestureRecognizer暴露的UIScrollView并在userInteraction上禁用scrollView。这样,您就可以获得scrollview的行为,但在集合视图上保持交互。在你的UICollectionViewCell子类上:

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

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

另一答案

这是一个UIScrollView子类方法,它维护单元格选择功能,并允许在scrollview内部和外部进行UIControl选择(按钮等)。

斯威夫特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)
  }

}

斯威夫特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)
    }
}

Objective-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
另一答案

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

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
        }
    }
} 

以上是关于UICollectionViewCell与UIScrollView取消didSelectItemAtIndexPath的主要内容,如果未能解决你的问题,请参考以下文章

如何与自定义 UICollectionViewCell 单元格交互

UICollectionViewCell 阴影与装饰视图不一致

如何使用自动布局将两个具有动态高度的 UILabel 与 UICollectionViewCell 的底部对齐

UICollectionViewCell 的动态高度以编程方式与约束?

如何设置动态宽度 UICollectionViewCell

UITableViewCell/UICollectionViewCell 的上下文