3D Touch in iOS 9, Part 2: Preview Actions

Photo Sep 26, 10 57 04

If you’ve implemented a Peek (or preview) in your app as described in my previous article, you may be interested in implementing Preview Actions as well. Those come up when the user triggers the Peek preview and swipes up. Notice the arrow icon at the top of the preview if such actions are available.

It’s easy to add them to your preview controller, although it’s not as clearly described in the Apple documentation as it perhaps should be. Here’s how to do it.

In a nutshell, we need to create an array of UIPreviewActions, each of which has a title, a style and a completion block. Then we replace this array in our preview view controller (it works much like overriding a method with our own). The result looks just like an UIActionSheet.

- (NSArray<id> *)previewActionItems {
    
    // setup a list of preview actions
    UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"Action 1" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Action 1 triggered");
    }];
    
    UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"Destructive Action" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Destructive Action triggered");
    }];
    
    UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"Selected Action" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Selected Action triggered");
    }];
    
    // add them to an arrary
    NSArray *actions = @[action1, action2, action3];
    
    // and return them
    return actions;
}

Those methods look a little scary because the parameters are so long, but code completion will gladly help you out.

Each Preview Action can have a style of default, destructive (red) or selected (with a tick mark). There’s no need to implement a delegate for reacting to the outcome of those actions, because each action has a completion block attached to it, in which you can define what shall happen if the user selects the action.

Preview Actions can in fact be grouped together to create submenus. The principle is very similar to the above:

  • create your actions and add them to an array
  • add the array to a UIPreviewActionGroup
  • repeat for other groups as necessary
  • add all groups to yet another array
  • return the array of action groups in previewActionItems

Here’s an example (with only a single group, based on the above):

- (NSArray<id> *)previewActionItems {
        
    // setup a list of preview actions
    UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"Action 1" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Action 1 triggered");
    }];
    
    UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"Destructive Action" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Destructive Action triggered");
    }];
    
    UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"Selected Action" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Selected Action triggered");
    }];
    
    // add them to an arrary
    NSArray *actions = @[action1, action2, action3];
    
    UIPreviewActionGroup *group1 = [UIPreviewActionGroup actionGroupWithTitle:@"Action Group" style:UIPreviewActionStyleDefault actions:actions];
    NSArray *group = @[group1];
    
    // and return them
    return group;
}

There’s no need to deal with dismissals or transitions, iOS will handle this beautifully for us.





Leave a Reply