Ad

How To Make UIView Animation Re-execute, Not .repeat In IOS (Swift)

- 1 answer

I would like to extend UIView to include an animation that makes a view shake (in consecutive but RANDOM rotations and translation distances) for an indefinite period.

I tried adding the following extention to UIView:

func tremble() {

    UIView.animate(withDuration: 0.5, delay: 0, options: [.repeat, .autoreverse, .allowUserInteraction], animations: {
        var randomFromZeroToOne = CGFloat(Float(arc4random()) / Float(UINT32_MAX))
        let randomBool:Bool = arc4random_uniform(2) == 0
        if randomBool { randomFromZeroToOne = -randomFromZeroToOne }
        let degrees = randomFromZeroToOne / 5
        self.transform = CGAffineTransform(translationX: randomFromZeroToOne, y: randomFromZeroToOne)    
        self.transform = CGAffineTransform.init(rotationAngle: degrees)       
    }, completion: nil)
}

But I am seeing now that the .repeat option simply repeats the exact same animation (with all the initially defined "random" variables, and it does not re-EXECUTE the animation (creating new random variables with each execution).

How can I make it do what I want? I have tried other options such as .beginFromCurrentState, .overrideInheritedOptions...

Ad

Answer

You can try this

 func tremble() {

        var randomFromZeroToOne = CGFloat(Float(arc4random()) / Float(UINT32_MAX))
        let randomBool:Bool = arc4random_uniform(2) == 0
        if randomBool { randomFromZeroToOne = -randomFromZeroToOne }
        let degrees = randomFromZeroToOne / 5

    UIView.animate(withDuration: 0.5, delay: 0, options: [ .allowUserInteraction], animations: {
        self.transform = CGAffineTransform(translationX: randomFromZeroToOne, y: randomFromZeroToOne)    
        self.transform = CGAffineTransform.init(rotationAngle: degrees)       
    }, completion: {
        self.tremble()
    })
}
Ad
source: stackoverflow.com
Ad