2014-05-21 13 views
7

Tôi có một số UICollectionView triển khai bố cục dựa trên lưới tùy chỉnh UICollectionViewCells. Để cho phép các ô phản hồi việc kéo, tôi cá nhân thêm một UIPanGestureRecognizer vào mỗi ô.Làm thế nào để chuyển cử chỉ pan sang UICollectionVIew từ UICollectionViewCell?

UICollectionView Vẫn cuộn (ngang) khi tôi chạm xuống và trượt sang trái/phải bắt đầu từ điểm giữa các ô, nhưng miễn là trình nhận dạng cử chỉ được thêm vào ô, có vẻ như CollectionView từ chối di chuyển khi tôi bắt đầu thao tác vuốt của tôi trong một ô.

Ngay bây giờ, tôi tách riêng các kéo ngang/phải ngang từ kéo lên/xuống theo chiều dọc, vì vậy không nên có bất kỳ xung đột nào giữa các ô kéo ra (trượt dọc) và cuộn CollectionView (vuốt ngang). Trong trường hợp này, làm thế nào tôi có thể vượt qua thao tác vuốt đến chế độ xem bộ sưu tập/cuộn để nó biết cuộn như bình thường? Nó thực sự gây phiền nhiễu khi phải bắt đầu trên ranh giới hoặc khoảng cách giữa các tế bào.

Khi tôi xóa cử chỉ di chuyển khỏi ô, việc cuộn hoạt động như bình thường bất kể tôi bắt đầu vuốt trên ô hay giữa các ô.

EDIT: mong muốn hành vi cử chỉ chảo đăng tải dưới đây là mã hiện

// Handle pans by detecting swipes: 
-(void) handlePan:(UIPanGestureRecognizer*)recognizer 
{ 
    // Calculate touch location 
    CGPoint touchXY = [recognizer locationInView:masterWindowView]; 

    // Handle touch 
    if (recognizer.state == UIGestureRecognizerStateBegan) 
    { 
     gestureWasHandled = NO; 
     pointCount = 1; 
     startPoint = touchXY; 
    } 

    if (recognizer.state == UIGestureRecognizerStateChanged) 
    { 
     ++pointCount; 

     // Calculate whether a swipe has occurred 
     float dX = deltaX(touchXY, startPoint); 
     float dY = deltaY(touchXY, startPoint); 

     BOOL finished = YES; 
     if ((dX > kSwipeDragMin) && (ABS(dY) < kDragLimitMax)) { 
      touchType = TouchSwipeLeft; 
      NSLog(@"LEFT swipe detected"); 
      [recognizer requireGestureRecognizerToFail:recognizer]; 
      //[masterScrollView handlePan] 
     } 
     else if ((dX < -kSwipeDragMin) && (ABS(dY) < kDragLimitMax)) { 
      touchType = TouchSwipeRight; 
      NSLog(@"RIGHT swipe detected"); 
      [recognizer requireGestureRecognizerToFail:recognizer]; 
     } 
     else if ((dY > kSwipeDragMin) && (ABS(dX) < kDragLimitMax)) { 
      touchType = TouchSwipeUp; 
      NSLog(@"UP swipe detected"); 
     } 
     else if ((dY < -kSwipeDragMin) && (ABS(dX) < kDragLimitMax)) { 
      touchType = TouchSwipeDown; 
      NSLog(@"DOWN swipe detected"); 
     } 
     else 
      finished = NO; 

     // If unhandled and downward, produce a new draggable view 
     if (!gestureWasHandled && finished && (touchType == TouchSwipeDown)) 
     { 

      [self.delegate cellBeingDragged:self]; 
      dragView.center = touchXY; 
      dragView.hidden = NO; 
      dragView.backgroundColor = [UIColor clearColor]; 


      masterScrollView.scrollEnabled = NO; // prevent user from scrolling during 
      gestureWasHandled = YES; 
     } 
     else if (gestureWasHandled) 
     { 
      // allow continued dragging after detection 
      dragView.center = touchXY; 
     } 
    } 

    if (recognizer.state == UIGestureRecognizerStateEnded) 
    { 
     // ensure that scroll view returns to scrollable 
     if (gestureWasHandled) { 
      [self.delegate cell:self dragEndedAt:touchXY]; 
     } 
    } 
} 

