最近公司需要實(shí)現(xiàn)多個(gè)scrollView的聯(lián)動(dòng)處理气筋,遇到了滑動(dòng)手勢(shì)的沖突問(wèn)題,現(xiàn)將幾個(gè)關(guān)鍵點(diǎn)記錄
首先看下UIGestureRecognizerDelegate的代理方法
// called when the recognition of one of gestureRecognizer or otherGestureRecognizer would be blocked by the other
// return YES to allow both to recognize simultaneously. the default implementation returns NO (by default no two gestures can be recognized simultaneously)
//
// note: returning YES is guaranteed to allow simultaneous recognition. returning NO is not guaranteed to prevent simultaneous recognition, as the other gesture's delegate may return YES
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
是否支持多手勢(shì)觸發(fā)待诅,返回YES,則可以多個(gè)手勢(shì)一起觸發(fā)方法懊蒸,返回NO則為互斥
如果tableView中放置了一個(gè)collectionView,自定義tableView的子類(lèi)测秸,可在實(shí)現(xiàn)文件中如下設(shè)置
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if ([self checkIsNestContentScrollView:(UIScrollView *)gestureRecognizer.view] || [self checkIsNestContentScrollView:(UIScrollView *)otherGestureRecognizer.view]) {
//如果交互的是嵌套的contentScrollView,證明在左右滑動(dòng)系宜,就不允許同時(shí)響應(yīng)
return NO;
}
return [gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]];
}
- (BOOL)checkIsNestContentScrollView:(UIScrollView *)scrollView
{
for (GCGiftContentView *listView in self.pagerView.validListDict.allValues) {
if (listView.collectionView == scrollView) {
return YES;
}
}
return NO;
}
手勢(shì)滑動(dòng)屏幕需要獲取手指滑動(dòng)方向的解決方案
在scrollView的子類(lèi)中實(shí)現(xiàn)
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([gestureRecognizer isMemberOfClass:NSClassFromString(@"UIScrollViewPanGestureRecognizer")]) {
CGFloat velocityX = [(UIPanGestureRecognizer *)gestureRecognizer velocityInView:gestureRecognizer.view].x;
CGFloat velocityY = [(UIPanGestureRecognizer *)gestureRecognizer velocityInView:gestureRecognizer.view].y;
if (velocityX > 0) {
//x大于0就是往右滑
} else if (velocityX < 0) {
//x小于0就是往左滑
}
if (velocityY > 0) {
// y大于0就是手指從下往上滑
} else {
// y大于0就是手指從上往下滑
}
}
return YES;
}
其中 用于獲取手指在屏幕上的滑動(dòng)速度 單位是points/second
// velocity of the pan in points/second in the coordinate system of the specified view
- (CGPoint)velocityInView:(nullable UIView *)view;
以上方法只能在手勢(shì)剛開(kāi)始觸發(fā)時(shí)獲取即將滑動(dòng)的方向照激,如果手指貼著屏幕一直不松手,此時(shí)結(jié)束時(shí)會(huì)回調(diào)此代理
// called on finger up if the user dragged. decelerate is true if it will continue moving afterwards
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
decelerate == NO 手指松開(kāi)后UI不再滑動(dòng),此時(shí)不回調(diào) scrollViewDidEndDecelerating
decelerate == YES 手指松開(kāi)后UI慣性滑動(dòng)一段距離,滑動(dòng)結(jié)束回調(diào) scrollViewDidEndDecelerating