3DTouch
一.概述
1.在日常开发中,我们经常需要使用3D Touch中的两个功能
在主屏幕上对应用图标使用3DTouch操作(ShortcutItem)
在应用程序内对某一控件使用3DTouch操作
二.ShortcutItem
ShortcutItem功能允许用户在主屏幕上对应用图标使用3DTouch操作,如果本次操作有效,则会给出几个快捷可选项允许用户进行操作
1.静态添加
在info.plist中添加UIApplicationShortcutItems关键字,以如下方式配置即可
// 其中各个关键字释义如下:
// UIApplicationShortcutItemType: 快捷可选项的特定字符串(必填)
// UIApplicationShortcutItemTitle: 快捷可选项的标题(必填)
// UIApplicationShortcutItemSubtitle: 快捷可选项的子标题(可选)
// UIApplicationShortcutItemIconType: 快捷可选项的图标(可选)
// UIApplicationShortcutItemIconFile: 快捷可选项的自定义图标(可选)
// UIApplicationShortcutItemUserInfo: 快捷可选项的附加信息(可选)
2.动态添加
- UIApplicationShortcutItem(单元)
每一个快捷可选项是一个UIApplicationShortcutItem
对象,其指定初始化器(NS_DESIGNATED_INITIALIZER)
如下
- (instancetype)initWithType:(NSString *)type localizedTitle:(NSString *)localizedTitle localizedSubtitle:(nullable NSString *)localizedSubtitle icon:(nullable UIApplicationShortcutIcon *)icon userInfo:(nullable NSDictionary *)userInfo;
// 其中各个参数释义如下:
// type: 快捷可选项的特定字符串(必填)
// localizedTitle: 快捷可选项的标题(必填)
// localizedSubtitle: 快捷可选项的子标题(可选)
// icon: 快捷可选项的图标(可选)
// userInfo: 快捷可选项的附加信息(可选)
- UIApplicationShortcutIcon(图标)
每一个快捷可选项图标为一个UIApplicationShortcutIcon
对象,我们可以使用系统提供的多个图标,也可以自定义我们自己的图标
// 使用系统提供的图标
+ (instancetype)iconWithType:(UIApplicationShortcutIconType)type;
// 自定义图标
+ (instancetype)iconWithTemplateImageName:(NSString *)templateImageName;
//注: 自定义图标需要使用镂空图标,同时建议1倍图标大小为35*35(如使用彩色图片及变成剪影效果)
- UIApplicationShortcutIconType
3.触发回调
当用户通过点击快捷可选项进入应用程序会回调如下方法,我们可以在这里通过快捷可选项的type来加以区分,以便进行不同的操作
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
{
if ([shortcutItem.type isEqualToString:@"item1"])
{
// do something ...
}
else if ([shortcutItem.type isEqualToString:@"item2"])
{
// do something ...
}
// ...
}
注意
在动态添加快捷可选项前,需要用判断是否支持3D Touch功能,以免在不支持的设备上运行程序导致闪退
if ([self respondsToSelector:@selector(traitCollection)])
{
if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)])
{
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
{
// 支持3D Touch
}
else
{
// 不支持3D Touch
}
}
}
注: 在支持3D Touch的设备上,用户可以在程序运行期间通过设置 -> 通用 -> 辅助功能 -> 3D Touch来关闭3D Touch功能,所以我们有必要通过重写-traitCollectionDidChange:方法随时处理
三.Peek(轻按) & Pop(重按)
Peek和Pop是应用内的一种全新交互模式,当用户不断增加力量在控件上按压,会依次进入四个阶段
- 1.轻按控件,除触发Peek的控件外,其他区域全部虚化
- 2.继续用力Peek被触发,展示Pop界面快照
- 3.向上滑动展示快捷选项
- 4.继续用力跳转进入Pop界面
实例
1.以"从ViewController中的UILabel控件通过Peek & Pop进入DetailViewController"为例,对Peek & Pop的使用进行一下讲解
需要实现Peek & Pop交互的控件所在的控制器遵守UIViewControllerPreviewingDelegate协议
@interface ViewController ()
@end
2.在控制器内为需要实现Peek & Pop交互的控件注册Peek & Pop功能
[self registerForPreviewingWithDelegate:self sourceView:label];
3.当进入Peek状态时,系统会回调如下方法
- (nullable UIViewController *)previewingContext:(id )previewingContext viewControllerForLocation:(CGPoint)location
{
// previewingContext.sourceView: 触发Peek & Pop操作的视图
// previewingContext.sourceRect: 设置触发操作的视图的不被虚化的区域
DetailViewController *detailVC = [[DetailViewController alloc] init];
// 预览区域大小(可不设置)
detailVC.preferredContentSize = CGSizeMake(0, 300);
return detailVC;
}
4.当进入Pop状态时,系统会回调如下方法
- (void)previewingContext:(id )previewingContext commitViewController:(UIViewController *)viewControllerToCommit
{
[self.navigationController pushViewController:viewControllerToCommit animated:YES];
}
5.在Peek时希望提供一些快捷选项,需要在DetailViewController中重写previewActionItems的getter方法
- (NSArray> *)previewActionItems
{
UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"选项一" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
}];//默认
UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"选项二" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
}];//选中
UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"选项三" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
}];//取消
UIPreviewActionGroup *actionGroup = [UIPreviewActionGroup actionGroupWithTitle:@"选项组" style:UIPreviewActionStyleDefault actions:@[action1, action2]];//会弹出二级列表
return @[action1, action2, action3, actionGroup];
}
四.封装方法
已在项目中使用
1.ShortcutItem
(1)封装方法
/*单例*/
+ (instancetype)defaultManager;
/*系统item*/
- (void)add3DTouchSystemItemWithIconType:(UIApplicationShortcutIconType)iconType type:(NSString *)type localizedTitle:(NSString *)localizedTitle localizedSubtitle:(NSString *)localizedSubtitle userInfo:(NSDictionary *)userInfo;
/*自定义item*/
- (void)add3DTouchCustomItemWithIconName:(NSString *)iconName type:(NSString *)type localizedTitle:(NSString *)localizedTitle localizedSubtitle:(NSString *)localizedSubtitle userInfo:(NSDictionary *)userInfo;
/*创建快捷方式*/
- (void)shortcutItems;
/*回调方法*/
- (void)actionShortcutItemType:(NSString *)type block:(void(^)(NSUInteger idx, NSArray* array))block;
(2)调用演示
- AppDelegate 激活itme
// 添加item
[default3DTouchManager add3DTouchCustomItemWithIconName:@"BorrowingSelected" type:@"item1" localizedTitle:@"急速借款" localizedSubtitle:nil userInfo:nil];
[default3DTouchManager add3DTouchCustomItemWithIconName:@"我的钱包" type:@"item2" localizedTitle:@"我的钱包" localizedSubtitle:nil userInfo:nil];
[default3DTouchManager add3DTouchCustomItemWithIconName:@"订单记录" type:@"item3" localizedTitle:@"闪电还款" localizedSubtitle:nil userInfo:nil];
[default3DTouchManager add3DTouchCustomItemWithIconName:@"邀请好友" type:@"item4" localizedTitle:@"好友分享" localizedSubtitle:nil userInfo:nil];
// 激活
[default3DTouchManager shortcutItems];
- 回调
#pragma mark - 3DTouch触发的方法
-(void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
{
//直接调用封装方法 传入"shortcutItem.type"
[default3DTouchManager actionShortcutItemType:shortcutItem.type block:^(NSUInteger idx, NSArray *array) {
//block回调idx为item序列,array为item数组,可从中userInfo
switch (idx) {
case 0:{
NSLog(@"点击第一个");
}
break;
case 1:{
NSLog(@"点击第二个");
}
break;
case 2:{
NSLog(@"点击第三个");
}
break;
case 3:{
NSLog(@"点击第四个");
}
break;
}
}];
}
2.Peek(轻按) & Pop(重按)
已封装到项目TableView基类中
- (void)viewDidLoad {
// 给Block赋值.返回值为pop方法需要跳转的viewController
[self setPreviewingBlock:^UIViewController *(MDFBaseTableViewCellModel *model) {
ZZDUserCenterModel *userModel = (ZZDUserCenterModel *)model;
if ([userModel.userCellClassName isEqualToString:More_VC] ||
[userModel.userCellClassName isEqualToString:CustomerService_TVC]) {
Base_VC *vc = [[UIStoryboard storyboardWithName:userModel.userCellClassName bundle:nil] instantiateViewControllerWithIdentifier:userModel.userCellClassName];
return vc;
} else {
if (![cSysPlist objectForKey:User_Login]) {
return nil;
} else {
UIViewController *vc = [[NSClassFromString(userModel.userCellClassName) alloc] init];
return vc;
}
}
}];
}