Theo Strauss
Theo Strauss

Reputation: 1351

Using UIDynamics gravity to animate CGRects

My goal is to have a bunch of UIViews that have a property of CGRect falling from offscreen and then piling up. Right now, I have one circle working, but every time I try to add another circle, they won't animate anymore. I am using UIDynamics and its gravity function. Here is my code:

func addBox(location: CGRect) -> UIView {
    let newBox = UIView(frame: location)
    newBox.backgroundColor = UIColor(red: 186.0/255.0, green: 216.0/255.0, blue: 242.0/255.0, alpha: 1.0)
    newBox.layer.cornerRadius = newBox.frame.width/2

    hView.insertSubview(newBox, at: 0)

    return newBox
}


addBox(location: CGRect(x: 100, y: -100, width: 100, height: 100))    

var animator: UIDynamicAnimator? = nil;
let gravity = UIGravityBehavior()
var collision: UICollisionBehavior!
animator = UIDynamicAnimator(referenceView: hView)

func createAnimatorStuff(box: UIView) {
    collision = UICollisionBehavior(items: [box])
    collision.translatesReferenceBoundsIntoBoundary = true
    animator?.addBehavior(collision)

    gravity.addItem(box)
    gravity.gravityDirection = CGVector(dx: 0, dy: 0.8)
    animator?.addBehavior(gravity)

}

func dropDown() {
    let xVal = 100
    let xVal2 = 700

    let box = addBox(location: CGRect(x: xVal, y: 100, width: 100, height: 100))
    let box2 = addBox(location: CGRect(x: xVal2, y: 100, width: 100, height: 100))
    createAnimatorStuff(box: box)
    createAnimatorStuff(box: box2)
}
dropDown()

If anyone could help me and adjust my code to create more circles falling and then piling up I would immensely appreciate it. Truly. Please ask any questions and thank you so much in advance.

Upvotes: 2

Views: 310

Answers (1)

Lou Franco
Lou Franco

Reputation: 89162

(NOTE: the question was updated with these suggestions, so that's why it appears to suggest things that were already done)

The general problem you are having is that you made box a global variable and you keep reinitializing the UIDynamicAnimator. So ...

Remove the box var, then

Change:

func addBox(location: CGRect) 

to:

func addBox(location: CGRect) -> UIView

and return newBox at the end.

Then, change:

func createAnimatorStuff() {

to:

func createAnimatorStuff(box: UIView) {

and

addBox(location: CGRect(x: xVal, y: 100, width: 100, height: 100))
createAnimatorStuff()

To

let box = addBox(location: CGRect(x: xVal, y: 100, width: 100, height: 100))
createAnimatorStuff(box: box)

Finally, don't create a new UIDynamicAnimator for every call -- make one and share it. You can do this with

let animator = UIDynamicAnimator(referenceView: hView)

(also, you don't need semicolons in Swift)

Upvotes: 1

Related Questions