iOS开发之3D Touch

1、简介

  3DTouch是在6s之后苹果的一项技术,只能在6s及其以上机型真机运行,Xcode的模拟器是不支持的。

  • Quick Actions(点击icon的快捷方式)

  • Peek&Pop(应用内快速预览内容)

  • UITouch和LivePhoto(读取压力和最大压力)

 

2、Quick Actions(点击icon的快捷方式)

  点击app的图标,可以弹出Today小组件(如果有的话)和UIApplicationShortcutItem快捷方式——这就是Quick Actions!

//
//  UIApplicationShortcutItem.h
//  UIKit
//
//  Copyright © 2015-2017 Apple Inc. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@class UIImage;

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;

NS_CLASS_AVAILABLE_IOS(9_0) __TVOS_PROHIBITED
@interface UIApplicationShortcutIcon : NSObject <NSCopying>
//初始化
+ (instancetype)iconWithType:(UIApplicationShortcutIconType)type;
//基于应用程序包中的图像创建主屏幕快速动作图标,最好是在资产目录中。
+ (instancetype)iconWithTemplateImageName:(NSString *)templateImageName;

@end

NS_CLASS_AVAILABLE_IOS(9_0) __TVOS_PROHIBITED
@interface UIApplicationShortcutItem : NSObject <NSCopying, NSMutableCopying>

//初始化
- (instancetype)init NS_UNAVAILABLE;
/**
 @param type 自定义的字符串type
 @param localizedTitle 标题
 @param localizedSubtitle 子标题
 @param icon 图标
 @param userInfo 传递的信息
 */
- (instancetype)initWithType:(NSString *)type localizedTitle:(NSString *)localizedTitle localizedSubtitle:(nullable NSString *)localizedSubtitle icon:(nullable UIApplicationShortcutIcon *)icon userInfo:(nullable NSDictionary *)userInfo NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithType:(NSString *)type localizedTitle:(NSString *)localizedTitle;

//读取相关初始化信息
@property (nonatomic, copy, readonly) NSString *type;
@property (nonatomic, copy, readonly) NSString *localizedTitle;
@property (nullable, nonatomic, copy, readonly) NSString *localizedSubtitle;
@property (nullable, nonatomic, copy, readonly) UIApplicationShortcutIcon *icon;
@property (nullable, nonatomic, copy, readonly) NSDictionary<NSString *, id <NSSecureCoding>> *userInfo;

@end

NS_CLASS_AVAILABLE_IOS(9_0) __TVOS_PROHIBITED
//可变item
@interface UIMutableApplicationShortcutItem : UIApplicationShortcutItem
@property (nonatomic, copy) NSString *type;
@property (nonatomic, copy) NSString *localizedTitle;
@property (nullable, nonatomic, copy) NSString *localizedSubtitle;
@property (nullable, nonatomic, copy) UIApplicationShortcutIcon *icon;
@property (nullable, nonatomic, copy) NSDictionary<NSString *, id <NSSecureCoding>> *userInfo;

@end

NS_ASSUME_NONNULL_END
UIApplicationShortcutItem相关API

  2.1、静态创建

    直接配置Info.plist文件

  2.2、动态创建  

    代码创建:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    NSMutableArray *arrShortcutItem = (NSMutableArray *)[UIApplication sharedApplication].shortcutItems;
    
    UIApplicationShortcutItem *shoreItem1 = [[UIApplicationShortcutItem alloc] initWithType:@"适得府君书咖啡来看" localizedTitle:@"搜索" localizedSubtitle:nil icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeSearch] userInfo:nil];
    [arrShortcutItem addObject:shoreItem1];
    UIApplicationShortcutItem *shoreItem2 = [[UIApplicationShortcutItem alloc] initWithType:@"杜师傅就快两个打开分割" localizedTitle:@"新消息" localizedSubtitle:@"" icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeCompose] userInfo:nil];
    [arrShortcutItem addObject:shoreItem2];
    UIApplicationShortcutItem *shoreItem3 = [[UIApplicationShortcutItem alloc] initWithType:@"sdfasjdfhsksdjfsdajklfdjfh" localizedTitle:@"加大开发" localizedSubtitle:@"" icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeLocation] userInfo:nil];
    [arrShortcutItem addObject:shoreItem3];
    UIApplicationShortcutItem *shoreItem4 = [[UIApplicationShortcutItem alloc] initWithType:@"sdfasjdfhskdjfh" localizedTitle:@"" localizedSubtitle:@"" icon:[UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeShare] userInfo:nil];
    [arrShortcutItem addObject:shoreItem4];

    [UIApplication sharedApplication].shortcutItems = arrShortcutItem;
    return YES;
}

  2.3、点击响应方法

- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler{
    NSLog(@"name ==%@\n type =  %@",shortcutItem.localizedTitle,shortcutItem.type);
}

  ps:系统优先加载静态方法创建的item,可以混合加载,最多4个item;

    正式发布后会有5个item,苹果统一添加个分享的item;

    有的item的图标会显现在右侧,这个和app在屏幕得位置有关;

 

 3、Peek&Pop(应用内快速预览内容)

  Peek页面预览:给视图添加一点压力,会以弹框的方式预览目标界面;

  Pop拉出菜单:在界面预览时,如果有菜单选项,向上拖拽下面会出现菜单栏;

  继续增加压力会跳转到目标界面——也就是Peek&Pop!

  3.1、Peek

    本例在图片上添加此功能:前提一个是可以交互、二是注册registerForPreviewingWithDelegate

    [self.imageView setUserInteractionEnabled:YES];
    if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
        [self registerForPreviewingWithDelegate:(id)self sourceView:self.imageView];
    }

    创建菜单栏:需要在目标ViewController界面重写- (NSArray<id<UIPreviewActionItem>> *)previewActionItems;方法

- (NSArray<id<UIPreviewActionItem>> *)previewActionItems{
    UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"action1" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"action1");
    }];
    
    UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"action2" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"action2");
    }];
    NSArray *actions = @[action1,action2];
    UIPreviewActionGroup *group1 = [UIPreviewActionGroup actionGroupWithTitle:@"Action Group" style:UIPreviewActionStyleDefault actions:actions];

    return@[action1,action2,group1];
}

    预览视图方法和跳转视图方法:

//预览
- (nullable UIViewController *)previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location NS_AVAILABLE_IOS(9_0)
{
    if ([self.presentedViewController isKindOfClass:[VideoViewController class]]){
        return nil;
    }else {
        VideoViewController *contentVC = [[VideoViewController alloc] init];
        return contentVC;
    }
}

//重按进入
- (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit NS_AVAILABLE_IOS(9_0)
{
    NSLog(@"重按进入");
    VideoViewController *v = [[VideoViewController alloc] init];
    [self presentViewController:v animated:YES completion:nil];
}

 

4、UITouch和LivePhoto(读取压力和最大压力)

  在UITouch类中有两个方法用来读取实时压力和最大压力:

// 触摸压力值
@property(nonatomic,readonly) CGFloat force NS_AVAILABLE_IOS(9_0);
// 最大触摸压力值
@property(nonatomic,readonly) CGFloat maximumPossibleForce NS_AVAILABLE_IOS(9_0);

  在本例中重写了ImageView的代理方法获取这两个数值:

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"=======%lf",touches.anyObject.force);
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"------%lf",touches.anyObject.maximumPossibleForce);
}

  结果:

  LivePhoto是一张图片和一段3秒的视频组成,当使用3D Touch时会播放这段视频,手指放开会结束播放。

  所以这个效果通过UITouch的上面两个属性就可以自己完成!

 

posted @ 2018-08-20 14:56  ForeverGuard  阅读(930)  评论(0编辑  收藏  举报