UIView 沿 Y 轴平移手势

Posted

技术标签:

【中文标题】UIView 沿 Y 轴平移手势【英文标题】:UIView pan gesture along Y axis 【发布时间】:2018-05-22 08:09:43 【问题描述】:

我有一个 UIView,我可以沿 Y 轴拖放它,它可以捕捉到 2 个位置中的 1 个。问题是我必须将它拖过 Y 轴上的某个点才能使其卡入到位。当您尝试快速滑动但没有超过特定的 Y 轴时,这会感觉很笨拙,它会弹回起始位置。

我想要的目标是让它根据用户在释放 UIView 时滑动的方向将其卡入 2 个位置中的 1 个。

@objc func panGesture(recognizer: UIPanGestureRecognizer) 
    let window = UIApplication.shared.keyWindow
    let translation = recognizer.translation(in: self)
    let currentY = self.frame.minY
    let partialY = (window?.frame.height)!-194
    let halfWayPoint = ((window?.frame.height)!/2)-40

    self.frame = CGRect(x: 0, y: currentY + translation.y, width: self.frame.width, height: self.frame.height)
    recognizer.setTranslation(CGPoint.zero, in: self)

    switch recognizer.state 

    case .changed:

        // Prevent scrolling up past y:0
        if currentY <= 0
        
            self.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
        

    case .ended:

        // Snap to 80 (y) (expanded)
        if currentY < 80 || currentY > 80 && currentY < halfWayPoint
        
            UIView.animate(withDuration:0.62, delay: 0.0, usingSpringWithDamping: 0.62, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations:
                
                    recognizer.view!.frame = CGRect(x: 0, y: 80, width: self.frame.width, height: self.frame.height)
            , completion:  (true) in
                self.isExpanded = true
            )
        

        // Snap back to partial (y) (original position)
        if currentY > partialY || currentY < partialY && currentY > halfWayPoint
        
            UIView.animate(withDuration:0.62, delay: 0.0, usingSpringWithDamping: 0.62, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations:
                
                    recognizer.view!.frame = CGRect(x: 0, y: partialY, width: self.frame.width, height: self.frame.height)
            , completion: (true) in
                self.isExpanded = false
            )
        

    default:
        print("Default")
    

如您所见,halfWayPoint 是视图必须位于上方或下方才能确定其捕捉位置的点。这是无效的,我想根据用户拖动视图的方向(向上或向下)来执行此操作。

【问题讨论】:

【参考方案1】:

我建议你使用 UIPanGestureRecognizers velicoty(in:) 方法。 它为您提供滑动速度(以每秒点数为单位)。

如果你只是将它添加到currentY(最好用一些常数缩放),你会得到那种轻飘飘的感觉,并且手势会感觉更自然。

只需更换 let currentY = self.frame.minYlet currentY = self.frame.minY + recognizer.velocity(in: nil).y * someConstantsomeConstant 一起玩,直到你得到你想要的感觉。

【讨论】:

谢谢,以 0.01 作为常数,设法让它足够接近。需要多玩一点,但效果很好

以上是关于UIView 沿 Y 轴平移手势的主要内容,如果未能解决你的问题,请参考以下文章

使用平移手势在屏幕的有限区域中移动 UIView

UIView/Drawer 使用平移/滑动手势

无法在其父视图之外平移手势较小的 UIView

设置平移手势的界限

基于平移手势翻译的滚动scrollview

与平移手势闪烁视图相关的问题