I have been learning Swift 2.2 for several days. After finishing the official tutorial, I'm trying to make some functional samples. E.g. I am trying to make an avatar decorator.
@IBAction func moveAvatar(recognizer:UIPanGestureRecognizer) {
recognizer.maximumNumberOfTouches = 1
recognizer.minimumNumberOfTouches = 1
let debugOutOfBounds = false
let debugGestureRecognizer = false
let debugVelocity = true
if (debugGestureRecognizer) {
print("pan")
}
let translation = recognizer.translationInView(self.avatar)
let standardAvatarSize:CGFloat = Conf.Size.avatarRadius * 2
if (self.avatar.frame.width < standardAvatarSize) {
self.avatar.frame = CGRect(origin: self.avatar.frame.origin, size: CGSize(width: standardAvatarSize, height:standardAvatarSize))
}
if let view = recognizer.view {
switch recognizer.state {
case .Began:
if (debugVelocity) {
print("Began: velocity: \(recognizer.velocityInView(view)) translation: \(translation)")
}
self.panAvatarLastTranslation = translation
self.avatar.center = CGPoint(x: self.avatar.center.x + translation.x, y: self.avatar.center.y + translation.y)
case .Changed:
if (debugVelocity) {
print("Changed: velocity: \(recognizer.velocityInView(view)) translation: \(translation)")
}
if (translation != CGPoint(x: 0.0, y: 0.0)) {
self.panAvatarLastTranslation = translation
}
self.avatar.center = CGPoint(x: self.avatar.center.x + translation.x, y: self.avatar.center.y + translation.y)
case .Ended:
if (debugVelocity) {
print("Ended: velocity: \(recognizer.velocityInView(view)) translation: \(translation)")
}
let velocityDistance = sqrt(pow(recognizer.velocityInView(view).x, CGFloat(2)) + pow(recognizer.velocityInView(view).y, CGFloat(2)))
print(velocityDistance)
if (velocityDistance > 100) {
let inertiaDelay: NSTimeInterval = 0.5
let inertiaDistance : CGFloat = velocityDistance * CGFloat(inertiaDelay) * 0.02
let inertiaX:CGFloat = self.panAvatarLastTranslation.x * inertiaDistance
let inertiaY:CGFloat = self.panAvatarLastTranslation.y * inertiaDistance
//sqrt(pow(inertiaX, CGFloat(2)) + pow(inertiaY, CGFloat(2)))
//print("inertiaDelay: \(inertiaDelay)")
UIView.animateWithDuration(inertiaDelay, animations: {
self.avatar.center.x += inertiaX
self.avatar.center.y += inertiaY
})
}
default:
print("default")
}
let standardAvatarBound: [String:CGFloat] = [
"top": UIApplication.sharedApplication().statusBarFrame.height + UIScreen.mainScreen().bounds.width / 2 - Conf.Size.avatarRadius,
"right": UIScreen.mainScreen().bounds.width / 2 + Conf.Size.avatarRadius,
"bottom": UIApplication.sharedApplication().statusBarFrame.height + UIScreen.mainScreen().bounds.width / 2 + Conf.Size.avatarRadius,
"left": UIScreen.mainScreen().bounds.width / 2 - Conf.Size.avatarRadius
]
let avatarBound: [String:CGFloat] = [
"top": self.avatar.center.y - self.avatar.frame.height / 2,
"right": self.avatar.frame.width / 2 + self.avatar.center.x,
"bottom": self.avatar.center.y + self.avatar.frame.height / 2,
"left": self.avatar.center.x - self.avatar.frame.width / 2
]
if (self.panAvatarLastTranslation.x < 0 && avatarBound["right"] < standardAvatarBound["right"]) {
UIView.animateWithDuration(0.5, animations: {
self.avatar.center.x += (standardAvatarBound["right"]! - avatarBound["right"]!)
})
if (debugOutOfBounds) {
print("Out of right bound")
}
}
if(self.panAvatarLastTranslation.x > 0 && avatarBound["left"] > standardAvatarBound["left"]) {
UIView.animateWithDuration(0.5, animations: {
self.avatar.center.x -= (avatarBound["left"]! - standardAvatarBound["left"]!)
})
if (debugOutOfBounds) {
print("Out of left bound")
}
}
if(self.panAvatarLastTranslation.y > 0 && avatarBound["top"] > standardAvatarBound["top"]) {
UIView.animateWithDuration(0.5, animations: {
self.avatar.center.y -= (avatarBound["top"]! - standardAvatarBound["top"]!)
})
if (debugOutOfBounds) {
print("Out of top bound")
}
}
if(self.panAvatarLastTranslation.y < 0 && avatarBound["bottom"] < standardAvatarBound["bottom"]) {
UIView.animateWithDuration(0.5, animations: {
self.avatar.center.y += (standardAvatarBound["bottom"]! - avatarBound["bottom"]!)
})
if (debugOutOfBounds) {
print("Out of bottom bound")
}
}
}
recognizer.setTranslation(CGPointZero, inView: view)
}
Okay, as you can see that I'm handling dragging inertia in the ".Ended" state of the pan gesture recognizer. It works well, but not smooth. What can I do to make a smooth panning inertia?
Here is the source code: https://github.com/AarioAi/NotesOpen/tree/master/Swift
Try using different method for animating. Heck out this tutorial
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With