Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make multiple UIImages fall with gravity at the same time?

As the user taps on superview I am detecting it via UITapGestureRecognizer and calling below function to create a UIImage view, add it to superview, add gravity to it and let it fall out of the superview.

Problem is that if the user taps again while the first UIImage is still on the screen, first image halts in place and the second UIImage starts falling. What is the best way to let multiple UIImage fall independently on the screen.

Secondly, I feel, I should be removing these UIImage from superview to conserve memory (as there could be hundreds of taps but I cant figure out how to automatically remove a UIImage as soon as it is out of the screen.

Help in swift please.

func dropBall(tapLocation:CGPoint) {
    let ball = UIImageView(image: UIImage(named: "White50.png"))
    ball.frame = CGRect(origin: CGPoint(x:tapLocation.x-25,y:tapLocation.y-25), size: CGSize(width:50,height:50))
    view.addSubview(ball)

    animator = UIDynamicAnimator(referenceView: self.view)
    gravity = UIGravityBehavior(items: [ball])
    animator.addBehavior(gravity)
}
like image 748
Kashif Avatar asked Feb 11 '23 06:02

Kashif


1 Answers

The reason the first animation stops is that when you call this again, you are instantiating a new animator and releasing the old one. You should instantiate the animator only once. Likewise, you should instantiate gravity just once.

In terms of stopping the behavior once the view is off screen, one technique is to add an action block for the behavior, iterate through the behavior's items and see if each is still on screen, and remove the item from the behavior's list of items when the item falls off screen.

override func viewDidLoad() {
   super.viewDidLoad()

    animator = UIDynamicAnimator(referenceView: view)

    gravity = UIGravityBehavior()
    gravity.action = { [unowned self] in
        let itemsToRemove = self.gravity.items.filter() { !CGRectIntersectsRect(self.view.bounds, $0.frame) }
        for item in itemsToRemove {
            self.gravity.removeItem(item as UIDynamicItem)
            item.removeFromSuperview()
        }
    }
    animator.addBehavior(gravity)
}

Now, to give an item gravity, just add the item to the gravity behavior and it will automatically be removed when it falls out of view:

gravity.addItem(ball)
like image 121
Rob Avatar answered Feb 13 '23 19:02

Rob