44

In ViewController.Swift I managed to make a box animate from one point to another. I thought it would be easy to loop this so the box will animate to one point and then animate back to its original position and then loop again. I have managed to move the object to a position and in "complete" move it back again, but that doesn't make i loop. How can this be achieved?

I thought maybe this could work but i honestly don't know:

let boxmoves = [CGRect(x: 120, y: 220, width: 100, height: 100), CGRect(x: 120, y: 120, width: 100, height: 100)]
for boxmove in boxmoves {
    coloredSquare.frame = boxmove
}

How could I center it based on the device-width (I assume there are some math involved?)?

My code:

let coloredSquare = UIView()

coloredSquare.backgroundColor = UIColor.blueColor()

coloredSquare.frame = CGRect(x: 120, y: 120, width: 100, height: 100)

self.view.addSubview(coloredSquare)

// found repeate but this will not animate as I want.
//UIView.animateWithDuration(2.0, delay: 0.2, options: UIViewAnimationOptions.Repeat, animations: {
UIView.animateWithDuration(2.0, animations: {

    coloredSquare.frame = CGRect(x: 120, y: 220, width: 100, height: 100)

    }, completion: { finished in
        UIView.animateWithDuration(2.0, animations: {
        coloredSquare.frame = CGRect(x: 120, y: 120, width: 100, height: 100)
        })
})
Cœur
  • 37,241
  • 25
  • 195
  • 267
JLR
  • 723
  • 1
  • 8
  • 17

2 Answers2

159

No need to do the completion block approach, just use the animation options argument:

updated for Swift 3.0

UIView.animate(withDuration: 2.0, delay: 0, options: [.repeat, .autoreverse], animations: {

    coloredSquare.frame = CGRect(x: 120, y: 220, width: 100, height: 100)

}, completion: nil)

If for any reason you want to stop the animation later, just use:

coloredSquare.layer.removeAllAnimations()
Mazyod
  • 22,319
  • 10
  • 92
  • 157
  • Wow, it was that easy. Thanks @Mazyod! Do you know how to center it based on device-width as well? – JLR Dec 26 '14 at 18:50
  • 1
    @JohanNdiyoLinnarsson Well, you'd have to remove all those hard coded values, obviously. Try setting the frame with the size you want, then animating the `coloredSquare.center` property, instead of the frame. To center it in the view, try `coloredSquare.center = view.center`, or better `coloredSquare.center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)` – Mazyod Dec 26 '14 at 18:56
  • if you're not using autolayout, you'd also need to set the `autoresizingMask` property to flexible margins. – Mazyod Dec 26 '14 at 18:58
  • Thank you for your kind help @Mazyod. With your help I manage to solve my problem. – JLR Dec 26 '14 at 19:33
  • 2
    @Blankarsch `coloredSquare.layer.removeAllAnimations()` – Mazyod Feb 19 '16 at 19:38
  • For a UIButton animation: use buttonName.imageView?.layer.removeAllAnimations() – Stotch May 16 '20 at 15:56
2
UIView.animate(withDuration: 3.0,
                           delay: 0.0,
                           options: [.curveLinear, .repeat],
                           animations: { () -> Void in
                           coloredSquare.frame = CGRect(x: 120, y: 220, width: 100, height: 100)

}, completion: { (finished: Bool) -> Void in

})
niku
  • 472
  • 3
  • 12