i trying animate view based on uipangesturerecognizer
. in beginning, view should move user's finger on x-axis , rotate. after view has moved set amount, should slide off screen. imagine card being slid off deck.
for final sliding, using animatewithkeyframeanimation
. while testing put in function , hooked uibutton
. view move finger , stop once hit maximum moved limit. tap button mentioned above , view seamlessly slide off of screen.
then added "sliding off screen" animation code inside gesture handler function. , view flashes off screen, slides was, , animates off. tried calling function inside gesture handler , got same result.
can please me understand going on here? don't understand why calling code in 1 place produce such vastly different results. also, how fix it?
code
i moving anchorpoint
without moving view rotation point purposes.
class viewcontroller: uiviewcontroller { override func viewdidload() { super.viewdidload() movingview.layer.anchorpoint = cgpoint(x: 0.5, y: 0.9) } override func viewdidlayoutsubviews() { movingview.frame = cgrect(origin: cgpointzero, size: movingview.frame.size) }
this function gesturerecognizer
hooked to.
@ibaction func handlepan(recognizer: uipangesturerecognizer) { let screenwidth = screenbounds.width let percentmovedbeforeremoving = cgfloat(0.8) let totalmovedbeforeremoving = (screenwidth / 2) * percentmovedbeforeremoving let translation = recognizer.translationinview(view) if abs(totalmoved) >= totalmovedbeforeremoving { finishanimatingoffscreen(nil) //i tried putting code in here same strange results } else { // moves view finger in first place let percenttorotate = translation.x / (screenbounds.width / 2) totalrotated += cgfloat(percenttorotate * totalrotation) totalmoved += translation.x movingview.transform = cgaffinetransformmakerotation(totalrotated) movingview.center = cgpoint(x: (movingview.center.x + translation.x), y: movingview.center.y) } recognizer.settranslation(cgpointzero, inview: view) }
and function animates view rest of way off of screen.
@ibaction func finishanimatingoffscreen(sender: uibutton?) { print(movingview.frame) let totalrotationtransform = cgaffinetransformmakerotation(-cgfloat(m_pi / 12)) let finalviewframe = cgrectapplyaffinetransform(self.movingview.frame, totalrotationtransform) let xtomove: cgfloat = -(finalviewframe.width / 2 + self.movingview.center.x) uiview.animatekeyframeswithduration(5, delay: 0, options: [.calculationmodecubic], animations: { uiview.addkeyframewithrelativestarttime(0, relativeduration: 0.01, animations: { self.movingview.transform = cgaffinetransformmakerotation(self.totalrotated) self.movingview.center = cgpoint(x: (self.movingview.center.x), y: self.movingview.center.y) }) uiview.addkeyframewithrelativestarttime(0.01, relativeduration: 4.99, animations :{ let moveoffscreentransform = cgaffinetransformmaketranslation(xtomove, 0) let rotatetransform = cgaffinetransformmakerotation(-cgfloat(m_pi / 12)) self.movingview.transform = cgaffinetransformconcat(moveoffscreentransform, rotatetransform) }) }, completion: nil) } }
you moving view while it's being animated , messing animation.
you should disable pangesture while it's animating. example:
if abs(totalmoved) >= totalmovedbeforeremoving { recognizer.enabled = false finishanimatingoffscreen(nil) }
then @ end of finishanimatingoffscreen
say:
uiview.addkeyframewithrelativestarttime(0.01, relativeduration: 4.99, animations :{ let moveoffscreentransform = cgaffinetransformmaketranslation(xtomove, 0) let rotatetransform = cgaffinetransformmakerotation(-cgfloat(m_pi / 12)) self.movingview.transform = cgaffinetransformconcat(moveoffscreentransform, rotatetransform) }) }, completion:{ _ in self.pangesture.enabled = true })
i rule of thump update constraints rather frames when using auto layout though.