// Allow simultaneous recognition 
-(BOOL) gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer 
{ 
    return YES; 
} 

Mã này hoạt động khi trao cho mỗi tế bào riêng lẻ. Nó không hoạt động khi được gắn vào UICollectionView như là trình nhận dạng cử chỉ của nó, và thực tế nó dừng tất cả việc di chuyển.

+0

Mã đó ở đâu? Mã nhận dạng cử chỉ của bạn phải nằm trong bộ điều khiển chế độ xem của bạn. Phương thức 'gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer' cho phép hai cử chỉ khác nhau chạy đồng thời, ** không ** một cử chỉ được nhận dạng bởi hai khung nhìn khác nhau - đó là những gì bạn định? – KerrM

Trả lời

8

Thay vì gắn một UIPanGestureRecognizer để mỗi tế bào (mà sẽ làm giảm hiệu suất) thêm một UIPanGestureRecognizer đến UICollectionView và khi cử chỉ chảo xảy ra sử dụng locationInView để có được những điểm nào trong UICollectionView nơi chảo bắt đầu, và sau đó indexPathForItemAtPoint đó sẽ trở lại bạn đường dẫn chỉ mục cho ô bạn nên tạo hiệu ứng động.

Bằng cách này, bạn sẽ chỉ có một bộ nhận dạng cử chỉ (tốt!) Cho toàn bộ bộ sưu tập của bạn trong khi vẫn duy trì sự kiểm soát trong bộ điều khiển xem của bạn (như bạn muốn)

Sử dụng giải pháp này, trong bộ điều khiển chế độ xem của bạn, bạn sẽ thực hiện gestureRecognizer:shouldReceiveTouch:, lấy cử chỉ đã cho. Hãy chắc chắn đó là số UIPanGestureRecognizer của bạn và sử dụng phương pháp translationInView: của nó để tìm hiểu xem bản dịch có trên trục X hoặc Y hay không. Sử dụng thông tin đó để quyết định xem bạn có muốn trả lại CÓ hoặc KHÔNG. Ví dụ:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { 
    if([gestureRecognizer isEqual:myTapGesture]) { 
    CGPoint point = [gestureRecognizer translationInView:self.collectionView]; 
    if(point.x != 0) { //adjust this condition if you want some leniency on the X axis 
     //The translation was on the X axis, i.e. right/left, 
     //so this gesture recognizer shouldn't do anything about it 
     return NO; 
    } 
    } 
    return YES; 
} 
+0

Tôi đã thử tính năng này và UICollectionView ngừng cuộn hoàn toàn, ngoài việc không phát hiện các lần vuốt của tôi trên từng ô riêng lẻ. Tôi đã quay trở lại cách tiếp cận ban đầu của mình, ít nhất là cho phép tôi cuộn bằng cách chạm vào giữa các biểu tượng! – Cindeselia

+0

Hiển thị một số mã về những gì bạn đã thử và cách bạn triển khai giải pháp mà tôi đã đề xuất. Tôi nên thêm rằng bạn nên đã thực hiện giao thức 'UIGestureRecognizerDelegate' (cụ thể là' gestureRecognizer: shouldReceiveTouch: ') để quyết định xem một ô có nhận được cử chỉ hay không. – KerrM

+0

Trên thực tế, có, nó sẽ giúp rất nhiều để biết các chức năng đại biểu mà tôi phải ghi đè lên - và liệu có ghi đè lên chúng trên ViewController, UICollectionView, UICollectionViewFlowLayout hoặc UICollectionViewCell hay không. Tôi đã ghi đè lên handleGestureSimultaneously để luôn trả về YES. Sẽ đăng mã tại đây trong giây lát – Cindeselia

5

Có -shouldReceiveTouch: và -shouldRecognizeSimultaneouslyWithGestureRecognizer: trở YES, thêm UIGestureRecognizerDelegate dạng danh sách giao thức lớp học của bạn và ủy cử chỉ của bạn uỷ thác cho tự trong -viewDidLoad.

yourGesture.delegate = self; 
+0

@Cindeselia là câu trả lời mất khi được chấp nhận? –

+0

Câu trả lời đơn giản nhất mà tôi có thể tìm thấy trên SO. Cảm ơn người đàn ông! –

Các vấn đề liên quan