3DTouch那点事

作者: zhanming | 来源:发表于2016-06-13 14:17 被阅读848次

    公司之前在新的版本中添加了3DTouch,今天就总结出来方面大家参考和查阅

    一、3D Touch 的Quick Action实现

    Quick Action有两种方式:静态和动态,静态是在plist文件中申明,动态则是在代码中注册,系统支持两者同时存在。但是系统限制每个app最多显示4个快捷图标,包括静态和动态。

    第一种方式动态添加入口标签

    -(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    

    方法中实现添加和分享的入口,代码如下 :

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
        // 创建标签的ICON图标。
        UIApplicationShortcutIcon *firstItemIcon = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeAdd];
        // 创建一个标签,并配置相关属性。
        UIMutableApplicationShortcutItem *firstItem = [[UIMutableApplicationShortcutItem alloc]initWithType:@"First" localizedTitle:@"添加" localizedSubtitle:nil icon:firstItemIcon userInfo:nil];
        UIApplicationShortcutIcon *secondItemIcon = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeShare];
        UIMutableApplicationShortcutItem *secondItem = [[UIMutableApplicationShortcutItem alloc]initWithType:@"Second" localizedTitle:@"分享" localizedSubtitle:nil icon:secondItemIcon userInfo:nil];
        
        // 自定义创建标签的ICON图标。
        UIApplicationShortcutIcon *thirdItemIcon = [UIApplicationShortcutIcon iconWithTemplateImageName:@""];
        UIMutableApplicationShortcutItem *thirdItem = [[UIMutableApplicationShortcutItem alloc]initWithType:@"Third" localizedTitle:@"自定义" localizedSubtitle:nil icon:thirdItemIcon userInfo:nil];
        application.shortcutItems = @[firstItem,secondItem,thirdItem];
        return YES;
    }
    

    系统提供的图标样式

    typedef NS_ENUM(NSInteger, UIApplicationShortcutIconType) { UIApplicationShortcutIconTypeCompose, 
    UIApplicationShortcutIconTypePlay, 
    UIApplicationShortcutIconTypePause, 
    UIApplicationShortcutIconTypeAdd, 
    UIApplicationShortcutIconTypeLocation, 
    UIApplicationShortcutIconTypeSearch, 
    UIApplicationShortcutIconTypeShare, 
    UIApplicationShortcutIconTypeProhibit NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeContact NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeHome NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeMarkLocation NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeFavorite NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeLove NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeCloud NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeInvitation NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeConfirmation NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeMail NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeMessage NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeDate NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeTime NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeCapturePhoto NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeCaptureVideo NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeTask NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeTaskCompleted NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeAlarm NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeBookmark NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeShuffle NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeAudio NS_ENUM_AVAILABLE_IOS(9_1), 
    UIApplicationShortcutIconTypeUpdate NS_ENUM_AVAILABLE_IOS(9_1)
    } 
    NS_ENUM_AVAILABLE_IOS(9_0) __TVOS_PROHIBITED;
    

    2.实现这个方法

    -(void)application:(UIApplication *)application performActionForShortcutItem:
    (UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
    

    在这个方法中处理添加和分享的事件,代码如下:

    -(void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
    { 
       if ([shortcutItem.type isEqual:@"add"])
           { NSLog(@"执行添加事件"); }
       else if([shortcutItem.type isEqual:@"share"])
           { NSLog(@"执行分享的操作 ");}
    }
    
    
    

    第二种方式静态添加入口标签

    静态添加入口标签不需要写代码,只需要在info.plist文件中添加相关功能设置即可。
    静态的方法加入:
    即在plist文件中加入UIApplicationShortcutItems标签,标签类型为NSArray,根据需要可以添加四个不同的子标签。类型为NSDictionary。然后加如所需键值对:
    必填项(下面两个键值是必须设置的):

    UIApplicationShortcutItemType 这个键值设置一个快捷通道类型的字符串
    UIApplicationShortcutItemTitle 这个键值设置标签的标题

    选填项(下面这些键值不是必须设置的):

    UIApplicationShortcutItemSubtitle 设置标签的副标题
    UIApplicationShortcutItemIconType 设置标签的图标样式,系统提供了29中样式的图标
    UIApplicationShortcutItemIconFile 设置自定义标签图片文件的路径
    UIApplicationShortcutItemUserInfo 设置用户信息,是一个字典类型,可以用来传值

    UIApplicationShortcutItems
     <key>UIApplicationShortcutItems</key>
     <array>
      <dict>
               <key>UIApplicationShortcutItemType</key>
               <string>First</string>
               <key>UIApplicationShortcutItemTitle</key>
               <string>添加</string>
               <key>UIApplicationShortcutItemIconType</key>
               <string>UIApplicationShortcutIconTypeFavorite</string>
    
       <string>UIApplicationShortcutIconTypeShare</string>
      </dict>
       <dict>
                <key>UIApplicationShortcutItemType</key>
                <string>Second</string>
                <key>UIApplicationShortcutItemTitle</key>
                <string>帅哥</string>
                <key>UIApplicationShortcutItemIconType</key>
                <string>UIApplicationShortcutIconTypeFavorite</string>
       </dict>
     </array>
    
    IMG_0046.PNG

    二、3D Touch 的Peek和Pop实现

    3D Touch 的Peek和Pop实现

    使用步骤:

    1. 给Cell注册3DTouch
    2. 遵守协议<UIViewControllerPreviewingDelegate>
    3. 实现协议方法

    第1步:给Cell注册3DTouch

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        MyTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"zhan" forIndexPath:indexPath];
        //判断是否支持3DTouch
        if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
            //注册Cell支持3DTouch,并设置代理
            [self registerForPreviewingWithDelegate:self sourceView:cell];
        }
        
        return cell;
        
    }
    
    

    第2步:遵守协议<UIViewControllerPreviewingDelegate>

    @interface ViewController ()<UITableViewDelegate,UITableViewDataSource,UIViewControllerPreviewingDelegate>
    @property (weak, nonatomic) IBOutlet UITableView *myTableView;
    
    

    第3步:实现协议方法

    -(UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location
    {
        //获取sourceView
        MyTableViewCell *cell = (MyTableViewCell *)[previewingContext sourceView];
        //设置弹出预览的位置(peek是从哪个位置弹出)
        [previewingContext setSourceRect:cell.bounds];
        //设置弹框的View.
        UIStoryboard *sb=[UIStoryboard storyboardWithName:@"Main" bundle:nil];
        
        DetailViewController *detailVC = [sb instantiateViewControllerWithIdentifier:@"DetailViewController"];
        //设置弹出peek的高度(设置宽度是没有效果的)
        detailVC.preferredContentSize = CGSizeMake(0, self.view.bounds.size.height*0.6);
        //取出Cell的模型传递给详情控制器.
        
        return detailVC;
        //设置标题
        //detailVC.title = @"帅";
        //在这里想弹一个带有导航条的控制器,控制器里面包装一个导航条.直接返回导航控制器.那么就会peek出一个导航控制器.
    
        //return [[UINavigationController alloc] initWithRootViewController:detailVC];
    }
    
    QQ20160613-1.png
    弹框出现后,继续重按时调用
    //弹框出现后,继续重按时调用 //viewControllerToCommit:就是上面return的控制器. 
     - (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UINavigationController *)viewControllerToCommit{ 
    
    
       //*******如果上面返回的是导航控制器*********
        
        //获取导航控制器的根控制器.因为当前已经是一个导航控制器了,不能再继续push一个导航控制器,所以要先获取peek的导航控制器里面的根控制器.
        //然后再拿当前的控制器把获取的控制器push进去.
        
        //DetailViewController *detailVC = (DetailViewController*)viewControllerToCommit.childViewControllers.lastObject;
        
        //*******如果上面返回的是导航控制器*********
        
        DetailViewController *detailVC = (DetailViewController*)viewControllerToCommit;//.childViewControllers.lastObject;
        [self.navigationController pushViewController:detailVC animated:YES];
        
        //使用show和push是一样的效果
        //[self showViewController:viewControllerToCommit sender:self];
    

    弹窗出现后,向上滑动,会出现类似ActionSheet的控件.
    实现该效果必须得要是在previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location return回去那个控制器当中实现以下方法,(我们这里peek出来的是DetailViewController,所以必须得要在DetailViewController中实现该方法)

    -(NSArray<id<UIPreviewActionItem>> *)previewActionItems
    {
        //弹出的第一个按钮
        UIPreviewAction *action0 = [UIPreviewAction actionWithTitle:@"收藏" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
            NSLog(@"收藏");
            
        }];
        
        UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"点赞" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
            NSLog(@"点赞");
        }];
        
        UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"试试" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
            NSLog(@"试试");
        }];
        UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"星星" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
            NSLog(@"星星");
        }];
        
        //该按钮可以是一个组,点击该组时,跳到组里面的按钮.
        UIPreviewActionGroup *actionGroup = [UIPreviewActionGroup actionGroupWithTitle:@"组" style:UIPreviewActionStyleSelected actions:@[action2, action3]];
        //直接返回数组.
        return  @[action0,action1,actionGroup];
    }
    
    IMG_0050.PNG

    三、通过模拟器进行调试

    使用SBShortcutMenuSimulator来配置模拟器,使模拟器支持3D Touch
    在终端中按顺序输入以下命令:

    1.git clone https://github.com/DeskConnect/SBShortcutMenuSimulator.git

    2.cd SBShortcutMenuSimulator

    3.make

    然后打开刚才写好的程序 运行一下打开模拟器,再去终端中按顺序输入一下命令:

    1.xcrun simctl spawn booted launchctl debug system/com.apple.SpringBoard --environment DYLD_INSERT_LIBRARIES=$PWD/SBShortcutMenuSimulator.dylib

    2.xcrun simctl spawn booted launchctl stop com.apple.SpringBoard

    3.echo 'com.apple.mobilecal' | nc 127.0.0.1 8000
    注意: 'com.apple.mobilecal' ''里边写的是自己项目的Bundle identifier. 这行命令就是要让模拟器显示出3D Touch,每次想要显示快速入口只要重复操作即可

    echo 'com.zhanming.text.-DTouch-OC
    ' | nc 127.0.0.1 8000

    具体代码放在了GitHub上大家可以下载。
    如果感觉这篇文章对您有所帮助,顺手点个喜欢,谢谢啦

    相关文章

      网友评论

      本文标题:3DTouch那点事

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