I am trying to animate a custom button using Facebooks POP framework. The animation does not happen until the request is done using Alamofire.
What I want to do is make the request and during the waiting process animate the button.
The code below visually works, but it does the request after the animation finishes.
func animate(tappedView:UIView){
let rotation = POPBasicAnimation(propertyNamed: kPOPLayerRotationX)
rotation.duration = 2.0
rotation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
tappedView.layer.anchorPoint = CGPointMake(0.5, 0.5)
rotation.toValue = 3*M_PI
let scaleUp = POPBasicAnimation(propertyNamed: kPOPLayerSize)
scaleUp.duration = 0.5
scaleUp.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
tappedView.layer.anchorPoint = CGPointMake(0.5, 0.5)
let size = CGSizeMake(tappedView.frame.size.width ,tappedView.frame.size.height)
let scaledSize = CGSizeMake(size.width * 1.5, size.height * 1.5)
scaleUp.toValue = NSValue(CGSize: scaledSize)
let scaleDown = POPSpringAnimation(propertyNamed: kPOPLayerSize)
scaleDown.beginTime = CACurrentMediaTime() + 0.5
scaleDown.toValue = NSValue(CGSize: size)
scaleDown.springSpeed = 4
scaleDown.springBounciness = 8
scaleDown.completionBlock = { (anim:POPAnimation!, finished:Bool) -> Void in
let requestURL = self.prepare4SQrequest(withLocation: self.currentLocation)
let request = Alamofire.request(.GET, requestURL)
request.responseJSON{ response in
HANDLE REQUEST RESPONSE LOGIC
}
tappedView.layer.pop_addAnimation(rotation, forKey: "popRotationX")
tappedView.layer.pop_addAnimation(scaleUp, forKey: "popScaleUp")
tappedView.layer.pop_addAnimation(scaleDown, forKey: "popScaleD")
}
I tried to make use of Alamofire's request.progress but it did not work. In this version the animation starts when the request logic finishes.
func animate(tappedView:UIView){
let rotation = POPBasicAnimation(propertyNamed: kPOPLayerRotationX)
rotation.duration = 2.0
rotation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
tappedView.layer.anchorPoint = CGPointMake(0.5, 0.5)
rotation.toValue = 3*M_PI
let scaleUp = POPBasicAnimation(propertyNamed: kPOPLayerSize)
scaleUp.duration = 0.5
scaleUp.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
tappedView.layer.anchorPoint = CGPointMake(0.5, 0.5)
let size = CGSizeMake(tappedView.frame.size.width ,tappedView.frame.size.height)
let scaledSize = CGSizeMake(size.width * 1.5, size.height * 1.5)
scaleUp.toValue = NSValue(CGSize: scaledSize)
let scaleDown = POPSpringAnimation(propertyNamed: kPOPLayerSize)
scaleDown.beginTime = CACurrentMediaTime() + 0.5
scaleDown.toValue = NSValue(CGSize: size)
scaleDown.springSpeed = 4
scaleDown.springBounciness = 8
tappedView.layer.pop_addAnimation(rotation, forKey: "popRotationX")
tappedView.layer.pop_addAnimation(scaleUp, forKey: "popScaleUp")
tappedView.layer.pop_addAnimation(scaleDown, forKey: "popScaleD")
}
func buttonTapped(gesture:UIGestureRecognizer){
let tappedView:UIView = gesture.view!
switch (tappedView.tag)
{
case 1:
let requestURL = prepare4SQrequest(withLocation: currentLocation)
let request = Alamofire.request(.GET, requestURL)
request.progress({bytesRead, totalBytesRead, totalBytesExpectedToRead in
dispatch_async(dispatch_get_main_queue()) {
print("Total bytes to read : \(totalBytesExpectedToRead)")
print("Total bytes read \(totalBytesRead)")
print("Bytes read \(bytesRead)")
self.animate(tappedView)
}
} )
request.responseJSON{ response in
HANDLE REQUEST RESPONSE LOGIC
}
break
}
Any help would be appricieted.
Thank you
Your buttonTapped function should look like this
func buttonTapped(gesture:UIGestureRecognizer) {
// 1 do your setup and switch case
// 2 first ask alamofire to send request
Alamofire.request(.GET, requestURL).
responseJSON {
response in
// handle response here
stopAnimation()
}
// 3 call your animation
animate(tappedView)
}
Now if you put a breakpoint on animate(tappedView) and code that handles json response you will see that your debugger will stop at animate first, then after a while will stop at response code. Alamofire has multithreading logic built in so you ask it to fetch you something from network and then it executes code you passed in the closure to .response whenever it's ready.
Hope that helps!