Lance Samaria
Lance Samaria

Reputation: 19572

UICollisionBehavior Ignore Screen Edges

I have several UIViews continuously move across the screen. Using UICollisionBehavior I can prevent the views from bumping into each other but I need them to pass through the edges (top, left, right, bottom) of the screen. In this example below once they hit the bottom edge of the screen they bounce off of each other and then eventually just sit there. I tried to subclass the UIViews and see if the collision would only apply to the subclass types but that didn't work.

How can I prevent the UIViews from colliding into each other but still let them pass through the edges of the screen?

subclass:

class CollisionView: UIView { // nothing special happens here except it's a subclass
}

code:

lazy var redView: CollisionView = {
    let view = CollisionView()
    view.backgroundColor = .red
    return view
}()

lazy var blueView: CollisionView = {
    let view = CollisionView()
    view.backgroundColor = .blue
    return view
}()

lazy var yellowView: CollisionView = {
    let view = CollisionView()
    view.backgroundColor = .yellow
    return view
}()

lazy var purpleView: CollisionView = {
    let view = CollisionView()
    view.backgroundColor = .purple
    return view
}()

lazy var greenView: CollisionView = {
    let view = CollisionView()
    view.backgroundColor = .green
    return view
}()

var arr = [CollisionView]()

var animator: UIDynamicAnimator!
var gravity: UIGravityBehavior!
var collider: UICollisionBehavior!
var bouncingBehavior  : UIDynamicItemBehavior!

override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .white
    
    addSubViews()
    
    addAnimatorAndBehaviors()
}

func addAnimatorAndBehaviors() {
    
    animator = UIDynamicAnimator(referenceView: self.view)
    
    gravity = UIGravityBehavior(items: arr)
    animator.addBehavior(gravity)
    
    collider = UICollisionBehavior(items: arr)
    collider.translatesReferenceBoundsIntoBoundary = true
    animator.addBehavior(collider)
    
    bouncingBehavior = UIDynamicItemBehavior(items: arr)
    bouncingBehavior.elasticity = 0.75
    animator.addBehavior(bouncingBehavior)
}

func addSubViews() {
    
    let size = CGSize(width: 50, height: 50)
    
    redView.frame = CGRect(origin: view.center, size: size)
    blueView.frame = CGRect(origin: view.center, size: size)
    yellowView.frame = CGRect(origin: view.center, size: size)
    purpleView.frame = CGRect(origin: view.center, size: size)
    greenView.frame = CGRect(origin: view.center, size: size)
    
    view.addSubview(redView)
    view.addSubview(blueView)
    view.addSubview(yellowView)
    view.addSubview(purpleView)
    view.addSubview(greenView)
    
    arr = [redView, blueView, yellowView, purpleView, greenView]
}

Upvotes: 1

Views: 42

Answers (1)

Lance Samaria
Lance Samaria

Reputation: 19572

Easy fix, I only had to add:

collider.collisionMode = .items

enter image description here

The CollisionView subclass is unnecessary

Upvotes: 1

Related Questions