6

Tôi đang cố gắng thêm trình nhận dạng cử chỉ di chuyển vào chế độ xem có chứa chế độ xem cuộn, nhưng tôi đoán là tôi đã gặp sự cố với mức độ ưu tiên.Xung đột UIPanGestureRecognizer với scrollview

UIView toàn cầu của tôi có một UIPanGestureRecognizer thiết lập như thế này:

_bottomPanGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(bottomPanGestureDetected:)]; 
_bottomPanGestureRecognizer.minimumNumberOfTouches = 2; 
_bottomPanGestureRecognizer.maximumNumberOfTouches = 2; 
_bottomPanGestureRecognizer.delaysTouchesBegan = NO; 
_bottomPanGestureRecognizer.delaysTouchesEnded = NO; 

Tôi muốn nhận cử chỉ này để hiển thị một cái nhìn từ dưới lên với một số loại nhúm down-to-up.

Vấn đề là scrollview đang nhận ra cử chỉ di chuyển của riêng nó trước khi tôi.

Vì vậy, tôi cố gắng trì hoãn nó nhờ:

[_scrollView.panGestureRecognizer requireGestureRecognizerToFail:_bottomPanGestureRecognizer]; 

Và nó hoạt động, sự kiện scrollview là bắn sau hai ngón tay của tôi dưới lên trên nhận dạng, nhưng vấn đề bây giờ là khi tôi chỉ sử dụng một ngón tay để cuộn trong scrollview, cuộn hoạt động sau một sự chậm trễ nhỏ.

Tôi muốn không có sự chậm trễ cho sự kiện này, điều này có khả thi không? Bất kỳ ý tưởng nào được hoan nghênh!

Chúc mừng.

Cyril

+0

Bạn đã cố gắng đặt 'maximumNumberOfTouches' của' _scrollView.panGestureRecognizer' thành '1'? – kovpas

+0

Có nhưng kỳ lạ, có vẻ như điều kiện này bị bỏ qua. – cyrilPA

+1

Vâng, một tùy chọn khác là triển khai 'gestureRecognizerShouldBegin:' của 'UIGestureRecognizerDelegate' và kiểm tra số lần chạm ở đó. Vì vậy, nếu đó là hai lần chạm, 'return NO' – kovpas

Trả lời

7

Trong trường hợp chưa được giải quyết, tôi đã giải quyết được sự cố cho tôi.

Tôi đã thêm UIPanGestureRecognizer vào UIScrollView để phát hiện hai cử chỉ di chuyển ngón tay và hành vi UIScrollView mặc định (di chuyển đến mục nào đó) vẫn hoạt động.

Vì vậy, những gì tôi đã làm là thêm UIPanGestureReconizer đến UIScrollView:

UIPanGestureRecognizer *pangestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(displayReloadIndicator:)]; 
pangestureRecognizer.minimumNumberOfTouches = 2; 
pangestureRecognizer.delegate = self; 
[self.scrollView addGestureRecognizer:pangestureRecognizer]; 
[pangestureRecognizer release]; 

Sau này tôi thêm vào đoạn code:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { 

    return YES; 
} 

Sau này, tôi thực hiện bên nhận cử chỉ phương pháp hành động chảo.

- (void) displayReloadIndicator:(UIPanGestureRecognizer*) panGestureRecognizer { 

    UIGestureRecognizerState gestureRecognizerState = gestureRecognizer.state; 

    CGPoint translation = [gestureRecognizer translationInView:self.scv_bibgesamt]; 

    if (gestureRecognizerState == UIGestureRecognizerStateBegan) { 

     // create a UIView with all the Pull Refresh Headers and add to UIScrollView 
     // This is really much lines of code, but its simply creating a UIView (later you'll find a myRefreshHeaderView, which is my base view) and add UIElements e.g. UIActivityIndicatorView, a UILabel and a UIImageView on it 
     // In iOS 6 you will also have the possibility to add a UIRefreshControl to your UIScrollView 

    } 

    else if (gestureRecognizerState == UIGestureRecognizerStateEnded 
      || gestureRecognizerState == UIGestureRecognizerStateCancelled) { 

     if (translation.y >= _myRefreshHeaderView.frame.size.height + 12) { // _myRefreshHeaderView is my baseview 

     //so the UIScrollView has been dragged down with two fingers over a specific point and have been release now, so we can refresh the content on the UIScrollView 
     [self refreshContent]; 

     //animatly display the refresh view as the top content of the UIScrollView 
     [self.scrollView setContentOffset:CGPointMake(0, myRefreshHeaderView.frame.size.height) animated:YES]; 
    } 

    else { 

     //the UIScrollView has not been dragged over a specific point so don't do anything (just scroll back to origin) 
     [self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES]; 

     //remove the view (because it's no longer needed) 
     [_myRefreshHeaderView removeFromSuperview]; 
    } 
} 

UPDATE:

Trong trường hợp bạn có thể muốn tích hợp các swipe lại chức năng từ navigationcontroller của bạn, bạn cần tích hợp mã sau:

- (void) viewDidLoad { 

    [super viewDidLoad]; 


    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) { 

     self.navigationController.interactivePopGestureRecognizer.enabled = YES; 

     self.navigationController.interactivePopGestureRecognizer.delegate = nil; 
    } 

    //setup view controller 
} 

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { 

    if (gestureRecognizer == _panGestureRecognizer 
     && [self.navigationController.viewControllers count] > 1) { 

     CGPoint point = [touch locationInView:self.view.window]; 

     if (point.x < 20 
      || point.x > self.view.window.frame.size.width - 20) { 

      return NO; 
     } 
    } 

    return YES; 
} 
+0

Cảm ơn @NicTesla – channi

+0

Bạn được chào đón :) – NicTesla

1

Triển khai ủy quyền panRecognizer cho e nable đồng thời nhận ra UIScrollView UIGestureRecognizer

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
{ 
    if (_panRecognizer == gestureRecognizer) { 
     if ([otherGestureRecognizer.view isKindOfClass:UIScrollView.class]) { 
      UIScrollView *scrollView = (UIScrollView *)otherGestureRecognizer.view; 
      if (scrollView.contentOffset.x == 0) { 
       return YES; 
      } 
     } 
    } 

    return NO; 
}