Tobias Schmidt
Tobias Schmidt

Reputation: 391

Cancel UIControl animateWithDuration to start a new animation

I have troubles in creating a very simple square button with the following behaviour:

The problem is, when I touch/lift up while the animation is playing the button should stop the current animation and shrink/grow. Right now I can only interact with the button after the grow/shrink animation is fully played.

I tried to use the layer.removeAllAnimations() function in the touch functions ... without success. I tried to animate the View itself and the layer.

Here is my attempt of the UIControl that I used to build my custom button.

import UIKit

class TriggerPad: UIControl {

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init(frame: CGRect) {
        //  I init the Frame with w:200 h:100 in my ViewController
        super.init(frame: frame)

        self.backgroundColor = UIColor.clearColor()

        self.layer.frame = frame
        self.layer.backgroundColor = UIColor.blueColor().CGColor
        self.multipleTouchEnabled = true
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

        let oldFrame = self.layer.frame
        self.layer.removeAllAnimations()

        UIView.animateWithDuration(2) { () -> Void in
            self.layer.frame.size.height = 50
            self.layer.frame.size.width = 100
            // I need to adjust the origin here
        }
    }

    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {

        let oldFrame = self.layer.frame
        self.layer.removeAllAnimations()

        UIView.animateWithDuration(2) { () -> Void in
            self.layer.frame.size.height = 100
            self.layer.frame.size.width = 200
            // I need to adjust the origin here
        }
    }
}

Upvotes: 4

Views: 2128

Answers (1)

Dario
Dario

Reputation: 3135

You can solve it adding to the UIView the animation option .AllowUserInteraction. Your code would be:

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

    UIView.animateWithDuration(2.0, delay: 0.0, options: UIViewAnimationOptions.AllowUserInteraction, animations: { () -> Void in
        self.layer.frame.size.height = 50
        self.layer.frame.size.width = 100
        // I need to adjust the origin here
    }, completion: nil)
}

    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {

    UIView.animateWithDuration(2.0, delay: 0.0, options: UIViewAnimationOptions.AllowUserInteraction, animations: { () -> Void in
        self.layer.frame.size.height = 100
        self.layer.frame.size.width = 200
        // I need to adjust the origin here
    }, completion: nil)
}

But I think you can get the similar effect to the App you mention with:

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

    UIView.animateWithDuration(2.0, delay: 0.0, options: UIViewAnimationOptions.AllowUserInteraction, animations: { () -> Void in
        self.transform = CGAffineTransformMakeScale(0.6, 0.6)
    }, completion: nil)

}

    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {

    UIView.animateWithDuration(2.0, delay: 0.0, options: UIViewAnimationOptions.AllowUserInteraction, animations: { () -> Void in
        self.transform = CGAffineTransformIdentity
    }, completion: nil)

}

Because this way it keeps the view's center.

Upvotes: 5

Related Questions