This year, I entered the WWDC 2015 Scholarships competition. I didn’t win, but there were a couple of interesting parts of my app that I thought were still worth sharing.

My design centred around rising and falling blocks that represented the different parts of my life. These blocks had mass and density and elasticity, and they responded in a lively way. And, like little blocks in a glass case, I wanted them to fall away when the device rotated.

I tried doing this by animating blocks from one side of the device to the other, but it just didn’t feel right. The blocks needed to be physical. I needed a physics engine: UIKit Dynamics.

The first step to this is to get the blocks falling down the device in a realistic way. The second step is to listen for device orientation changes, and update our blocks in response to these changes.

We also add a UIDynamicAnimator, which controls the physics for the system. We add a UIGravityBehavior, for replicating gravity, and collisions and elasticity between the items.

// Animator for all of the componentsvaritemsAnimator:UIDynamicAnimator?// Gravity for the systemvargravityBehavior:UIGravityBehavior?// CollisionsvarboundaryCollisionBehavior:UICollisionBehavior?// ElasticityvarelasticityBehavior:UIDynamicItemBehavior?

Then we need to add all of these components to our master animator, and tweak the the elasticity of the blocks so they’re more bouncy.

// Our master item animatoritemsAnimator=UIDynamicAnimator(referenceView:view)// The gravity for our systemgravityBehavior=UIGravityBehavior(items:blocks)// The collision between our items, and with the boundary of the containing viewboundaryCollisionBehavior=UICollisionBehavior(items:blocks)boundaryCollisionBehavior?.translatesReferenceBoundsIntoBoundary=true// The elasticity for the blockselasticityBehavior=UIDynamicItemBehavior(items:blocks)elasticityBehavior?.elasticity=0.6// Add everythingitemsAnimator?.addBehavior(gravityBehavior)itemsAnimator?.addBehavior(boundaryCollisionBehavior)itemsAnimator?.addBehavior(elasticityBehavior)

At this stage, our view controller will be something like (regularGravityVector and invertedGravityVector are not needed yet, but will be useful later).

classViewController:UIViewController{// MARK: - Blocks// Our blocklazyvargreenBlock:UIView={letview=UIView(frame:CGRect(x:50.0,y:50.0,width:100.0,height:100.0))view.backgroundColor=UIColor.greenColor()returnview}()lazyvarorangeBlock:UIView={letview=UIView(frame:CGRect(x:125.0,y:190.0,width:50.0,height:50.0))view.backgroundColor=UIColor.orangeColor()returnview}()// MARK: - Dynamics properties// Animator for all of the componentsvaritemsAnimator:UIDynamicAnimator?// Gravity for the systemvargravityBehavior:UIGravityBehavior?lazyvarregularGravityVector:CGVector={CGVector(dx:0,dy:1.0)}()lazyvarinvertedGravityVector:CGVector={CGVector(dx:0,dy:-1.0)}()// CollisionsvarboundaryCollisionBehavior:UICollisionBehavior?// ElasticityvarelasticityBehavior:UIDynamicItemBehavior?// MARK: - View lifecycleoverridefuncviewDidLoad(){super.viewDidLoad()// Listen for orientation changesNSNotificationCenter.defaultCenter().addObserver(self,selector:"orientationChanged:",name:UIDeviceOrientationDidChangeNotification,object:UIDevice.currentDevice())// Add our blocks to the viewview.addSubview(greenBlock)view.addSubview(orangeBlock)letblocks=[greenBlock,orangeBlock]// Our master item animatoritemsAnimator=UIDynamicAnimator(referenceView:view)// The gravity for our systemgravityBehavior=UIGravityBehavior(items:blocks)// The collision between our items, and with the boundary of the containing viewboundaryCollisionBehavior=UICollisionBehavior(items:blocks)boundaryCollisionBehavior?.translatesReferenceBoundsIntoBoundary=true// The elasticity for the blockselasticityBehavior=UIDynamicItemBehavior(items:blocks)elasticityBehavior?.elasticity=0.6// Add everythingitemsAnimator?.addBehavior(gravityBehavior)itemsAnimator?.addBehavior(boundaryCollisionBehavior)itemsAnimator?.addBehavior(elasticityBehavior)}}

We can build and run our project, and see the cool falling-blocks effect.

To achieve the cool effect of blocks-in-a-box, we wanted to be able to rotate the device and have the gravity flip around. This is super easy to implement, thanks to the setup we did earlier.