Topics

#95: 3D Touch 👊

Topics

We've covered a few of the new 3D Touch APIs in iOS 9 like Static and Dynamic Shortcut Items (Bite #79, #88) as well as View Controller Previews (Bite #80), but today we'll look at how to access and utilize raw force values from a user's touches. Let's get started.

We'll start with the "Single View" template. We'll open up our Main.storyboard and drag a UIProgressView out to the top of the screen. Then we'll give it an @IBOutlet in our ViewController and wire it up.

Next, the fun part. We'll create a new function called updateForTouches, that will take in an optional Set of UITouch objects. We'll guard to make sure 3D Touch is available, and assume our force is 0.0 unless a touch is present. Then, we update the progress property of our progress view and for good measure, we'll set a red background color on our view, mapping it's opacity to the touch's force as well.

func updateForTouches(touches: Set<UITouch>?) {
  guard traitCollection.forceTouchCapability == .Available else { return }

  var force: Float = 0.0

  if let touches = touches, let touch = touches.first {
    force = Float(touch.force / touch.maximumPossibleForce)
  }

  forceProgressView.progress = force
  view.backgroundColor = UIColor.redColor().colorWithAlphaComponent(CGFloat(force))
}

Lastly we'll need to implement all the touchesBegan, touchesMoves, touchesCancelled, and touchesEnded functions, calling our function and passing in the touches on each:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
  super.touchesBegan(touches, withEvent: event)
  updateForTouches(touches)
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
  super.touchesMoved(touches, withEvent: event)
  updateForTouches(touches)
}

override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
  super.touchesCancelled(touches, withEvent: event)
  updateForTouches(touches)
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
  super.touchesEnded(touches, withEvent: event)
  updateForTouches(touches)
}

Success! If we build and run on an iPhone 6S or iPhone 6S Plus, we can start pressing the screen lightly and watch as the progress view and background color change as we begin pressing more firmly.

It might not be immediately obvious when playing around with Shortcut Items or View Controller Previews, but the hardware does in fact report every single tiny change in the force in real time. Neat!

You can download the project we built here.