3D Touch in iOS 9, Part 1: Peek and Pop

Screen Shot 2015-09-26 at 09.48.21

With the introduction of the iPhone 6s we have some new ways of getting user input via 3D Touch. Now THAT’S innovative!

There are several things we can do with 3D Touch, and the first one we’ll explore here is Peek and Pop. When the user presses down a little harder, a Peek (or preview) appears, and if the user presses even harder, a Pop (or commit) view controller appears. Both are plain view controllers that are called via a delegate method we need to implement. Let’s see how this works.

Before we begin

The first thing we’ll need to do is to indicate that our view controller will conform to a new protocol. It’s called the UIViewControllerPreviewDelegate Protocol.

@interface ViewController () <UIViewControllerPreviewingDelegate>
@property (nonatomic, strong) UILongPressGestureRecognizer *longPress;

For backward compatibility I’ll also add a long press gesture recogniser here. Should our sample app be run on a device without 3D Touch support, at least the preview can be brought up via a long press gesture.

We’ll check if 3D Touch is available using something like the following method. To complete the setup, I’ve also included a custom initialiser for the long press gesture.

- (void)check3DTouch {
    
    // register for 3D Touch (if available)
    if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
        
        [self registerForPreviewingWithDelegate:(id)self sourceView:self.view];
        NSLog(@"3D Touch is available! Hurra!");
        
        // no need for our alternative anymore
        self.longPress.enabled = NO;
        
    } else {
        
        NSLog(@"3D Touch is not available on this device. Sniff!");
        
        // handle a 3D Touch alternative (long gesture recognizer)
        self.longPress.enabled = YES;
        
        }
}

- (UILongPressGestureRecognizer *)longPress {
    
    if (!_longPress) {
        _longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(showPeek)];
        [self.view addGestureRecognizer:_longPress];
    }
    return _longPress;
}

The above checks a new property of the UITraitCollection class called forceTouchCapability. If it returns the enum “available”, then the device is 3D Touch capable and it’s switched on. Note that at the time of writing, only the iPhone 6s and 6s Plus support this feature, and of course the iPad Pro when it arrives in November. Neither the iPhone 6 or earlier, nor the Simulator support the 3D Touch feature.

Because there’s a chance that the user may disable 3D Touch at any point, we can call this method in viewWillAppear. This will make sure it gets called when the app launches and when our main view comes back into vision. In that case, we’ll simple enable the long press gesture and the app keeps working. If the user switched 3D Touch on again, we’ll disable that gesture so it won’t interfere with 3D Touch.

We also want to call this method in traitCollectionDidChange, which is called when the user switches the 3D Touch feature on or off (among other occasions). Here’s how we do that:

This content is for members only.

Make sure to implement a method that can dismiss the preview view controller, otherwise it’ll just sit on top of the stack and not go away again.

When the user swiped up while the preview view is displayed, we can display what’s known as Preview Action items. I’ll discuss this in my next article.

Implementing Pop

Once the preview is presented, the user can elect to press deeper to switch to another view controller. Again, all we have to do is to conform to the second method of our above protocol. This one is called previewingContext:commitViewController:viewControllerToCommit.

Just like before, I’ll instantiate a view controller from my storyboard here.

This content is for members only.

Further Reading





Leave a Reply