平移手势使视图在拖动时从手指跳开

Posted

技术标签:

【中文标题】平移手势使视图在拖动时从手指跳开【英文标题】:Pan Gesture making view jump away from finger on drag 【发布时间】:2020-04-10 17:11:17 【问题描述】:

我在尝试使用平移手势识别器拖动视图时遇到问题。该视图是一个collectionViewCell,并且拖动代码正在工作,除非当拖动开始时,视图会向上和向左跳跃。我的代码如下。

在collectionViewCell中:

override func awakeFromNib() 
    super.awakeFromNib()
    let panRecognizer = UIPanGestureRecognizer(target:self, action:#selector(detectPan))
    self.gestureRecognizers = [panRecognizer]


var firstLocation = CGPoint(x: 0, y: 0)
    var lastLocation = CGPoint(x: 0, y: 0)
    @objc func detectPan(_ recognizer:UIPanGestureRecognizer) 
        switch recognizer.state 
        case .began:
            firstLocation = recognizer.translation(in: self.superview)
            lastLocation = recognizer.translation(in: self.superview)
        case .changed:
            let translation  = recognizer.translation(in: self.superview)
            self.center = CGPoint(x: lastLocation.x + translation.x, y: lastLocation.y + translation.y)
        default:
            UIView.animate(withDuration: 0.1) 
                self.center = self.firstLocation
            
        
    

第一张是拖动开始前的画面,第二张是向上拖动时的画面。

【问题讨论】:

我相信您的 .changed 案例不应该使用 self.center。 @xTwisteDx 我应该改用什么? 其实就是用翻译而不是最后一个位置+翻译。试试看.. 抱歉,没有 XCode atm,所以我无法测试。我认为实际上可能发生的是您正在修改设置的最后位置,然后添加翻译。注意视图向上和向左。这表明它在计算某些东西。 @xTwisteDx 啊!我想到了。你的第一个猜测是正确的,我应该更新 frame.origin.y 和 frame.origin.x 而不是中心。谢谢! 【参考方案1】:

您正在使用self.center 而不是使用self.frame.origin.xself.frame.origin.y,然后您将设置翻译并将其添加到lastLocation。

实际上发生的事情是您的视图正在计算从视图中心更改的位置,就好像您完全从该位置拖动然后平移 + lastLocation。我敢肯定,只要阅读您就知道这个问题。

修复很简单。

self.frame.origin.x = translation.x
self.frame.origin.y = translation.y

不同之处在于起始计算与翻译。 Origin 将根据触摸事件开始的位置获取 x/y 位置。而.center 总是从中心开始。

【讨论】:

以上是关于平移手势使视图在拖动时从手指跳开的主要内容,如果未能解决你的问题,请参考以下文章

代码中的假平移手势

如果视图注册平移手势,则捏合手势不起作用

使用平移手势,单次触摸后忽略触摸?

使用平移手势平滑地更改动画约束

按下按钮(子视图)时不要在超级视图上处理平移手势

带有其他手势的 ScrollView 中的 2 个手指平移 - iOS SDK