美文网首页
iOS之3D Touch

iOS之3D Touch

作者: 柚子_童鞋 | 来源:发表于2017-02-09 14:52 被阅读0次

之前在玩手机的时候,无意间长摁去年的前年的软件时,竟然不支持3DTouch,于是想着有空学学3DTouch。在这篇文章中,我将参照官方API来整理一下3DTouch的一些使用方法和注意事项。

3D Touch简介:

3D Touch是一种立体触控技术,被苹果称为新一代多点触控技术,是在Apple Watch上采用的Force Touch,屏幕可感应不同的感压力度触控。3D Touch,苹果iPhone 6s上的新功能,看起来类似 PC 上的右键。有Peek Pop 两种新手势。
2015年9月10日,苹果在新品发布会上宣布了3D-Touch功能。 2016年6月13日,苹果开发者大会WWDC在旧金山召开,会议宣布可以在待机画面用3D Touch操作通知。

在官方文档中,介绍了一下三点:

  • Home screen quick action
  • Peek and pop
  • UITouch force properties

接下来我们将逐一学习:

1.Home screen quick action

其实现方式可以分为Static quick actionsDynamic quick actions

1.1 Static quick actions

Static quick actions--静态添加快捷菜单,通过操作plist文件来实现:在plist文件中添加相对应的key-value键值对(由于3DTuch功能不是APP的刚性需求,所以系统的plist文件并没有附带);

首先在plist文件中添加一个UIApplicationShortcutItem数组,在该数组中添加字典,字典内键值对如下:
-UIApplicationShortcutItemType 必填! type为string类型,决定了点击菜单后跳段到哪一个界面;
-UIApplicationShortcutItemTitle 必填! title为string类型,菜单的标题
-UIApplicationShortcutItemSubtitle subtitle为string类型,菜单的副标题
-UIApplicationShortcutItemIconType 菜单左侧的icon系统类型,系统内有29种样式,枚举的前6种是通用的,后边的23种是iOS9.1之后新增的;详见API文档
-UIApplicationShortcutItemIconFile 如果系统的29种icon样式不能满足我们的需求,我们也可以自定义icon样式。添加UI提供的icon,填写icon的名字即可;

下面通过两张截图来对比键值对添加之前和添加之后的plist文件:
未添加键值对的plist文件截图如下:

未添加键值对

已添加键值对的plist文件截图如下:


已添加键值对

1.2 Dynamic quick actions

Dynamic quick actions--动态添加快捷菜单。在了解了Static quick actions之后Dynamic quick actions就简单了,Dynamic quick actions就是我们通过代码来添加快捷菜单:

//在`didFinishLaunchingWithOptions`方法内部添加代码
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    /**
     * 添加快捷菜单
     */
    UIApplicationShortcutItem *item0 = [[UIApplicationShortcutItem alloc]initWithType:@"" localizedTitle:@"列表0"];
    
    UIApplicationShortcutIcon *icon1 = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeShare];
    UIApplicationShortcutItem *item1 = [[UIApplicationShortcutItem alloc]initWithType:@"" localizedTitle:@"列表1" localizedSubtitle:@"列表1-副标题" icon:icon1 userInfo:nil];
    
    UIApplicationShortcutIcon *icon2 = [UIApplicationShortcutIcon iconWithTemplateImageName:@"scan"];
    UIApplicationShortcutItem *item2 = [[UIApplicationShortcutItem alloc]initWithType:@"" localizedTitle:@"列表2"localizedSubtitle:@"列表2-副标题" icon:icon2 userInfo:nil];
    
    [UIApplication sharedApplication].shortcutItems = @[item0,item1,item2];
    
    return YES;
}

添加完毕之后长摁APP的效果图如下:

长摁效果图

写到这里有心的同学可能注意到type的值是空的,那么点击了“列表0”或者“列表1”之后会触发什么响应呢?以及响应的方法是哪个呢?不要急静静的往下看:

 /**
     * 动态添加菜单列表
     */
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    UIApplicationShortcutIcon *icon1 = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeShare];
    UIApplicationShortcutItem *item1 = [[UIApplicationShortcutItem alloc]initWithType:@"share" localizedTitle:@"分享" localizedSubtitle:@"列表1-副标题" icon:icon1 userInfo:nil];
    
    UIApplicationShortcutIcon *icon2 = [UIApplicationShortcutIcon iconWithTemplateImageName:@"scan"];
    UIApplicationShortcutItem *item2 = [[UIApplicationShortcutItem alloc]initWithType:@"scan" localizedTitle:@"扫一扫"localizedSubtitle:@"列表2-副标题" icon:icon2 userInfo:nil];
    [UIApplication sharedApplication].shortcutItems = @[item1,item2];
    
    return YES;
}
    /**
     * 菜单item被点击时,会触发下面的方法
     */
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
{
    UITabBarController *tabVC = (UITabBarController *)self.window.rootViewController;
    //为item指定跳转界面(通过type值或者title值来绑定界面)
    if ([shortcutItem.type isEqualToString:@"share"])
    {
        tabVC.selectedIndex = 0;//分享界面
    }
    else
    {
        tabVC.selectedIndex = 1;//扫一扫界面
    }
}

