2016-10-04 84 views
0

我有一個UICollectionView,其中我已啓用項目的拖動。但是我也需要能夠檢測物品上的水龍頭。檢測水龍頭,但也拖動單元格

爲了檢測竊聽,我簡單地使用didSelectItemAtIndex

爲了檢測拖動,我添加了一個UILongPressGestureRecognizer到的CollectionView和從長按的位置找到單元:

longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(OrganizeWidgetsViewController.handleLongGesture(gesture:))) 
    longPressGesture.numberOfTapsRequired = 0 
    longPressGesture.minimumPressDuration = 0.01 
    widgetCollectionView.addGestureRecognizer(longPressGesture) 

問題我需要在用戶的手指觸摸屏幕並開始拖動時立即進行拖動。但是,我的longPressGestrue(0.01)的minimumPressPressDuration較低,無法檢測到Tap。

我的longPressGesture被檢測到,但敲擊通常不會。有沒有更好的方法來檢測攻絲和拖動細胞?

+0

增加最小持續時間,我作爲用戶總是期望拖動將發生,如果我按一個更長的時間和通常的水龍頭需要。 –

回答

1

我解決了這個問題,將longPressGesture.minimumPressDuration設置爲0,然後檢查用戶離開水龍頭的距離有多遠。

如果拖拽距離原點的最大距離大於一定量,我將其識別爲拖拽。否則,這是一個水龍頭。

步驟1:貫徹longPressGesture到的CollectionView:

longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(MyViewController.handleLongGesture(gesture:))) 
    longPressGesture.numberOfTapsRequired = 0 
    longPressGesture.minimumPressDuration = 0 
    myCollectionView.addGestureRecognizer(longPressGesture) 

步驟2:聲明的類兩個變量來計算拖動

var startPoint: CGPoint? 
var maxDistance: CGFloat? 

步驟的距離3編寫一個函數,該函數將計算距離拖曳原點的總距離(我們將在下一步)

func calculateDistance(from: CGPoint, to: CGPoint) -> CGFloat { 
     return sqrt(pow((from.x - to.x),2) + pow((from.y - to.y),2)) 
} 

第4步:處理拖入

func handleLongGesture(gesture: UILongPressGestureRecognizer) { 
    switch(gesture.state) { 
    case UIGestureRecognizerState.began: 
     startPoint = gesture.location(in: myCollectionView) 
     maxDistance = 0 
     guard let selectedIndexPath = myCollectionView.indexPathForItem(at: gesture.location(in: myCollectionView)) else { 
      break 
     } 
     myCollectionView.beginInteractiveMovementForItem(at: selectedIndexPath) 

    case UIGestureRecognizerState.changed: 
     maxDistance = max(maxDistance!, calculateDistance(from: startPoint!, to: gesture.location(in: myCollectionView))) 
     myCollectionView.updateInteractiveMovementTargetPosition(gesture.location(in: gesture.view!)) 
    case UIGestureRecognizerState.ended: 
     if maxDistance! < CGFloat(10) { 
      if let selectedIndexPath = myCollectionView.indexPathForItem(at: gesture.location(in: myCollectionView)) { 
       collectionView(myCollectionView, didSelectItemAt: selectedIndexPath) 
      } 
     } 
     myCollectionView.endInteractiveMovement() 

    default: 
     myCollectionView.cancelInteractiveMovement() 
    } 
} 

注: 我們呼籲didSelectItemAtIndex我們的CollectionView從第4步之內,所以一定要確保你希望發生什麼功能在一個水龍頭在那裏。