I'm trying to let a UIView slide between 2 points on slide touch. I've tried using UIPanGestureRecognizer. The sliding is fine but when the view arrive at the limit point, there's a bumpy jump. It's not smooth. This is my gesture function:
func wasDragged(gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == UIGestureRecognizerState.began || gestureRecognizer.state == UIGestureRecognizerState.changed {
let translation = gestureRecognizer.translation(in: self.view)
print(gestureRecognizer.view!.center.x)
if(gestureRecognizer.view!.center.x <= self.view.frame.width) && (gestureRecognizer.view!.center.x >= self.view.frame.width - 100) {
gestureRecognizer.view!.center = CGPoint(x: gestureRecognizer.view!.center.x + translation.x, y: gestureRecognizer.view!.center.y)
}else if (gestureRecognizer.view!.center.x > self.view.frame.width){
gestureRecognizer.view!.center = CGPoint(x: self.view.frame.width, y: gestureRecognizer.view!.center.y)
}else if (gestureRecognizer.view!.center.x < self.view.frame.width - 100){
gestureRecognizer.view!.center = CGPoint(x: self.view.frame.width - 100, y: gestureRecognizer.view!.center.y)
}
gestureRecognizer.setTranslation(CGPoint(x: 0,y: 0), in: self.view)
}
}
Any help? Thanks.
Your problem is that you are looking at where the view is now, and not where it will be after the current move has been applied.
I fixed your code by introducing newx
which shows where the view is trying to move to. That is the value that you want to constrain.
@IBAction func wasDragged(gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
let translation = gestureRecognizer.translation(in: self.view)
print(gestureRecognizer.view!.center.x)
let newx = gestureRecognizer.view!.center.x + translation.x
if(newx <= self.view.frame.width) && (newx >= self.view.frame.width - 100) {
gestureRecognizer.view!.center = CGPoint(x: newx, y: gestureRecognizer.view!.center.y)
}else if (newx > self.view.frame.width){
gestureRecognizer.view!.center = CGPoint(x: self.view.frame.width, y: gestureRecognizer.view!.center.y)
}else if (newx < self.view.frame.width - 100){
gestureRecognizer.view!.center = CGPoint(x: self.view.frame.width - 100, y: gestureRecognizer.view!.center.y)
}
gestureRecognizer.setTranslation(CGPoint(x: 0,y: 0), in: self.view)
}
}
You might also want to consider a change to your final setTranslation
call. If the user tries to drag the view left when it is already at its left limit and then (without lifting their finger) changes direction and moves to the right, your code will move the view right even though their finger is no longer over the view.
With the change below, the view will not move to the right until the user's finger gets back to the original touch point:
gestureRecognizer.setTranslation(CGPoint(x: newx - gestureRecognizer.view!.center.x ,y: 0), in: self.view)
Try it and see which you prefer.