'Move an UIView in a limited area of the screen using pan gesture
In my application, there is an UIView which should be moved in y direction when user pans in y direction on the super view within the given boundaries.
This is how it should work
This is my code
@IBOutlet weak var uiview: UIView!
// self.view is the supper view of uiview
var uiviewLastCenterPosition = CGPoint(x: 0, y: 0)
var lastTranslation = CGPoint(x: 0, y: 0)
override func viewDidAppear(_ animated: Bool) {
self.uiviewLastCenterPosition = self.uiview.center
}
@IBAction func supperViewPan(_ sender: UIPanGestureRecognizer) {
switch sender.state {
case .began:
break
case .changed:
let uiviewTop = self.uiview.frame.origin.y
let uiviewBottom = self.uiview.frame.origin.y + self.uiview.frame.size.height
let velocity = sender.velocity(in: self.view)
if velocity.y > 0.0 { // down
if uiviewBottom < 600{
self.uiview.center.y = (self.uiviewLastCenterPosition.y) + sender.translation(in: self.view).y
self.lastTranslation = sender.translation(in: self.view)
}else{
sender.setTranslation(self.lastTranslation, in: self.view)
}
}else if velocity.y < 0.0 { // up
if uiviewTop > 100{
self.uiview.center.y = (self.uiviewLastCenterPosition.y) + sender.translation(in: self.view).y
self.lastTranslation = sender.translation(in: self.view)
}else{
sender.setTranslation(self.lastTranslation, in: self.view)
}
}
break
case .ended:
self.uiviewLastCenterPosition = self.uiview.center
break
default:
break
}
}
All works perfect when user pans slowly. But when user pans fast, uiview goes beyond the boundaries.
Can someone please help me on this. I want to move the view exactly inside those boundaries. Any help would be highly appreciated.
Solution 1:[1]
You should clip the position before changing the position of the view which is self.uiview.center.y in your case. Look for the changes in the code.
@IBAction func supperViewPan(_ sender: UIPanGestureRecognizer) {
switch sender.state {
case .changed:
let viewTop = self.slideView.frame.origin.y
let viewBottom = self.slideView.frame.origin.y + self.slideView.frame.size.height
let halfHeight = self.slideView.frame.height / 2 // here
let velocity = sender.velocity(in: self.view)
if velocity.y > 0.0 { // down
if viewBottom < 600 {
var displacedPosition = (self.uiviewLastCenterPosition.y) + sender.translation(in: self.view).y
// changes here
displacedPosition = displacedPosition > 600 - halfHeight ? 600 - halfHeight : displacedPosition
displacedPosition = displacedPosition < 100 + halfHeight ? 100 + halfHeight : displacedPosition
self.slideView.center.y = displacedPosition
self.lastTranslation = sender.translation(in: self.view)
} else {
sender.setTranslation(self.lastTranslation, in: self.view)
}
} else if velocity.y < 0.0 { // up
if viewTop > 100 {
var displacedPosition = (self.uiviewLastCenterPosition.y) + sender.translation(in: self.view).y
// changes here
displacedPosition = displacedPosition < 100 + halfHeight ? 100 + halfHeight : displacedPosition
displacedPosition = displacedPosition > 600 - halfHeight ? 600 - halfHeight : displacedPosition
self.slideView.center.y = displacedPosition
self.lastTranslation = sender.translation(in: self.view)
} else {
sender.setTranslation(self.lastTranslation, in: self.view)
}
}
break
case .ended:
self.uiviewLastCenterPosition = self.slideView.center
break
default:
break
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | rule_it_subir |



