美文网首页程序员
3D Touch功能实现

3D Touch功能实现

作者: 一誠 | 来源:发表于2017-11-21 17:52 被阅读144次

    3D Touch

    3D Touch的触控技术,被苹果称为新一代多点触控技术。其实,就是此前在Apple Watch上采用的Force Touch,屏幕可感应不同的感压力度触控。

    3D Touch的三大模块

    1、Home Screen Quick Actions
    通过主屏幕的应用Icon,我们可以用3D Touch呼出一个菜单,进行快速定位应用功能模块相关功能的开发。

    2、peek and pop
    这个功能是一套全新的用户交互机制,在使用3D Touch时,ViewController中会有如下三个交互阶段:
    (1)提示用户这里有3D Touch的交互,会使交互控件周围模糊
    (2)继续深按,会出现预览视图
    (3)通过视图上的交互控件进行进一步交互

    3、Force Properties
    iOS9为我们提供了一个新的交互参数:力度。我们可以检测某一交互的力度值,来做相应的交互处理。例如,我们可以通过力度来控制快进的快慢,音量增加的快慢等。

    实现

    Home Screen Quick Actions

    1)系统限制每个App最多能够显示4个Action Item,其中包括静态方式和动态方式进行创建的;

    2)如果静态和动态方式同时使用的时候,给UIApplication的shortcutItems赋值的时候不会覆盖

    1、静态标签(在Info.plist文件中进行声明)
    在info.plist文件中添加如下键值
    先添加了一个UIApplicationShortcutItems的数组,这个数组中添加的元素就是对应的静态标签,在每个标签中我们需要添加一些设置的键值:
    必填项(下面两个键值是必须设置的):
    UIApplicationShortcutItemType 这个键值设置一个快捷通道类型的字符串UIApplicationShortcutItemTitle 这个键值设置标签的标题

    选填项(下面这些键值不是必须设置的) :
    UIApplicationShortcutItemSubtitle 设置标签的副标题
    UIApplicationShortcutItemIconType 设置标签Icon类型
    UIApplicationShortcutItemIconFile 设置标签的Icon文件
    UIApplicationShortcutItemUserInfo 设置信息字典(用于传值)

    2、动态标签(以动态方式创建)

    这里在应用启动的时候调用,可以根据需求动态添加

    # define kShortcutItemTypeNameSetting    @"zxl.game.setting"
    # define kShortcutItemTypeNameSahre      @"zxl.game.share"
    - (BOOL)touch_application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        
        // 分享
        NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
        NSString *appName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
        NSString * shareStr = [NSString stringWithFormat:@"分享“%@”",appName];
        UIApplicationShortcutIcon * shareIcon = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeShare];
        UIApplicationShortcutItem * shareItem = [[UIApplicationShortcutItem alloc]initWithType:kShortcutItemTypeNameSahre localizedTitle:shareStr localizedSubtitle:@"" icon:shareIcon userInfo:@{@"feel":@"今天风很大,标识很冷。"}];
        
        // 设置
        UIApplicationShortcutIcon * settingIcon = [UIApplicationShortcutIcon iconWithTemplateImageName:@"setting"];
        UIApplicationShortcutItem * settingItem = [[UIApplicationShortcutItem alloc]initWithType:kShortcutItemTypeNameSetting localizedTitle:@"设置" localizedSubtitle:@"文字设置" icon:settingIcon userInfo:nil];
        
        // 活动
        UIApplicationShortcutIcon * activityIcon = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeHome];
        UIMutableApplicationShortcutItem * mutableItem = [[UIMutableApplicationShortcutItem alloc]initWithType:kShortcutItemTypeNameActivity localizedTitle:@"活动" localizedSubtitle:@"" icon:activityIcon userInfo:@{}];
        
        NSArray * items = [NSArray arrayWithObjects:settingItem, shareItem, mutableItem, nil];
        
        // 添加到应用中 1-每次应用启动 不会覆盖
        NSArray * existingItems = [UIApplication sharedApplication].shortcutItems;
        NSArray * updatedItems = [existingItems arrayByAddingObjectsFromArray:items];
        [UIApplication sharedApplication].shortcutItems = items;
        
        return YES;
    }
    

    响应回调

    - (void)touch_application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler{
        customLog(@"Touch At --- %@",shortcutItem.type);
        // 确定根视图是window->UITabBarController->BaseNavigationController
        BaseNavigationController * navigation =   
        [self.window.rootViewController.childViewControllers firstObject];
        // 设置
        if ([shortcutItem.type isEqualToString:kShortcutItemTypeNameSetting]) {
            ConfigViewController * configVC = [ConfigViewController new];
            [navigation pushViewController:configVC animated:YES];
        }
        // 分享
        if ([shortcutItem.type isEqualToString:kShortcutItemTypeNameSahre]) {
            // 分享内容
            NSString *info = @"分享,作者:ZXL";
            UIImage *image=[UIImage imageNamed:kIconNameApp];
            NSURL *url = [NSURL URLWithString:@"https://itunes.apple.com/cn/app/%E5%BE%AE%E4%BF%A1/id414478124?mt="];
            NSArray *activities=@[info, image, url];
            UIActivity * activity = [[UIActivity alloc]init];
            UIActivityViewController * activityController = [[UIActivityViewController alloc]initWithActivityItems:activities applicationActivities:@[activity]];
            // 关闭系统的一些Activity类型,不需要的功能关掉。
            activityController.excludedActivityTypes = @[UIActivityTypePostToVimeo];
            //if iPhone
            if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
                // 设置RootViewController
                UIViewController * VC = [UIViewController new];
                self.window.rootViewController = VC;
                self.window.backgroundColor = [UIColor orangeColor];
                [VC presentViewController:activityController animated:YES completion:nil];
            }
            //if iPad
            else {
                // 可以添加到UIPopoverController中的contentViewController
                //UIBarButtonItem *shareBarButtonItem = self.navigationItem.leftBarButtonItem;
                //UIPopoverController *pop = [[UIPopoverController alloc] initWithContentViewController:controller];
                //[pop presentPopoverFromBarButtonItem:shareBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
            }
            
            // 回调
            activityController.completionWithItemsHandler = ^(UIActivityType  _Nullable activityType, BOOL completed, NSArray * _Nullable returnedItems, NSError * _Nullable activityError) {
                // 取消 -- completed=NO 分享完成-好的 --- completed=YES
                if (completed) {
                    customLog(@"completed --- %@",activityType);
                }
                else{
                    customLog(@"completed --- %@",activityType);
                }
            };
        }
    
    }
    

    peek and pop

    注册预览视图的代理和来源视图

    // Registers a view controller to participate with 3D Touch preview (peek) and commit (pop)
    if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
    
    [self registerForPreviewingWithDelegate:self sourceView:self.button];
    }
    

    轻压的时候调用

    - (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location{*
        PreviewViewController * previewVC = [[PreviewViewController alloc]init];
        previewVC.view.backgroundColor = [UIColor whiteColor];
        return previewVC;
    }
    

    继续重压显示下一个视图

    - (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit{
        viewControllerToCommit.view.backgroundColor = [UIColor orangeColor];
        [self showViewController:viewControllerToCommit sender:self];
    }
    

    pop功能-在PreviewViewController中实现方法

    - (NSArray<id<UIPreviewActionItem>> *)previewActionItems{
        UIPreviewAction * touchAction = [UIPreviewAction actionWithTitle:@"3D Touch" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction ]* _Nonnull action, UIViewController * _Nonnull previewViewController) {
        
        
        UIAlertController * alertVC = [UIAlertController alertControllerWithTitle:@"提示" message:@"点击了 3D Touch" preferredStyle:UIAlertControllerStyleActionSheet];
        
        UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleCancel handler:^(UIAlertAction ]* _Nonnull action) {
        
        }];
        [alertVC addAction:cancelAction];
        
        [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertVC animated:YES completion:nil];
        }];
        
        return @[touchAction];
    }
    

    在显示预览视图时向上滑动出现的视图UIPreviewAction,然后点击按钮出现弹框。

    Force Properties

    在iOS 9中,UITouch类支持3D触摸应用程序定制实现了两个新的属性:force 和 maximumpossibleforce 。

    // Force of the touch, where 1.0 represents the force of an average touch  
    @property(nonatomic,readonly) CGFloat force NS_AVAILABLE_IOS(9_0);  
    // Maximum possible force with this input mechanism  
    @property(nonatomic,readonly) CGFloat maximumPossibleForce NS_AVAILABLE_IOS(9_0);  
    
    #pragma mark 获取压力的大小非常简单,我们可以通过UITouch类中的一些属性来完成
    //我这里 只做了一个简单的  压力感应示例,如需更复杂的效果,可以自行编制。
    - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        //宣告一个UITouch的指标来存放事件触发时所撷取到的状态
        UITouch *touch = [[event allTouches] anyObject];
        self.forceLabel.text = [NSString stringWithFormat:@"当前压力值为: %f",touch.force];
       customLog(@"最大压力值  %f",touch.maximumPossibleForce);// 最大压力值  6.666667
        if (touch.force>0.2)
        {
            self.forceLabel.font = [UIFont systemFontOfSize:20*touch.force];
            self.forceLabel.textColor = RGBColor(255*touch.force/6.5, 0, 0);
        }
    }
    

    参考:
    iOS开发之3D Touch
    UIActivity View Controller
    iOS9 3D Touch 标签菜单 peek and pop force 压力触控 功能开发高级版教程

    相关文章

      网友评论

        本文标题:3D Touch功能实现

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