注意点(如何应对重度强迫症的产品经理):

  • 快捷菜单弹出方向:当你的APP图标位于手机桌面的上半部分,快捷菜单是向下弹出的;同理APP图标位于下半部分则快捷菜单是向上弹出的;
  • 菜单的Icon位置:当你的APP图标位于手机桌面的左半部分,icon图标位于菜单最左侧;同理APP图标位于右半部分则icon图标位于菜单最右侧;

2.Peek and pop

2.1 peek--轻摁预览

在微信的聊天列表里,我们轻摁与某一个朋友的聊天(PS:6s之前的手机屏幕摁破别打我),在屏幕上就会弹出一个呈现聊天内容的界面----这个场景就是官方所说的peek的一个应用场景;

在讲解之前我们先来思考下面的几个问题:

  • Q1.cell轻摁可以弹出预览界面,那么在配置cell的cellForRow方法内部是不是有所不同?
  • Q2.轻摁cell弹出的预览界面,是不是应该写在didSelectedRow方法内部呢?
  • Q3.轻摁cell弹出的预览界面被向上或向下拖拽之后,触发的“标为未读”、”“删除”是在当前界面配置还是在预览界面配置呢?

下面通过一个小demo结合代码来讲解:
demo功能:在tableView页面上有一个网址的列表,轻摁之后弹出网址预览界面;弹出预览界面之后重摁则跳转到详情界面;

基础界面tableView的搭建代码就省略了,直接上关键点:
第一步:要让cell有按压效果,需要在cellForRow方法内部注册cell支持预览的协议:UIViewControllerPreviewingDelegate(自然TableviewController要遵守该协议)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ......
    /**
     *  关键语句:告知系统该cell按压有peek效果
     */
    [self registerForPreviewingWithDelegate:self sourceView:cell];
    
    return cell;
}

第二步:cell支持按压,那么按压之后呈现什么控制器呢?UIViewControllerPreviewingDelegate的第一个方法

- (nullable UIViewController *)previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location

就是解决这个问题(方法的返回值为UIViewController

- (nullable UIViewController *)previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location
{
    WebViewController *webVC = [[WebViewController alloc]init];
    //根据location来获取到当前所点击的cell的row
    location = [self.tableView convertPoint:location fromView:[previewingContext sourceView]];//转换参考系
    NSIndexPath *path = [self.tableView indexPathForRowAtPoint:location];
    
    webVC.url = self.dataArray[path.row][@"html"];
    return webVC;
}

注意点:上边方法中的location是以cell为sourceView-参考系得到的坐标,而我们所需要的是以tableView为参考系的坐标,所以要对location进行转换;--下接2.2

2.2 pop--重摁跳转

第三步:在预览界面已呈现之后,大力摁压跳转到详情界面是在UIViewControllerPreviewingDelegate的另一个方法内实现

- (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit
- {
    viewControllerToCommit.hidesBottomBarWhenPushed = YES;
    [self.navigationController pushViewController:viewControllerToCommit animated:YES];
}

接下来,拖拽预览界面触发响应的代码是要在详情控制器里来书写;

- (NSArray<id<UIPreviewActionItem>> *)previewActionItems
{
    //创建赞操作
    UIPreviewAction *item0 = [UIPreviewAction actionWithTitle:@"赞" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        //此处block代码块为点击“赞”操作的响应代码
        NSLog(@"点赞---------------------");
    }];
    
    //创建举报操作
    UIPreviewAction *item1 = [UIPreviewAction actionWithTitle:@"举报" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"举报=====================");
    }];
    
    return @[item0,item1];
}

下面附上效果图:

列表 轻摁预览图

3.UITouch force properties

Force properties是在iOS 9.0之后UITouch新增的一个属性,简单来说系统可以扑捉到手指在屏幕的压力值(开个脑洞:会不会有哪个土豪搞n多个6s来测体重?)
关于Force properties比较简单,但是通常会和贝赛尔曲线结合起来做一些涂鸦画板之类的APP,这里就不再赘述了。我只是检测了一下压力的峰值:

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = touches.anyObject;
    NSLog(@"压力值为:%f",touch.force);
}
打印压力峰值

OK,关于3D Touch就这么多了附上官方文档,有什么不对的希望指出来,共同进步。

相关文章

网友评论

      本文标题:iOS之3D Touch

      本文链接:https://www.haomeiwen.com/subject/jjwiittx.html