【iOS Framework】新特性3DTouch

一、按压图标 弹出菜单

 

WeChat_1469066154.jpeg

像上图那样,按压图标 弹出菜单。这是应用最多的场景。那么如何实现呢?有两种方法:git

 

静态的:

在info.plist添加以下键值对,每个Item表明一个标签按钮,你能够添加标题,副标题,可使用系统图标,也可使用你本身的图片资源做为图标,只需添加你的图片名称便可。下面列举经常使用的键值对:github

/*
     经常使用键值对
     
     UIApplicationShortcutItemTitle  标题

     UIApplicationShortcutItemType   类型能够设置标识符
   
     UIApplicationShortcutItemIconType   图标类型,可设置系统图标样式

     UIApplicationShortcutItemSubtitle   副标题

     UIApplicationShortcutItemUserInfo   可存放一个字典,经过这个传值

*/

屏幕快照 2016-07-21 上午10.06.28.png

 

​下面列举系统支持的图标类型,根据你的需求来获取吧。数组

屏幕快照 2016-07-21 上午10.04.12.png

 

动态的:

//建立图标3DTouch 菜单
- (void)codeAddItems{
    
    //系统风格的icon
    UIApplicationShortcutIcon *share = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeShare];
    
    //使用自定义图标
    UIApplicationShortcutIcon *saoyisao = [UIApplicationShortcutIcon iconWithTemplateImageName:@"erweima"];
    
    //建立快捷选项 type 标识符
    UIApplicationShortcutItem * item1 = [[UIApplicationShortcutItem alloc]initWithType:@"com.occode.app.share" localizedTitle:@"分享" localizedSubtitle:@"分享副标题" icon:share userInfo:nil];
    
    UIApplicationShortcutItem * item2 = [[UIApplicationShortcutItem alloc]initWithType:@"com.mycompany.app.saoyisao" localizedTitle:@"扫一扫" localizedSubtitle:@"扫一扫副标题" icon:saoyisao userInfo:nil];
    
    //添加到快捷选项数组
    [UIApplication sharedApplication].shortcutItems = @[item1,item2];
    
}

 

运行效果:浏览器

 

小结:

动态标签不能覆盖静态标签,但能够追加,最多支持四个标签。微信

 

点击标签后的响应

app未启动时:

点击后,咱们能够从launchOptions中捕捉到UIApplicationShortcutItem,从而根据其类型来处理咱们想要的结果:app

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

 

捕捉UIApplicationShortcutItem,此时咱们须要return NO而不是YES;函数

//若是是从快捷选项标签启动app,则根据不一样标识执行不一样操做,而后返回NO
UIApplicationShortcutItem *shortcutItem = [launchOptions valueForKey:UIApplicationLaunchOptionsShortcutItemKey];
if (shortcutItem) {
    //根据Item的类型来进一步处理
   [self showForItem:shortcutItem];
    return NO;
}

 

app在后台时:

须要实现下面这个函数:测试

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

 

具体实现以下: 

//若是app在后台,经过快捷选项标签进入app,则调用该方法
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler {

    //判断先前咱们设置的快捷选项标签惟一标识,根据不一样标识执行不一样操做
    [self showForItem:shortcutItem];
    
    if (completionHandler) {
        completionHandler(YES);
    }
}

 

 

二、Peek 与 Pop

首先来看看微信的效果图:

 

Peek,偷偷一看,即轻按预览:

 

具体实现步骤以下:

第一步:让控制器遵照代理<UIViewControllerPreviewingDelegate>

第二步:判断该设备是否支持3DTouch

//判断是否支持3DTouch
- (BOOL)isValidForceTouch{
    return self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable;
}

第三步:若是支持3DTouch,则给这个cell注册3DTouch预览功能,遵照代理

//给这个cell注册3DTouch预览功能
[self registerForPreviewingWithDelegate:self sourceView:cell];

