3D Touch简易小示例

前言

3D Touch是iOS 9(系统版本小于iOS 9的不支持)出现的功能,虽然出来有段时间了,但其实有运用到3D Touch的App并不算很多。小编见过3D Touch做的比较好的App中,微信是佼佼者。在这里,小编班门弄斧一下,和大家说说3D Touch的简易实现方式。3D Touch一共有三种呈现形式,小编在此会一一举例,总体效果图如下:


效果

效果一

效果一就是按下屏幕,出现选择框,这是3D Touch目前来说被使用的最多的技术。效果图如下:


实现方法

效果一的实现其实非常简单,这里简单的说一下,效果一的每一个item里面都有3个东西,包括主标题、子标题和图片。主标题和图片必须设置,子标题可以不设置。图片可以用系统自带的,也可以自己设定。
在AppDelegate中加入下列代码即可完成,可以按照自己的要求增加选项的数量:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//    判断系统版本大于9.0(只支持9.0以上的操作)
    if ([[[UIDevice currentDevice]systemVersion]floatValue] >= 9.0) {
//        自定义图标的设置方法
//        UIApplicationShortcutIcon *home = [UIApplicationShortcutIcon iconWithTemplateImageName:@""];
//        系统图标的设置方法
        UIApplicationShortcutIcon *home = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeHome];
//        主标题和图标必须设置
        UIApplicationShortcutItem *item1 = [[UIApplicationShortcutItem alloc]initWithType:@"type" localizedTitle:@"主标题、子标题、图标" localizedSubtitle:@"子标题" icon:home userInfo:nil];
        UIApplicationShortcutItem *item2 = [[UIApplicationShortcutItem alloc]initWithType:@"type" localizedTitle:@"主标题、图标" localizedSubtitle:nil icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeAdd] userInfo:nil];
        // 设置按钮
        [[UIApplication sharedApplication] setShortcutItems:[@[item1,item2]mutableCopy]];
    }
    return YES;
}
// 通过3dtouch菜单启动
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler {
    NSLog(@"%@", shortcutItem.localizedTitle);
}

效果二

效果二是点击View预览视图,这个功能的实现,主要是因为在iOS 9时加入了UIViewControllerPreviewingDelegate这个协议,小编在例子中使用的是collectionView,大家可以把代理加到相应的地方。

实现方法

在这里先说一下如果只是点击预览而不需要进去的做法。

  • 第一步是设置代理;
  • 第二步是绑定代理(注意:如果在tableView和collectionView中不要反复绑定);
  • 第三步是建立新的视图控制器,这个控制器是用来放需要预览的视图的;
  • 第四步是调用系统Api中的 - (nullable UIViewController *)previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location NS_AVAILABLE_IOS(9_0) 方法。
    步骤1:
@interface DemoCell : UICollectionViewCell
/**
 设置3D Touch代理
 */
@property (weak, nonatomic) id<UIViewControllerPreviewingDelegate> previewingDelegate;
@end
//---------------------------------------------------------------------
@implementation DemoCell

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self){
        self.contentView.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];
    }
    return self;
}

- (void)setPreviewingDelegate:(id<UIViewControllerPreviewingDelegate>)previewingDelegate
{
//    这里设置代理,需要控制好设置(registerForPreviewingWithDelegate)的次数,确保每个cell都有register就可以,但不要重复(若大量registerForPreviewingWithDelegate 会造成滑动失控)
    if (!_previewingDelegate) {
        _previewingDelegate = previewingDelegate;
        UIViewController *controller = (UIViewController *)previewingDelegate;
        [controller registerForPreviewingWithDelegate:previewingDelegate sourceView:self.contentView];
    }
}
@end

步骤2:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    DemoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
    //设置代理
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0){
        cell.previewingDelegate = self;
    }
    return cell;
}

步骤3:

@interface PreViewController : UIViewController
@property (assign,nonatomic) NSInteger currentPage;
@end
//---------------------------------------------------------------------
@implementation PreViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100,30)];
    label.center = self.view.center;
    label.text = [NSString stringWithFormat:@"当前第%zd页",self.currentPage];
    UIView *view = [[UIView alloc]initWithFrame:(CGRect){0,0,375,20}];
    [view setBackgroundColor:[UIColor redColor]];
    [self.view addSubview:view];
    [self.view addSubview:label];
    
    // Do any additional setup after loading the view.
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    // 在iOS9 中 UITouch对象加入了 force属性,对应的是3dtouch的力度
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0){
        UITouch *touch = [[touches allObjects]lastObject];
        NSLog(@"%lf",touch.force);
    }
}
@end

步骤4:

- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location
{
//    1.我们可以通过触控的location获取 当前点击的是第几个元素(位于collectionview)
//    2.由于响应3dtouch事件的view是cell的contentView,我们对触控拿到的location要进行一个转换(相对于collectionview(父视图)来说的位置
//    3.这里通过previewingContext中sourceView获取到触摸的view
    UIView *contentView = previewingContext.sourceView;
//    看回"2" 中第一句话,我们要拿到这个触控的location位于collectionview中的位置
    CGPoint iLocation = [contentView convertPoint:location toView:self.collectionView];
//    将获取到的位置 通过collectionview获取indexPath
    NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:iLocation];
    
    PreViewController *preViewController = [[PreViewController alloc]init];
    preViewController.currentPage = indexPath.item;
    
    return preViewController;
}
加上点击进入该页面功能

实现这个功能只需要在上面的基础上调用UIViewControllerPreviewingDelegate的另一个代理方法即可。

- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit
{
//    打开详情页触发
    if (viewControllerToCommit) {
        [self showViewController:viewControllerToCommit sender:self];
    }
}

效果三

效果三是在效果二的基础上实现的,若没有实现效果二,请先实现效果二。效果图如下:


实现方法

在新建的视图控制器中加入代理的方法即可,如下

- (NSArray<id<UIPreviewActionItem>> *)previewActionItems{
    UIPreviewAction *itemA = [UIPreviewAction actionWithTitle:@"A" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"操作A");
    }];
    UIPreviewAction *itemB = [UIPreviewAction actionWithTitle:@"B" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"操作B");
    }];
    UIPreviewAction *itemC = [UIPreviewAction actionWithTitle:@"C" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"操作C");
    }];
    return @[itemA,itemB,itemC];
}

这就是3D Touch的内容,最后,希望这篇文章对各位看官们有所帮助。Demo下载地址:Demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,639评论 4 61
  • 我要把年轻时掉落的发丝, 一根一根的 悉心收藏。 待白发苍苍时, 盖在头上 依旧乌黑发亮。
    Jessica_04c6阅读 1,450评论 0 0
  • 2016年3月1日 第6篇 通讯工具日新月异的今天,众多智能手机横空出世。其实,作为通讯工具,老式的电话则...
    心理咨询师李彬阅读 2,312评论 0 0

友情链接更多精彩内容