Ответ 1
Нажмите на UIScrollView
, чтобы увидеть, нужно ли прокручивать.
Вы должны поймать единственное нажатие на UIScrollView и передать его окружающим UICollectionViewCell
.
У меня есть UICollectionView
, который горизонтально прокручивает, чтобы показывать один UICollectionViewCell
за раз. Каждый UICollectionViewCell
имеет вертикальную прокрутку UIScrollView
как подпункт для прокрутки содержимого ячейки. Это всего лишь 90% внутренней части UICollectionViewCell
, которая покрывается UIScrollView
, то есть внешний кадр ячейки не покрывается этим.
Оказывается, что часть UICollectionViewCell
, которая покрывается UIScrollView
, отменяет делегат UICollectionView
didSelectItemAtIndexPath
. Таким образом, когда простое нажатие происходит в UIScrollView
, этот метод не вызывается, тогда как если крана происходит во внешней части ячейки, то есть вне UIScrollView
, этот метод вызывается.
Любые предложения относительно того, как достичь настройки, где можно вызвать метод didSelectItemAtIndexPath
, даже если кратковременное нажатие происходит в UIScrollView
?
Нажмите на UIScrollView
, чтобы увидеть, нужно ли прокручивать.
Вы должны поймать единственное нажатие на UIScrollView и передать его окружающим UICollectionViewCell
.
Я обнаружил, что наиболее эффективным подходом является кража panGestureRecognizer, открытая UIScrollView и отключая userInteraction в scrollView. Таким образом, вы получаете поведение scrollview, но поддерживаете взаимодействие в представлении коллекции. В подклассе UICollectionViewCell:
self.scrollView.userInteractionEnabled = NO;
[self.contentView addGestureRecognizer:self.scrollView.panGestureRecognizer];
Это метод, который Apple рекомендует и демонстрирует в сессии WWDC 2014 235 (Advanced Scrollviews и Touch Handling Techniques)
Здесь применяется подкласс 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)
}
}
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