最近闲来,研究了下3D Touch 方面的功能,自己来做一个简单的总结。如果有研究这方面的朋友们可以一起来讨论下。
3D Touch 三大功能
1. Home Screen Quick Actions
2. Peek、Pop
3. Force Properties
3D Touch 实现
3D Touch实现起来不算难,就是实现需要硬件的支持,只能在6s/6s p等上面可以测试体验,模拟器是不能的, ShortcutItem主要由Item类型,主标题,副标题、图标,还可添加一些附加信息,每个App最多添加4个快捷键。
操作 - 用手指用力按压App的icon,会出现类似的菜单快捷键(ShortcutItem),附上Demo的效果图(Home Screen Quick Actions):
1. Home Screen Quick Actions
生成菜单 - 按压icon弹出快捷键的实现方法分为静态菜单、动态菜单等2种。
. 静态菜单 - 配置项目的.plist文件
目前Xcode版本的plist文件还没对应的key来获取,则 需要用户自己来手动输入UIApplicationShortcutItems(NSArray类型 - 内部都是字典- 对应 - 每个item);字典内一些key的解释:
UIApplicationShrtcutItemSubtitle (副标题)
UIApplicationShrtcutItemTitle( 必填)(可监听该项判断用户是从哪一个标签进入App)
UIApplicationShortcutItemType( 必填)(可监听该项判断用户是从哪一个标签进入App)
UIApplicationShrtcutItemIconType(图标)(系统提供了29种样式的图标)
UIApplicationShrtcutItemIconFile(自定义图片的文件路径)- 直接传入图片的名字即可
注意:若是设置了自定义的图片 则系统的不再生效
. 动态菜单 - 代码实现快捷菜单,动态添加方法需要代码执行一次,因此静态方法比动态方法优先加载
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/**
* 3d Touch
*/
/**
* iconWithType 系统的icon
*/
UIApplicationShortcutIcon *icon0 = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeHome];
UIMutableApplicationShortcutItem *item0 = [[UIMutableApplicationShortcutItem alloc] initWithType:@"主页" localizedTitle:@"主页" localizedSubtitle:nil icon:icon0 userInfo:nil];
UIApplicationShortcutIcon *icon1 = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeBookmark];
UIMutableApplicationShortcutItem *item1 = [[UIMutableApplicationShortcutItem alloc] initWithType:@"阅读" localizedTitle:@"阅读" localizedSubtitle:nil icon:icon1 userInfo:nil];
UIApplicationShortcutIcon *icon2 = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeAudio];
UIMutableApplicationShortcutItem *item2 = [[UIMutableApplicationShortcutItem alloc] initWithType:@"电台" localizedTitle:@"电台" localizedSubtitle:nil icon:icon2 userInfo:nil];
UIApplicationShortcutIcon *icon3 = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeContact];
UIMutableApplicationShortcutItem *item3 = [[UIMutableApplicationShortcutItem alloc] initWithType:@"我" localizedTitle:@"我" localizedSubtitle:nil icon:icon3 userInfo:nil];
[UIApplication sharedApplication].shortcutItems = @[item0,item1,item2,item3];
}
实现点击菜单ShortcutItem对应的item跳转到对应的页面
-(void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler{
UITabBarController *tabBarVC = (UITabBarController *)self.window.rootViewController;
if ([shortcutItem.localizedTitle isEqualToString:@"主页"]) {
tabBarVC.selectedIndex = 0;
}else if ([shortcutItem.localizedTitle isEqualToString:@"阅读"]){
tabBarVC.selectedIndex = 1;
}else if ([shortcutItem.localizedTitle isEqualToString:@"电台"]){
tabBarVC.selectedIndex = 2;
}else {
tabBarVC.selectedIndex = 3;
}
}
2. Peek、Pop
经过授权的应用视图控制器可响应用户不同的按压力量,随着按压力量的增加,会有三个交互阶段:
1.暗示预览功能可用,会有一个虚化的效果
2.Peek:重按一下后出现的预览,展示预览的视图以及快捷菜单
3.Pop:跳转到预览的视图控制器,是在Peek后进一步按压后进入预览的视图控制器
首先需遵守代理协议UIViewControllerPreviewingDelegate
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
/**
* UIForceTouchCapability 检测是否支持3D Touch
*/
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
//支持3D Touch
//系统所有cell可实现预览(peek)
[self registerForPreviewingWithDelegate:self sourceView:cell]; //注册cell
}
}
具体实现
/**
* <#Description#>
*
* @param previewingContext 被预览的视图控制器的内容对象
* @param location 源视图的左边系上的触摸点的坐标位置
*
* @return
*调用时间:进入peek预览阶段时会调用这个方法。
*作用:返回一个配置好的以供预览的视图控制器。
*需要的操作:把源视图坐标系上的点转换为当前控制器的视图上的点。
*返回一个控制器。
*/
-(UIViewController *)previewingContext:(id)previewingContext viewControllerForLocation:(CGPoint)location{
// //将触摸点的坐标转化为tableView坐标系上的坐标点
// location = [self.tableView convertPoint:location toView:[previewingContext sourceView]];
// //根据触摸点获取触摸的cell的indexPath
// NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
// // 根据indexPath对被peek的控制器进行配置
// UITableViewController *peekViewController =[[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped];
// peekViewController.model = self.pictureMArray[indexPath.row];
// return peekViewController;
//=====================
//防止重复加入 非常重要
if ([self.presentedViewController isKindOfClass:[ImageViewController class]]) {
return nil;
}else{
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Picture" bundle:nil];
ImageViewController *imageVC = [sb instantiateViewControllerWithIdentifier:@"ImageViewController"];
//转化坐标
CGPoint location11 = [self.tableView convertPoint:location fromView:[previewingContext sourceView]];
//根据location 获取位置
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location11];
// NSLog(@"--------------------%ld",(long)indexPath.row);
//根据位置获取字典传入控制器
JWPictureListcomModel *model = self.pictureComMArray[indexPath.row];
imageVC.imageUrl = model.GroupModel.url_listModel.Url_listModel.url;
imageVC.W = model.GroupModel.url_listModel.width;
imageVC.H = model.GroupModel.url_listModel.height;
return imageVC;
}
}
-(void)previewingContext:(id)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
viewControllerToCommit.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:viewControllerToCommit animated:YES];
}
在还没触发Pop,上划预览视图,则下面可去设置一些选项
- (NSArray> *)previewActionItems{
// 生成UIPreviewAction
//拷贝图片 可以直接在微信中发送个好友
UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"拷贝" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
UIPasteboard *pboard = [UIPasteboard generalPasteboard];
pboard.image = self.imageView.image;
// pboard.URL = [NSURL URLWithString:self.imageUrl];
// [UIApplication sharedApplication].applicationIconBadgeNumber=0;
}];
//存储图片 直接保存到相册
UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"存储图片" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
UIImageWriteToSavedPhotosAlbum(self.imageView.image, self, @selector(image: didFinishSavingWithError: contextInfo:), nil);
}];
NSArray *actions = @[action1, action2];
return actions;
}
//相册保存是否成功的信息反馈
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
if (error == nil) {
[MBProgressHUD showSuccess:@"保存成功"];
}else{
[MBProgressHUD showError:@"保存失败"];
}
}