我有UICollectionView
水平滚动以一次显示一个UICollectionViewCell
。每个UICollectionViewCell
都有一个垂直滚动UIScrollView
作为子视图,用于滚动单元格的内容。 UICollectionViewCell
覆盖的UIScrollView
内部只有90%左右 - 即单元格的外框未被覆盖。
事实证明,UICollectionViewCell
所涵盖的UIScrollView
部分会取消UICollectionView
委托didSelectItemAtIndexPath
。因此,当在UIScrollView
内进行简单点击时,此方法不被调用,而如果点击发生在单元格的外部,即UIScrollView
之外,则此方法是被调用。
有关如何实现可以调用didSelectItemAtIndexPath
方法的设置的任何建议,即使在UIScrollView
内进行点击也是如此?
答案 0 :(得分:32)
我发现最有效的方法是窃取panGestureRecognizer
,UIScrollView
公开,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
}
}
}