随着 Force Touch 在 iDevice 中的应用,3D Touch 也成了诸多公司积极适配的新功能,它为 iDevice 设备带来了预览(Peek)和敲击(Pop)以及压力感应等全新的操作体验。

关于其他 iOS 9 的特性与功能,有兴趣的朋友可以参考我博客中的 iOS 9 适配系列

更多关于 3D Touch 的内容请参阅 Getting Started with 3D TouchiOS SDK Release Notes for iOS 9.1

苹果开发3D Touch的幕后故事 开发难度超乎想象

对于开发小伙伴们来说,我们的关注点主要涉及以下几个部分:

  • Pressure Sensitivity: 压力灵敏度。允许针对不同的压力情况做出反应。

  • Peek and Pop: 预览(Peek)和敲击(Pop)手势。

  • Quick Actions: 快捷动作。这个功能应用于系统 Home 页面,类似于个人电脑中的右键操作,分为静态与动态两种情况。

Pressure Sensitivity

苹果在 iOS 9 中为 UITouch 增加了一些的属性和方法进行扩充来满足开发者的使用需求:

属性描述返回值
altitudeAngle当笔平行于平面时,该值为 0;当笔垂直于平面时,该值为 Pi / 2
estimatedProperties当前触摸对象估计的触摸特性UITouchPropertyies
updatedProperties当前触摸对象已经更新的触摸特性UITouchPropertyies
estimationUpdateIndex当每个触摸对象的触摸特性发生变化时,该值将会单独增加NSNumber
方法描述
PreciseLocationInView:当前触摸对象的坐标
PrecisePreviousLocationInView:当前触摸对象的前置坐标
azimuthAngleInview:沿着 x 轴正向的方位角;当与 x 轴正向方向相同时,该值为 0;当 view 参数为 nil 时,默认为 keyWindow
azimuthUnitVectorInView:当前触摸对象的方向上的单位向量;当 view 参数为 nil 时,默认为 keyWindow
UIForceTouchCapability说明
UIForceTouchCapabilityUnknown不能确定是否支持压力感应
UIForceTouchCapabilityUnavailable不能支持压力感应
UIForceTouchCapabilityAvailable可以支持压力感应
UITouchType说明
UITouchTypeDirect垂直的触摸类型
UITouchTypeIndirect非初值的触摸类型
UITouchTypeStylus水平的触摸类型
UITouchProperties说明
UITouchPropertyForce

Peek and Pop

要使用预览(Peek)和敲击(Pop)功能,首先需要遵守 UIViewControllerPreviewingDelegate 协议:

@interface MXSomeViewController: UIViewControll <UIViewControllerPreviewingDelegate>

然后实现方法:

- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
    UIViewController *previewController = [UIViewController new];
    previewController.preferredContentSize = CGSizeMake(0., 200.);
    previewingContext.sourceRect = CGRectMake(8, location.y - 8, self.view.frame.size.width - 16, 16);
    return previewController;
}

- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
    [self showViewController:viewControllerToCommit sender:self];
}

最后,别忘了在控制器中进行注册:

[self registerForPreviewingWithDelegate:self sourceView:self.view];

Quick Actions

在实际应用中,Quick Actions 又被分为静态与动态两种情况,前者被用于在你的应用从未被用户完整启动过的情况下显示,反之,如果有过至少一次完整启动,会显示开发者配置的动态动作。

静态动作的配置Info.plist 中即可完成,我们只需为 UIApplicationShortcutItems 关键字添加 item 即可。

动态动作的配置要在代码中完成,首先要创建 UIApplicationShortcutItem,苹果为我们提供了很多方法:

- - initWithType:localizedTitle:localizedSubtitle:icon:userInfo:
- - initWithType:localizedTitle:

以及这些属性:

- - localizedTitle:NSString
- localizedSubtitle:NSString
- type:NSString
- icon:UIApplicationShortcutIcon
- userInfo:NSDictionary

这里需要注意一点,UIApplicationShortcutItem 是不可变的,它对应的可变类型为 NSMutableApplicationShortcutItem

然后,与静态动作类似,我们也需要 item:

+ + iconWithType:
+ + iconWithTemplateImageName:
+ + iconWithContact:

接着,我们前面提到,要显示动态动作要求应用至少完整启动一次,也就是说在程序启动后还有一些事情需要做,与推送功能类似,我们同样要判断 launchOptions 字典的内容,也即 UIApplicationLaunchOptionsShortcutItemKey 的值是否为空, 当它不为空时 application:didFinishLaunchWithOptions 方法返回 false,反之返回 true

最后,对于动作的点击事件处理,则需要用到 application:performActionForShortcutItem:completionHandler 方法。

当然,有了增,必不可少的也会有删改查操作,首先介绍最简单的 功能:

//获取一个应用程序对象的shortcutItem列表
NSArray *existingShortcutItems = [[UIApplication sharedApplication] shortcutItems];

是的,它真的简单到只有一句代码,接下来介绍 功能:

// 以第 0 个为例
NSArray *existingShortcutItems = [[UIApplication sharedApplication] shortcutItems];
UIMutableApplicationShortcutItem *curItem = [[existingShortcutItems objectAtIndex: 0] mutableCopy];
    [curItem setLocalizedTitle: @"Meniny"];

当然,就算你要用新的 items 进行重置也完全是靠谱的:

UIApplicationShortcutItem *newitem = [[UIApplicationShortcutItem alloc] initWithType: @"Meniny"localizedTitle: @"Meniny' Blog"];
NSMutableArray *newShortcutItems = [existingShortcutItems mutableCopy];
[newShortcutItems replaceObjectAtIndex: 0 withObject: newitem];
[[UIApplication sharedApplication] setShortcutItems: newShortcutItems];