3D Touch

作者: 啃手高手 | 来源:发表于2016-01-15 19:46 被阅读727次

    苹果在iPhone6s和iPhone6s Plus中加入了3D Touch技术,其实Apple Watch的屏幕上很早就用到这一技术了,并不新颖,由于本人刚买的iPhone6s,所以试玩一下。没有6S和6SP的小伙伴也不要抱怨,好东西来了:SBShortcutMenuSimulator,能让模拟器支持HomeScreen Quick Action。赶紧去尝试吧~

    SBShortcutMenuSimulator

    1.编译:在终端依次输入下面的命令

    git clone https://github.com/DeskConnect/SBShortcutMenuSimulator.git
    
    cd SBShortcutMenuSimulator
    
    make
    

    2.让SpringBoard支持SBShortcutMenuSimulator

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

    3.预览:

    echo 'com.apple.mobilecal' | nc 127.0.0.1 8000
    

    注意:'com.apple.mobilecal' 是系统自带日历的BundleID,记得要换成自己的喔~

    Home Screen Quick Action

    预览图1.png
    创建Quick Action分为静态和动态两种方式:动态就是代码实现,但是程序要运行一次才会有效果;静态就是通过程序的Info.plist文件来设置。
    动态实现的代码如下:
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
        UIApplicationShortcutIcon *addIcon = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeAdd];
        UIApplicationShortcutIcon *shareIcon = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeShare];
        UIApplicationShortcutIcon *searchIcon = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeSearch];
        
        UIApplicationShortcutItem *item0 = [[UIApplicationShortcutItem alloc] initWithType:@"1" localizedTitle:@"添加" localizedSubtitle:nil icon:addIcon userInfo:nil];
        UIApplicationShortcutItem *item1 = [[UIApplicationShortcutItem alloc] initWithType:@"2" localizedTitle:@"分享" localizedSubtitle:nil icon:shareIcon userInfo:nil];
        UIApplicationShortcutItem *item2 = [[UIApplicationShortcutItem alloc] initWithType:@"3" localizedTitle:@"搜索" localizedSubtitle:nil icon:searchIcon userInfo:nil];
        
        NSArray *itemArray = [NSArray arrayWithObjects:item0,item1,item2, nil];
        
        [[UIApplication sharedApplication] setShortcutItems:itemArray];
        
        return YES;
    }
    

    响应回调:

    - (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
    {
        if ([shortcutItem.localizedTitle isEqualToString:@"1"]) {
            NSLog(@"添加");
        }else if ([shortcutItem.localizedTitle isEqualToString:@"2"]){
            NSLog(@"分享");
        }else if([shortcutItem.localizedTitle isEqualToString:@"3"]){
            NSLog(@"搜索");
        }
    }
    

    特别注意:
    **1.每个APP最大支持4个Action Item;
    2.静态动态同时设置的时候,不会覆盖;
    **

    UIKit Peek & Pop

    短时间按压屏幕可以实现预览,这就是peek,再用力按压,直接进到另一个页面,就是Pop了。要实现Peek和Pop功能,首先要判断设备是否支持3D Touch功能,然后遵守UIViewControllerPreviewingDelegate,并实现它仅有的两个方法:


    delegateMethods.png

    监测3D Touch:

    我们可以在viewWillAppear方法里检测:

    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        
        if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
            NSLog(@"3D Touch 可用");
        }else if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityUnavailable){
            NSLog(@"3D Touch 不可用");
        }else{
            NSLog(@"3D Touch 未检测");
        }
    }
    

    如果程序内修改了3D Touch设置,我们通过traitCollectionDidChange来检测:

    //生命周期内可以通过这个方法重新检测3D Touch功能
    - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
    {
        if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
            //功能可用的情况下进行注册
            [self registerForPreviewingWithDelegate:self sourceView:self.tableView];
            NSLog(@"已注册");
        }else{
            NSLog(@"没注册");
        }
    }
    

    实现UIViewControllerPreviewingDelegate的代理方法:

    #pragma mark - viewcontrollerPrewingdelegate
    //Peek 代理方法:
    - (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location
    {
        //防止重复弹出
        if ([self.presentationController isKindOfClass:[PeekViewController class]]) {
            return nil;
        }else{
            //找到正在按压的cell,从而着重显示,
            NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
            if (!cell) {
                return nil;
            }
            previewingContext.sourceRect = cell.frame;
            PeekViewController *peekVC = [[PeekViewController alloc] initWithNibName:@"PeekViewController" bundle:nil];
            peekVC.preferredContentSize = CGSizeMake(0, 0);
            return peekVC;
        }
    }
    //Pop 代理方法:
    - (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit
    {
        PeekViewController *peekVC = [[PeekViewController alloc] initWithNibName:@"PeekViewController" bundle:nil];
        peekVC.sendData = @"from POP";
        [self presentViewController:peekVC animated:YES completion:nil];   
    }
    

    你可能见过类似的效果:


    peek_quick_actions_2x.png

    那么底下的这些选项又是怎么实现的呢?这个呢,需要在目标控制器里设置,也就是说,如果你的A控制器实现了上面的代理方法,然后想跳到B控制器,那么这些选项的设置就要在B控制器里通过UIPreviewAction来设置。

    //初始化preViewActionsItems
    - (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(@"删除");
        }];
        NSArray *previewActionItemsArray = @[action0,action1];
        return previewActionItemsArray;
    }
    

    OK~终于大功告成了。

    最后

    推荐文章
    源码地址

    相关文章

      网友评论

        本文标题:3D Touch

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