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
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的上面两个属性就可以自己完成!