第四步:实现Peek协议方法

// peek 预览
- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location{
    //按压的行
    NSIndexPath * indexPath = [_tableView indexPathForCell:(UITableViewCell *)[previewingContext sourceView]];
    //预览界面
    ShowViewController * showVC = (ShowViewController *)[self vcForSBID:kShowVCId];
    showVC.title = @"我是按进来的";
    showVC.text = [self selectedTextForRow:indexPath.row];
    //临时显示自定义的导航
    [showVC showTitle];
    
    return showVC;
}

看下运行效果:

Pop,重按进入:

第五步:实现Pop协议方法

//pop 进入
- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit{
    ShowViewController * showVC = (ShowViewController *)viewControllerToCommit;
    //隐藏咱们临时的导航,由于进入后有真正的导航
    [showVC hideTitle];
    [self showViewController:viewControllerToCommit sender:self];
}

运行效果图:

三、预览菜单

先来看看微信的效果图:

 

 

咱们只须要在预览控制器里实现以下方法,返回一个UIPreviewActionItem的数组:

//peek 时上滑出现的菜单
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems {
    // 普通样式
    UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"Aciton1" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Aciton1");
    }];
    
    //已被选择的样式 后面有个对勾
    UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"Aciton2" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Aciton2");
    }];
    
    //警示样式(红色字体)
    UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"Aciton3" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Aciton3");
    }];
    
    NSArray *actions = @[action1,action2,action3];
    
    return actions;
}

运行效果图:

四、关于导航、按压视图大小、预览视图的比例等

关于导航栏:

细心地同窗发现,预览的界面是没有导航栏的,微信是怎么实现的呢?我在试了不少方法,发现“在peek是显示一个自定义的导航栏,pop时隐藏自定义的导航栏”是一个可行的办法(若是哪位同窗知道更好的办法能够联系本人!!)。

 

关于按压视图大小:

有时候咱们只想按压某一个区域来预览,而不是整个cell,也许是cell上的label,或view上的某一个区块,这时候咱们能够改变显示的上下文视图的Rect来改变:

previewingContext.sourceRect = CGRectMake(0, 0, 300, 20);

 

关于预览视图比例:

预览视图的大小是能够改变的,若是你按压的是一个图片,pop出图片浏览器,显然效果不是那么理想,咱们能够根据图片的大小来设置预览视图的大小:

// peek 预览
- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location{
    
    //预览界面
    PhotoViewController * pvc = [[PhotoViewController alloc]init];
    pvc.image = _imageView.image;
    
    //设置预览视图的比例 能够看出 预览视图的宽高比例 图片的比例是一致的
    pvc.preferredContentSize = CGSizeMake(_imageView.image.size.width, _imageView.image.size.height);
    
    return pvc;
}

 

预览视图比例演示效果以下:

 

五、捕获“压力值”

经过touchesBegan、touchesMoved等方法来捕获,获取force值:

//按住移动or压力值改变时的回调
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    NSArray *arrayTouch = [touches allObjects];
    UITouch *touch = (UITouch *)[arrayTouch lastObject];

    NSLog(@"move压力 = %f",touch.force);
    
    //label显示压力值
    _textLabel.text = [NSString stringWithFormat:@"压力%f",touch.force];

    self.view.backgroundColor = [self colorForForce:touch.force];
}

经测试发现压力的范围是0.06666...~6.6666...,须要注意的是 这里的force ”压力“值 并非以牛顿为单位的物理上的力,而表明的是一个相对的参考系 咱们经过0.666... ~ 6.666... 来模拟压力的小和大。例如:我吧force值和颜色对应起来,按得越重,背景颜色就越黑。

 

效果以下:

 

六、结束语

3DTouch用处还未被彻底挖掘,但愿iOS Coder能够用它开发出更有意思的产品和功能。

 

七、Demo地址

github:

https://github.com/ly918/Demos

相关文章
相关标签/搜索