2016-10-04 60 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步之内,所以一定要确保你希望发生什么功能在一个水龙头在那里。