3DTouch那点事

公司之前在新的版本中添加了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上大家可以下载。
如果感觉这篇文章对您有所帮助,顺手点个喜欢,谢谢啦

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 一夜风吹雨打 叶用她美丽的丝绢 为秋绣好了厚厚的锦被 枝条还沉浸在 风雨的梦乡 轻轻地啍着对秋的恋歌 根无瑕欣赏秋...
    六月天气阅读 394评论 33 40
  • 青石电影(ifmovie)原创,转载请微信公号联系授权! 前戏 一直以来青石始终认为韩剧是有毒的,看完火遍全球的《...
    青石电影阅读 441评论 0 0
  • 举拳立誓献国防,柴米油盐愁断肠。 凌云壮志终不悔,裙裳鞋袜总是伤。 纵然螺钉一小枚,红心映出半边天。
    小菜一碟中花生米阅读 292评论 1 1