Funny things: 3D Touch

一些废话

首先声明,本文并不会涵盖所有所有关于 3D Touch 的东西,因为我只想介绍我觉得还不错的东西。如果你希望把3D Touch彻彻底底啃一遍,那就好好钻研一下文档,以及各个 Sample 吧~~

最近入手了一个iPhone 6s Plus,也是我人生中的第一部真正意义上的iPhone。作为一个iOS开发者,手上拿着MX4 Pro用也是经常被实习的同事们嘲讽。现在终于摆脱了卡卡卡的安卓手机辣!写这篇博客的时候心里还在暗喜,然而这不是本文的主题!

其实我是想说,有了新手机,第一个想折腾的就是3D Touch。目前我看到的适配了3D Touch的App(当然,除了苹果自家的)有微信和新浪微博,适配速度那简直叫一个快,iPhonoe 6s一发货就已经更新支持了3D Touch。在这里就想和大家分享一下,另外我会在10月10日的iShare的第一次活动中和大家一起聊聊3D Touch。同时还有两个炒鸡牛逼的朋友和大家分享其他叼叼的iOS相关技术,在南京有空的同学欢迎来参加哟~

3D Touch API们

用3D Touch 的 API 们,我做了一个小 Demo,名曰Scroker,意为Scrum Poker。有兴趣一看的同学们可以>>>戳我<<<

好了,废话不多说,直接进入主题。3D Touch的官方(>>>官方文档戳我<<<)给的途径主要有以下三种:

  1. Home Screen Quick Actions
  2. Peek and Pop
  3. UITouch

挨着来说。

Home Screen Quick Actions

即是重按主界面应用图标后弹出的快捷菜单比如说微博的ShortcutItem:

ShortcutItems

*需要注意的是:*这个弹出菜单的样式我们不能改。唯一可以改的,就是item的数量、文字和icon。

实现Quick Actions有两种办法: 静态、动态。

Static(静态) Quick Actions

只需要修改 Info.plist 文件中的 UIApplicationShortcutItems 即可。(具体可以参考>>>官方文档戳戳戳<<<), 有一张图片,一看就能懂:Static quick actions

Dynamic(动态) Quick Actions

如果需要动态地修改Quick Actions,那么我们就需要在合适的地方,修改UIApplication中的shortcutItems属性。代码如下:

    NSMutableArray *items = NSMutableArray.new;
    // 这里的icon为nil,就不会有对应的图标。
    [items addObject:[[UIApplicationShortcutItem alloc] initWithType:@"Poker1" localizedTitle:@"1h" localizedSubtitle:@"Choose a ONE-HOUR poker" icon:nil userInfo:nil]];
    [items addObject:[[UIApplicationShortcutItem alloc] initWithType:@"Poker2" localizedTitle:@"2h" localizedSubtitle:@"Choose a TWO-HOUR poker" icon:nil userInfo:nil]];
    [items addObject:[[UIApplicationShortcutItem alloc] initWithType:@"Poker3" localizedTitle:@"3h" localizedSubtitle:@"Choose a THREE-HOUR poker" icon:nil userInfo:nil]];
    application.shortcutItems = items.copy;

上面的代码中,没有做icon。这里的icon还并不是单单的UIImage,而是一个叫UIApplicationShortcutIcon的类(>>>戳你懂<<<)。

在这个ShortcutIcon类中有三个方法,也是挺有意思的:

methods

  • iconWithType,这个 Type 是当前类的 constants,可以在文档上面找到。不同的Type对应不同的预设好的图片,有编辑啊,播放啊,暂停啊,添加啊等等等的图标。麻麻再也不用担心我懒得找图标没图标用辣(逃

  • iconWithTemplateImageName没啥好说的,自己看吧。注意一下下面这段话就好:

Icons should be square, single color, and 35x35 points, as shown in these template files and as described in Template Images in UIKit User Interface Catalog and in iOS Human Interface Guidelines.

  • iconWithContact 这个有点意思,参数是CNContact类,可以把联系人的头像撸过来玩。比如说我们可以做一个基于Quick Actions的猜爹游戏,让朋友猜猜哪个是你爹。。。2333,以上逗逼描述纯属娱乐→_→。

Actions在被点击后的响应

- (void)application:(UIApplication *)application performActionForShortcutItem:(nonnull UIApplicationShortcutItem *)shortcutItem completionHandler:(nonnull void (^)(BOOL))completionHandler {
//  Codes here
    NSLog(shortcutItem.type);
}

我想你应该能懂。=v=

Peek and Pop

Peek and Pop实际上就是基于重按的两个操作:peekpop使用场景item的详细信息不能完全展示出来时,通过3D Touch来预览以及跳转至详情页。Apple 公司在这一个交互操作中封装很严实,我们甚至不能决定动画的样式,只能修改一下这个preview窗体的高度。以下是Scroker的Peek and Pop动画:

Scroker

Peek

在第一次重按item时触发的操作,会弹出预览框。弹出预览框后,如果这时松手,那么预览框也会随即消失。

Pop

Peek操作完成后不松手,再次重按,就可以跳转至详情页了。在跳转至详情页的过程中,我们还可以看到一个轻微的纵向弹性动画。Duang~Duang~

How

我们就来一个最简单天然不加雕饰的Peek and Pop吧。
先上代码:

@interface SPMainViewController : UICollectionViewController<UIViewControllerPreviewingDelegate>
[self registerForPreviewingWithDelegate:self sourceView:self.view];
#pragma mark - peek and pop
// for peek
- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
    NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:location];
    if (!indexPath) {
        return nil;
    }
    SPMainViewCell *cell = (SPMainViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
    previewingContext.sourceRect = cell.frame;
    SPPokerDetailController *detailController = [self.storyboard instantiateViewControllerWithIdentifier:@"SPPokerDetailController"];
    detailController.pokerNumber = cell.number.text;
    detailController.preferredContentSize = CGSizeMake(0.0, 400);
    NSLog(@"peek action");
    return detailController;
}

// for pop
- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
    [self showViewController:viewControllerToCommit sender:self];
    NSLog(@"%@ pop action", previewingContext);
}

从上面可以看到,我们需要实现UIViewControllerPreviewingDelegate的两个代理方法。但在此之前我们还要注册一下registerForPreviewingWithDelegate:sourceView:。然后我们可以选择通过detailController.preferredContentSize来设置预览窗体的尺寸。很简单地就把Peek and Pop搞定啦~~

当然,除了上面这点东西以外,还有PreviewActions可以玩,就是在Peek后向上滑的菜单。留给感兴趣的你,去尝试吧~~

附带一个官方的Sample Code(Swift)

UITouch

UITouch里面多了两个API,分别是力度和最大力度。这个就可以很个性化地做一些帅气的交互操作辣!这没啥好说的,touch.forcetouch.maximumPossibleForce

Brain Storming

我们可以利用3D Touch玩些什么呢?我想到了不少好玩或者奇葩的→_→

  1. 增强型Garage Band,通过不同的力度来反馈不同的声音,以前Garage Band对于鼓这块有个有意思的优化,通过不知名的什么API能够判断用户是重击还是轻击。那时,架子鼓里面的乐器在受到重击和轻击所反馈的声音是不同的,这次引入3D Touch的force,我们可以做得更精确,分级更多。

  2. 屏幕破坏器,引导用户使劲按压屏幕,打地鼠啥的,按着按着突然……→_→2333333333别打我哈哈哈

  3. 钻洞游戏,手指的力度代表走的距离远近,洞不是笔直的,所以需要在走的时候控制方向,同时稳定地加大力度。诶好像还挺好玩诶!

抛砖完毕,各位玩好0v0~