Laap
Laap

Reputation: 71

Overlapping UIView animation canceling the first completion block

I have two buttons to move views. When I press the first button it will move a view and the other will move it back.

The first animation has a completion block, but I want to prevent this block from executing when the user moves the view back before the completion is done.

I have tried using solutions given to other questions similar to this but it doesn't seem to stop the execution of the first completion block.

@IBOutlet func moveView(sender: AnyObject) {
    UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .AllowUserInteraction, animations: { /* animation */ }) { _ in /* completion */ }
}

@IBOutlet func moveBack(sender: AnyObject) {
    UIView.animateWithDuration(0.0, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .BeginFromCurrentState, animations: { /* animation */ }) { _ in /* completion */ }
}

I also tried removing all the animations and the completion parameter will be false but the animation will just jump to the end and animate from there.

Any ideas is very much appreciated.

Upvotes: 1

Views: 695

Answers (2)

Laap
Laap

Reputation: 71

After searching for a while I think I've found a solution. To get the completion block to return false, the animation has to be removed. But by doing so, the animation will jump to the "end state" so to prevent this I used:

object.layer.frame = object.layer.presentationLayer()!.frame
object.layer.removeAllAnimations()

From here I can start my new animation (moving back the object) without worrying about the completion block of the first animation. Information

I'm not sure if this is how it should be done or if there's a better way of doing this.

Upvotes: 0

TechBee
TechBee

Reputation: 1941

You may use boolean flag to achieve the desired functionality like as under:

var moveViewFlag = false var moveBackFlag = false

@IBOutlet func moveView(sender: AnyObject) {
UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .AllowUserInteraction, animations: { /* animation */ }) { _ in /* completion */ 

        //inside completion block make the moveBackFlag to true
        moveBackFlag = true
   }
}



@IBOutlet func moveBack(sender: AnyObject) {
UIView.animateWithDuration(0.0, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .BeginFromCurrentState, animations: { /* animation */ }) { _ in /* completion */ 
    //inside completion block make the moveBackFlag to true
        moveViewFlag = true

       if moveBackFlag{
          //do whatever you want to do!
       }
}
}

Hope this helps.

Than you should create a custom class and handle that inside the class to avoid cluttered flags.

Upvotes: 0

Related Questions