3D Touch实战演练

摘要

iOS9提供了四类API(Home Screen Quick Action、UIKit Peek & Pop、WebView Peek & Pop和UITouch Force Properties)本篇只演练前两种。

Home Screen Quick Action

主屏幕快速选项,光说这个词不明白啥意思,上一张图就懂了,看图:

3D Touch实战演练_第1张图片

就是从图标呼出菜单,那么要实现这种效果,有两种方法

  1. 静态标签
  2. 动态标签

静态标签就是我们在Info.plist中配置,上图的例子就是用静态标签完成的


3D Touch实战演练_第2张图片

这里我们介绍一下参数

name 解释 是否必须
UIApplicationShortcutItemType 设置类型字符串,点击后以便在程序中处理
UIApplicationShortcutItemTitle 标题
UIApplicationShortcutItemSubtitle 副标题
UIApplicationShortcutItemIconType 图标,是个枚举值
UIApplicationShortcutItemIconFile 图标文件名
UIApplicationShortcutItemUserInfo 信息字典

建议及提醒

  1. 每个App的Item最多4条,这是系统做的限制。
  2. 要么都用静态标签,要么都用动态标签,两者都采用不会覆盖,但看起来好乱。
  3. 不用纠结呼出菜单的图标位置,是在左边还是右边由你的App图标所在屏幕位置决定,放在左边菜单的图片就在左边,放在右边图标就在右边。

一切都做好了,接下来就是回调了UIApplication为我们提供了回调方法。

- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler

此处需要注意的是,在App完全退出的情况下,上面方法Handler返回的是NO。
这就需要我们在下面方法中也加入相应的回调处理

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

苹果给我们提供了获取Item的方式:

UIApplicationShortcutItem *item = [launchOptions valueForKey:UIApplicationLaunchOptionsShortcutItemKey];

至此,我们的回调处理就算完成了,看一下完整版的代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    UIApplicationShortcutItem *item = [launchOptions valueForKey:UIApplicationLaunchOptionsShortcutItemKey];
    [self actionWithShortcutItem:item];
    
    return YES;
}

- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler {
    if (shortcutItem) {
        [self actionWithShortcutItem:shortcutItem];
    }
    
    if (completionHandler) {
        completionHandler(YES);
    }
}

-(void)actionWithShortcutItem:(UIApplicationShortcutItem *)item
{
    if (item) {
        UINavigationController *nav = [(UITabBarController *)self.window.rootViewController viewControllers][0];
        if ([item.type isEqualToString:@"FirstVC"]) {
            [nav.tabBarController setSelectedIndex:0];
        } else {
            [nav.tabBarController setSelectedIndex:1];
        }
    }
}

UIKit Peek & Pop

Peek & Pop就是在我们的程序中,通过按压某一块区域,进行不同的处理,peek是轻按后发生的,pop是在peek后,继续加力后发生的。

依照惯例,我们看下示例图:


3D Touch实战演练_第3张图片

上图中,黄色界面展示的就是peek的过程,在peek过程中可以加上Action,第二次进入peek后,再加力进入pop过程,这里我偷了点懒,直接切进了Second View。

在处理的过程中,我们首先要判断3D Touch是否可用。由于用户可能在使用应用的途中切到设置页面开启或关闭3D Touch功能,所以判断代码应放在viewDidAppear中,下面代码判断如果3D Touch可用,那么将tableView注册上。

- (void) check3DTouchAvailable {
    if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
        [self registerForPreviewingWithDelegate:(id)self sourceView:self.tableView];
    }
}

UIViewControllerPreviewingDelegate为我们提供了两个方法,分别用于处理peek过程和pop过程。

- (UIViewController *)previewingContext:(id)previewingContext viewControllerForLocation:(CGPoint)location
(void)previewingContext:(id)previewingContext commitViewController:(UIViewController *)viewControllerToCommit

别的文章说在peek处理过程中,peek代理方法会进来多次,所以要在处理过程中加判断。由于我手里没有6s,在模拟器中测试peek方法只进来了一次,为了保险起见,我还是加上了判断。

我需要根据点击的位置,判断具体点击了哪一行,然后peek相应行的详情,我们新建一个PeekViewController,用于展示上图中黄色view那部分。

- (UIViewController *)previewingContext:(id)previewingContext viewControllerForLocation:(CGPoint)location {
    if ([self.presentedViewController isKindOfClass:[PeekViewController class]]) {
        return nil;
    } else {
        CGPoint p = [self.tableView convertPoint:location fromView:self.view];
        NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
        
        PeekViewController *peekViewController = [[PeekViewController alloc] init];
        peekViewController.cellTitle = cell.textLabel.text;
        return peekViewController;
    }
}

切换到PeekViewController中,在PeekViewController什么代码都没添加的情况下,弹出来的是一片模糊,我把PeekViewController的背景颜色换成了黄色,就如图中展示的一样,就是块区域。

接下来,如果有需要的话,添加Action,这个就比较容易了,iOS 9在UIViewController中提供了previewActionItems属性,下面代码添加到PeekViewController中。

- (NSArray> *)previewActionItems
{
    UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"第一个Action" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"点击了第一个Action");
    }];
    
    UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"第二个Action" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"点击了第二个Action");
    }];
    
    return @[action1,action2];
}

上面代码只展示了UIPreviewAction,如果有需要,Action还可以进行二级菜单的处理,用UIPreviewActionGroup,不过个人觉得这种功能做的太复杂反而不美。

到现在为止图中黄色过程就已经完成了。接下来在pop代理中,实现跳转逻辑,图中只是切换了一下tabbar,就一行代码我就不贴了。

下面是我在写例子过程中参考的文章。

在iOS9中使用3D Touch

浅谈3D Touch(1) -- Home screen quick action

浅谈3D Touch(2) -- UITouch && Peek && Pop

你可能感兴趣的:(3D Touch实战演练)