UIPanGestureRecognizer 在滑动单元格以获得更多按钮时如何在用户滑动不到一半时使视图反弹

Posted

技术标签:

【中文标题】UIPanGestureRecognizer 在滑动单元格以获得更多按钮时如何在用户滑动不到一半时使视图反弹【英文标题】:UIPanGestureRecognizer when swipe cell for more buttons how to make view bounce back if user swipes less than halfway 【发布时间】:2018-08-08 12:21:22 【问题描述】:

我希望如果用户滑动不到按钮宽度的一半,那么它会弹回并且不显示任何按钮,但如果用户滑动超过按钮宽度的一半,那么单元格会弹回正确的位置。

这就是我目前所拥有的,它使左右滑动成为可能。

private func swipeBothButtonsBothPresent(gesture: UIPanGestureRecognizer) 
    let translation = gesture.translation(in: swipeAbleView)
    guard let gestureView = gesture.view else 
        return
    
    let center: CGPoint = CGPoint(x: gestureView.center.x + translation.x, y: gestureView.center.y)

    let velocity: CGPoint = gesture.velocity(in: swipeAbleView)
    if velocity.x > 0 
        //right
        if center.x < swipeAbleView.frame.width / 2 + leftButton.frame.size.width 
            swipeAbleView.center = center
         else 
            swipeAbleView.center = CGPoint(x: swipeAbleView.frame.width / 2 + leftButton.frame.size.width, y: swipeAbleView.center.y)
        
     else 
        //left
        if center.x > swipeAbleView.frame.width / 2 - rightButton.frame.size.width 
            swipeAbleView.center = center
         else if  isRightButtonThere 
            swipeAbleView.center = CGPoint(x: swipeAbleView.frame.width / 2 - rightButton.frame.size.width, y: swipeAbleView.center.y)
        
    
    gesture.setTranslation(CGPoint.zero, in: swipeAbleView)

【问题讨论】:

【参考方案1】:

您必须使用 UIPangesture 状态才能找出您所处的状态。 您可以使用开关来执行此操作并检查 .changed、.ended、.cancelled 状态。

private func swipteBothButtonsBothPresent(with gesture: UIPanGestureRecognizer) 
let translation = recognizer.translation(in: swipeAbleView)

// you can use the center point+velocity to compare to the gestureView center but there is another way as well directly access the translation.x
let center: CGPoint = CGPoint(x: gestureView.center.x + translation.x, y: gestureView.center.y)
let velocity: CGPoint = gesture.velocity(in: swipeAbleView)


// Pan gesture has state which you can access using the gesture you have passed
switch gesture.state 
case .changed:
    // Here you can directly check for translation.x
    /*
    if translation.x < 0 
        // Do you're calculations
      else 

     
    */
    // Your logic to show left or right button
    if velocity.x > 0 
        //right
        if center.x < swipeAbleView.frame.width / 2 + leftButton.frame.size.width 
            swipeAbleView.center = center
         else 
            swipeAbleView.center = CGPoint(x: swipeAbleView.frame.width / 2 + leftButton.frame.size.width, y: swipeAbleView.center.y)
        
     else 
        //left
        if center.x > swipeAbleView.frame.width / 2 - rightButton.frame.size.width 
            swipeAbleView.center = center
         else if  isRightButtonThere 
            swipeAbleView.center = CGPoint(x: swipeAbleView.frame.width / 2 - rightButton.frame.size.width, y: swipeAbleView.center.y)
        
    

    gesture.setTranslation(CGPoint.zero, in: swipeAbleView)

case .ended:
    // Check here if you have swiped more than buttons half width or lesss you can do it easily using the translation value you have
    // Check if user was swiping left or right you already has the velocity parameter or you can check translation.x to see if the value is negitive or positive (left or right)
    // I cast the translation.x to abs() so even if the value was negitive it will change it back to positive
    // do the check for left or right I have directly added the check for rightButton

    if abs(translation.x) > (rightButton.frame.size.width / 2) 
        // you have dragged more than half of the right button
        // even you can add spring animation to get the bounce effect
        UIView.animate(withDuration: 0.3) 
            // animate back to orignal place
        
    

case .cancelled:
    // Do the same dance for cancelled because there can be this state through some times reset add the same code from ended here
    // create a function move the code from .ended state to the function and call the function here
    //
    resetButtons(x: abs(translation.x))
default:
    // there are 3 more states but you can skip them .began, .failed, .possible
    break



func resetButtons(x: Int) 
    // Move the code from .ended state of the switch here

【讨论】:

这就是我想要的。这应该有效。谢谢 看看它是否有效,然后不要忘记将答案标记为正确答案祝你好运 我不会忘记的。只是需要一些时间来实现它。

以上是关于UIPanGestureRecognizer 在滑动单元格以获得更多按钮时如何在用户滑动不到一半时使视图反弹的主要内容,如果未能解决你的问题,请参考以下文章

如何使用步进滑块在滑块拇指上添加 UILabel?

歌曲不会在滑块拖动 iOS 上快进

在 wxPython 中,如何使用 sizers 在滑块下方左右对齐静态文本?

使用小部件测试在滑块中选择值

tvOS 手势识别器在滑出屏幕后停止工作

触摸按钮时无法在滑出菜单中推动视图控制器