iOS 9之后提供以下几个3D Touch API:
1.Home screen quick action 主屏幕快速访问 最多四个
2.UIKit peek and pop 应用内peek、pop,提供了应用内的一个对触住的压力感应的替代方法
3.Web view peek and pop 让你可以预览HTML链接指定的网页
4.UITouch force properties让你可以自定义app基于压力的交互
不论你使用哪一个API,你都要在runtime的时候检查3D Touch是否可用。
一、检查3D Touch是否可用
如果当前对象遵循UITraitEnvironment协议(UIScreen、UIWindow、UIViewController、UIPresentationController、UIView),检查self.traitCollection.forceTouchCapability,它有三个值:
1.UIForceTouchCapabilityUnknown(3D Touch状态未知,例如,你创建了一个view但是你还没有将它加入到你的视图层级中,就会处于这个状态)
2.UIForceTouchCapabilityUnavailable(3D Touch不可用)
3.UIForceTouchCapabilityAvailable(3D Touch可用)
如果用户在app运行的时候关闭了3D Touch,可以在UITraitEnvironment协议中的traitCollectionDidChange:代理方法监测到变化,具体写法如下:
- (void) traitCollectionDidChange: (UITraitCollection *) previousTraitCollection
{
[super traitCollectionDidChange: previousTraitCollection];
if (self.traitCollection.forceTouchCapability!=previousTraitCollection.forceTouchCapability)
{
// your custom implementation here
}
}
为了保障所有用户都能体验到app的特性,根据3D Touch的支持情况配置不同的代码。可用的时候使用3D Touch,不可用的时候使用UILongPressGestureRecognizer类。
二、Home Screen Quick Actions
iOS 9支持主屏幕静态和动态的quick actions:
(1)静态quick actions:你的app安装完成后即可使用。在你的info.plist中定义UIApplicationShortCutItems数组。
每个item字典的键有以下几种:
1.UIApplicationShortcutItemType(必要)根据这一个值来判断你选的是哪一个quick action
2.UIApplicationShortcutItemTitle(必要)quick action的名字,如果该字符串过长并且没有设置subtitle,会以两行展示,还是不够的话末尾会变为省略号
3.UIApplicationShortcutItemSubtitle 副标题,会在主标题下面显示,主标题不论多长都会以一行显示,副标题过长会以一行显示,末位是省略号。
4.UIApplicationShortcutItemIconType 提供一些系统的图标
5.UIApplicationShortcutItemIconFile 从app bundle或者asset catalog中选择一张图片,要求方形,35X35点坐标,retina 屏幕是70 x 70像素,plus是104 x 104像素,设置了这个值,系统会忽略UIApplicationShortcutItemIconType
6.UIApplicationShortcutItemUserInfo 一个可选的,app定义的字典,这个字典的一个作用是提供app的版本,如果用户安装了你的app,按压icon会先显示静态quick actions,启动之后如果还有空位才会显示动态quick actions,如果用户更新了app但还没有启动,动态quick action还是显示的上一个版本的,在这个字典中添加版本信息可以解决这个问题。(具体如何实现?猜测是自己加入一个版本号字段,在代码中判断版本号,符合的话再加入)
(2)动态quick actions:首次启动后可用。使用UIapplicationShortcutItem,UIMutableApplicationShortcutItem,UIApplicaitionShortcutIcon定义主屏幕的动态quick action。使用UIApplication的shortcutItems属性添加动态quick actions。使用系统定义图片调用UIApplicationShortcutIcon的iconWithType:方法,自定义图片使用iconWithTemplateImageName:。
系统首先按照UIApplicationShortCutItems定义的静态quick actions的顺序展示,如果还有空余位置,再展示动态quick actions。
<small><small><small>当用户选择了一个主界面quick action,系统会调用application:performActionForShortcutItem:completionHandler:方法,但是注意,系统会在调用application:performActionForShortcutItem:completionHandler之前调用application:willFinishLaunchingWithOptions:和application:didFinishLaunchingWithOptions:,所以如果quick action使你的app显示的界面不一样的话(本来打开你的app会进入View A,但是使用quick action会进入View B),这时候就要在两个launch方法中处理quick action,UIApplicationShortcutItem存在于launchOptions的UIApplicationLaunchOptionsShortcutItemKey中,处理完成后,返回NO,系统就不会再调用application:performActionForShortcutItem:completionHandler:。</small></small></small>
三、UIKit Peek、Pop
1.Peek 当用户按压一个特定视图时弹出的一个的视图预览功能,除此之外,还可以添加一些quick actions,这些quick actions可以在peek弹出式向上滑动调出。
通过在要显示的viewController中设置previewActionItems数组添加,如下:
-(NSArray> *)previewActionItems
{
UIPreviewAction *p1 = [UIPreviewAction actionWithTitle:@"选项1" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
[FireflyAlertView showWithTitle:@"提示" message:@"选项1" buttonTitle:@"确定"];
}];
UIPreviewAction *p2 = [UIPreviewAction actionWithTitle:@"选项2" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
[FireflyAlertView showWithTitle:@"提示" message:@"选项2" buttonTitle:@"确定"];
}];
UIPreviewAction *p3 = [UIPreviewAction actionWithTitle:@"选项3" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
[FireflyAlertView showWithTitle:@"提示" message:@"选项3" buttonTitle:@"确定"];
}];
return @[p1,p2,p3];
}
2.Pop 当用户在peek后再次重压,则会继续预览这个视图并导向这个视图。
视图控制器如果想使用3D Touch,必须遵循UIViewControllerPreviewingDelegate协议,并使用以下方法注册
- (id)registerForPreviewingWithDelegate:(id)delegatesourceView:(UIView *)sourceView;
第一个参数填写当前视图控制器,self,第二个参数填写当前视图控制器的view。
UIViewControllerPreviewingDelegate协议中有两个方法,都是必须实现
1.- (UIViewController *)previewingContext:(id)previewingContextviewControllerForLocation:(CGPoint)location;
第一个参数由系统自己创建,注意这个协议不能在自定义的类中遵循,通过这个类可以获取以下四个属性
1.sourceRect 最初重压时不变模糊的区域
2.previewingGestureRecognizerForFailureRelationship 通过一个遵循UIGestureRecognizerDelegate协议的代理对象来使用这个手势,这个协议的方法可以让你在其他手势失败后再执行peek,或者同时开始识别等。(没有找到具体如何使用,知道的朋友欢迎补充)
3.delegate
4.sourceView
第二个参数用来标明是哪个坐标位置的控件要使用peek&pop。
2.-(void)previewingContext:(id)previewingContextcommitViewController:(UIViewController *)viewControllerToCommit
在这个方法中实现pop的时候是如何显示view controller的,showViewController:sender:(普通的方式),presentViewController:animated:completion:(动画+完成回调)
四、Web View Peek and Pop
在UIWebView和WKWebView中有一个属性allowsLinkPreview,设置为YES则可以在任意链接上使用peek和pop。
在SFSafariViewController中自动支持。(此处咱不介绍SFSafariViewController)
五、Force Properties in UITouch Objects
UITouch有两个新的属性—force和maximumPossibleForce,可以让你在所有的UIEvent中检测和响应压力。(估计跟Apple pencil相关的app会用到)