3D Touch 简单介绍与接入指南
0x00 前言
- 3D Touch 简单介绍
- Home Screen Quick Actions(动态生成)
- Peek&Pop
- Peek上拉快捷操作
文中的代码均取自本人的 Github 项目 For3DTouchDemo
0x01 3D Touch 简单介绍
3D Touch是苹果在2015年发布iPhone6s,iPhone 6s plus时加入的全新的触控方式。
1.用户可以在主屏幕按压APP图标来立即访问您的应用程序提供的功能
官方备忘录提供的快捷功能
2.在应用中用户可以通过按压视图来预览到更多内容和更快地访问功能
官方邮件应用的预览
Peek的快捷菜单
具体功能说明可以查看官方介绍:iOS Developer Library - Getting Started with 3D Touch
0x02 Home Screen Quick Actions(动态生成)
静态生成方法请查看官方文档: UIApplicationShortcutItems
动态方法是在项目中创建UIApplicationShortcutItem
对象(一般放置在AppDelegate
中)
- (void)configShortcutItems{
UIApplicationShortcutItem *item0 = [[UIApplicationShortcutItem alloc]initWithType:@"0" localizedTitle:@"NO.1"localizedSubtitle:nil icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeAdd] userInfo:nil];
UIApplicationShortcutItem *item1 = [[UIApplicationShortcutItem alloc]initWithType:@"1" localizedTitle:@"NO.2"localizedSubtitle:nil icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeAdd] userInfo:nil];
UIApplicationShortcutItem *item2 = [[UIApplicationShortcutItem alloc]initWithType:@"2" localizedTitle:@"NO.3"localizedSubtitle:nil icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeAdd] userInfo:nil];
[UIApplication sharedApplication].shortcutItems = @[item0, item1, item2];
}
注意!该段代码在程序中被执行过一次后才会被添加到主屏幕的 ShortcutItems 菜单中,所以首次安装完后不能直接使用。ShortcutItems最多可以设置4个,且静态生成在动态生成之前。
//这是UIApplicationShortcutItem中图标的类
NS_CLASS_AVAILABLE_IOS(9_0) __TVOS_PROHIBITED
@interface UIApplicationShortcutIcon : NSObject <NSCopying>
// Create an icon using a system-defined image.
+ (instancetype)iconWithType:(UIApplicationShortcutIconType)type;
// Create an icon from a custom image.
// The provided image named will be loaded from the app's bundle
// and will be masked to conform to the system-defined icon style.
+ (instancetype)iconWithTemplateImageName:(NSString *)templateImageName;
UIApplicationShortcutIconType是官方提供的图标标识,少部分才可以在9.0上显示,大部分只能在iOS 9.1之后使用。接入正式项目的话还是自己做图标比较好。
设置好ShortcutItems之后,我们就需要复写Appdelegate中的方法
- (void)application:(UIApplication *)application
performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem
completionHandler:(void (^)(BOOL))completionHandler
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler{
SubViewController *subVC = [[SubViewController alloc] init];
subVC.isPop = YES;
subVC.number = [shortcutItem.type integerValue] + 1;
self.window.rootViewController = [[UINavigationController alloc]initWithRootViewController:self.rootviewController];
[self.rootviewController.navigationController pushViewController:subVC animated:NO];
}
然后在真机上运行APP,就像这样
0x03 Peek&Pop
交互过程分为三个步骤:
- 轻压UI元素,周围界面变模糊,提示用户这边3d touch中peek可用
- 再稍微用力,会弹出对应元素的预览视图,若视图上有交互控件,通过向上滑动,可以进一步操作
- 继续用力,触发pop方法,进入预览的视图或者其他自定义的操作
注意! 按压力度要求跟用户的设置有关
首先需要遵循系统的代理方法UIViewControllerPreviewingDelegate
检查3D Touch是否可用
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
[self registerForPreviewingWithDelegate:self sourceView:self.tableview];
}
然后需要实现两个代理方法
- peek
- (nullable UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location{
NSIndexPath *indexPath = [self.tableview indexPathForRowAtPoint:location];
if (indexPath && indexPath.row >= 0 && indexPath.row < 6) {
SubViewController *subVC = [[SubViewController alloc] init];
subVC.number = indexPath.row + 1;
return subVC;
}
return nil;
}
- pop
- (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
SubViewController *vc = (SubViewController *)viewControllerToCommit;
vc.isPop = YES;
[self.navigationController pushViewController:vc animated:YES];
}
效果图如下
0x04 peek上拉快捷操作
在被预览的视图控制器中实现以下方法
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems;
- 具体代码
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems{
UIPreviewAction *item1 = [UIPreviewAction actionWithTitle:@"Share me!" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
NSLog(@"share");
}];
NSArray *actions = @[item1];
return actions;
}
效果图如下