一、屏幕圖標使用3D Touch創建快速進入入口:
1、與之相關的類:
(1)、 UIApplicationShortcutIcon:快捷方式的圖標
-
+ (instancetype)iconWithType:(UIApplicationShortcutIconType)type;
:使用系統圖標創建對象。
typedef NS_ENUM(NSInteger, UIApplicationShortcutIconType) {
UIApplicationShortcutIconTypeCompose,
UIApplicationShortcutIconTypePlay,
UIApplicationShortcutIconTypePause,
UIApplicationShortcutIconTypeAdd,
UIApplicationShortcutIconTypeLocation,
UIApplicationShortcutIconTypeSearch,
UIApplicationShortcutIconTypeShare,
// pragma -------------------- 以下類型只能在9.1及以上系統使用
UIApplicationShortcutIconTypeProhibit,
UIApplicationShortcutIconTypeContact,
UIApplicationShortcutIconTypeHome,
UIApplicationShortcutIconTypeMarkLocation,
UIApplicationShortcutIconTypeFavorite,
UIApplicationShortcutIconTypeLove,
UIApplicationShortcutIconTypeCloud,
UIApplicationShortcutIconTypeInvitation,
UIApplicationShortcutIconTypeConfirmation,
UIApplicationShortcutIconTypeMail,
UIApplicationShortcutIconTypeMessage,
UIApplicationShortcutIconTypeDate,
UIApplicationShortcutIconTypeTime,
UIApplicationShortcutIconTypeCapturePhoto,
UIApplicationShortcutIconTypeCaptureVideo,
UIApplicationShortcutIconTypeTask,
UIApplicationShortcutIconTypeTaskCompleted,
UIApplicationShortcutIconTypeAlarm,
UIApplicationShortcutIconTypeBookmark,
UIApplicationShortcutIconTypeShuffle,
UIApplicationShortcutIconTypeAudio,
UIApplicationShortcutIconTypeUpdate
} NS_ENUM_AVAILABLE_IOS(9_0)
+ (instancetype)iconWithTemplateImageName:(NSString *)templateImageName;
:自定義圖標樣式創建對象。+ (instancetype)iconWithContact:(CNContact *)contact;
:使用代表用戶通訊簿中的聯系人的圖標,可以通過ContactsUI框架訪問,需要導入ContactsUI頭文件 ---#import <ContactsUI/ContactsUI.h>
。
(2)、 UIApplicationShortcutItem:不可變快捷方式項
?必須在初始化期間指定實例的特征,然后才能將其注冊到應用對象。即:直接的init方法不可用。
- (instancetype)initWithType:(NSString *)type localizedTitle:(NSString *)localizedTitle localizedSubtitle:(nullable NSString *)localizedSubtitle icon:(nullable UIApplicationShortcutIcon *)icon userInfo:(nullable NSDictionary *)userInfo NS_DESIGNATED_INITIALIZER;
:指定的創建方法。其中參數:type -- 自定義的的字符串標識;localizedTitle -- 快速操作標題;localizedSubtitle -- 快速操作副標題;icon -- 圖標;userInfo -- 攜帶的信息,如果NSDictionary不是plist-encoding會拋出異常。- (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;
:獲取操作所需的應用程序特定信息。
(3)、 UIMutableApplicationShortcutItem:可變快捷方式項
?繼承于UIApplicationShortcutItem,屬性與之一樣但是其屬性性質是copy屬性。如下所示:
@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;
2、靜態設置方式:在Info.plist設置
(1)、首先在Info.plist
-->Information Property List
下添加array屬性的鍵欄目:UIApplicationShortcutItems
(該字段系統未定義需要全程手寫~),用于指定應用程序的靜態主屏幕快速操作。該鍵包含一系列 字典。每個字典包含有關單個快速操作及其使用方法的詳細信息。
(2)、在UIApplicationShortcutItems
鍵欄目下添加dictionary屬性的鍵,然后再在dictionary屬性的鍵欄目下再添加3D Touch相關鍵。
(3)、3D Touch 相關鍵:
UIApplicationShortcutItemType
: 必須的!相當于添加一個標識。UIApplicationShortcutItemTitle
:必須的!主標題,如果標題符合一行,則系統將其顯示為單行快速操作項。如果標題對于一行而言太長,并且沒有指定UIApplicationShortcutItemSubtitle字符串,系統將在兩行顯示標題。UIApplicationShortcutItemSubtitle
:可選的,副標題。UIApplicationShortcutItemIconType
:可選的,指定系統提供的庫中圖標類型的可選字符串,參照上面UIApplicationShortcutIconType枚舉類。UIApplicationShortcutItemIconFile
:可選的,使用自定義圖標,如果指定此鍵,系統將忽略該UIApplicationShortcutItemIconType鍵。UIApplicationShortcutItemUserInfo
:可選的,此字典的一個用途是可以提供應用程序版本信息。
如下圖設置所示:
(4)、值得注意的是:
- 1、鍵的前后不能有空格!這個可以將plist文件以Source Code 的形式打開查看一下;
- 2、若設置了UIApplicationShortcutItemIconFile但是文件路徑錯誤或者為空則會顯示小黑點圖標;
- 3、最多只會有四個快捷入口生效,依次按從上到下的順序顯示。
PS: 附上關于 "鍵" 的文檔地址 -- > UIApplicationShortcutItems
3、代碼設置快捷入口項:
代碼設置時需要檢查設備是否支持3D Touch,即讀取任意遵循特征環境協議(UITraitEnvironment)的特征集合類型(UITraitCollection類型)屬性的觸摸力能力(UIForceTouchCapability類型)屬性,以達到判斷設備是否支持3D Touch:
typedef NS_ENUM(NSInteger, UIForceTouchCapability) {
UIForceTouchCapabilityUnknown = 0,
UIForceTouchCapabilityUnavailable = 1,
UIForceTouchCapabilityAvailable = 2
};
一般直接在didFinishLaunchingWithOptions:
方法中操作,也可以在根視圖控制器中進行操作,這里示例是第一種:
if ([self.window.rootViewController respondsToSelector:@selector(traitCollection)]){
if ([self.window.rootViewController.traitCollection respondsToSelector:@selector(forceTouchCapability)]){
if (self.window.rootViewController.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable){
// 支持3D Touch
UIApplicationShortcutIcon * icon_one = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypePlay];
UIApplicationShortcutIcon * icon_two = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeAdd];
UIApplicationShortcutItem * item_one = [[UIApplicationShortcutItem alloc] initWithType:@"com.test.one" localizedTitle:@"第一標題" localizedSubtitle:@"第一副標題" icon:icon_one userInfo:nil];
UIApplicationShortcutItem * item_two = [[UIApplicationShortcutItem alloc] initWithType:@"com.test.two" localizedTitle:@"第二標題" localizedSubtitle:@"第二副標題" icon:icon_two userInfo:nil];
application.shortcutItems = @[item_one, item_two];
}else{
// 不支持3D Touch
}
}
}
以上就將外部顯示項設置完成了,但是這樣是不夠的,當你沒有其他設置后通過快捷方式進入程序永遠是首頁沒方法到你想到的界面,所以這不是結束,而是開始~
4、通過快捷方式進入程序目的界面:
在iOS9時,UIApplicationDelegate添加了如下關于快捷方式進入應用程序的方法:
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void(^)(BOOL succeeded))completionHandler;
當應用程序通過該方法啟動或者激活時會走此方法,當然會有例外(下面會介紹),參數shortcutItem是用戶選擇的那個shortcutItem,可以依次做判斷跳轉到不同界面;參數completionHandler,是在快速執行完成后調用此block塊,根據實施代碼的成功或失敗返回YES或NO。該方法與
didFinishLaunchingWithOptions
方法存在一定的關系,根據官方文檔描述:通常需要在didFinishLaunchingWithOptions
方法中獲取launchOptions
的鍵UIApplicationLaunchOptionsShortcutItemKey
所對應的對象來做檢查是否是通過使用快速操作啟動程序的。該對象是UIApplicationShortcutItem
類型的對象,如果應用程序是通過快速操作 啟動(而不是激活)的,則該對象是代表用戶選擇的ShortcutItem,否者為null。通過該方式可以區分是否是通過快速操作啟動程序的,然后以此進行不同的操作。當用戶t通過選擇快速操作啟動應用程序時,系統將在調用
performActionForShortcutItem:
方法之前先調用啟動方法didFinishLaunchingWithOptions
。-
如果
didFinishLaunchingWithOptions
方法返回NO時,系統將不調用performActionForShortcutItem:
方法!到這里第一部分結束,這里放上一個示例,僅供參考!
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UINavigationController * navigationController = [[UINavigationController alloc] initWithRootViewController: [[ViewController alloc] init]];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
if ([self.window.rootViewController respondsToSelector:@selector(traitCollection)]){
if ([self.window.rootViewController.traitCollection respondsToSelector:@selector(forceTouchCapability)]){
if (self.window.rootViewController.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable){
// 支持3D Touch
UIApplicationShortcutIcon * icon_one = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypePlay];
UIApplicationShortcutIcon * icon_two = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeAdd];
UIApplicationShortcutItem * item_one = [[UIApplicationShortcutItem alloc] initWithType:@"com.test.one" localizedTitle:@"第一標題" localizedSubtitle:@"第一副標題" icon:icon_one userInfo:nil];
UIApplicationShortcutItem * item_two = [[UIApplicationShortcutItem alloc] initWithType:@"com.test.two" localizedTitle:@"第二標題" localizedSubtitle:@"第二副標題" icon:icon_two userInfo:nil];
application.shortcutItems = @[item_one, item_two];
}else{
// 不支持3D Touch
}
}
}
// 通常不會寫這一段,它和完全沒有效果一樣~
#ifdef __IPHONE_9_0
if ([launchOptions objectForKey:UIApplicationLaunchOptionsShortcutItemKey]) {
UIApplicationShortcutItem * item = [launchOptions objectForKey:UIApplicationLaunchOptionsShortcutItemKey];
[self application:application performActionForShortcutItem:item completionHandler:^(BOOL succeeded) {
}];
return NO;
}
#endif
return YES;
}
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
{
UINavigationController * navicattionC = (UINavigationController *)self.window.rootViewController;
ViewController * VC = (ViewController *)navicattionC.topViewController;
if (shortcutItem) {
if ([shortcutItem.type isEqualToString:@"com.test.one"]) {
TextViewController * textVC = [[TextViewController alloc] init];
[VC.navigationController pushViewController:textVC animated:YES];
}
if ([shortcutItem.type isEqualToString:@"com.test.two"]) {
AffineTransformViewController * AffineTransformVC = [[AffineTransformViewController alloc] init];
[VC.navigationController pushViewController:AffineTransformVC animated:YES];
}
}
}
二、程序內使用3D Touch預覽和進入下一界面,即(Peek and Pop):
1、與之相關的類與協議及方法與屬性:
(1、)試圖控制器新增分類方法與屬性:
- (id <UIViewControllerPreviewing>)registerForPreviewingWithDelegate:(id<UIViewControllerPreviewingDelegate>)delegate sourceView:(UIView *)sourceView ;
:UIViewController用于注冊視圖控制器參與3D Touch的方法。delegate -- 代理;sourceView -- 響應Peek & Pop的視圖。- (void)unregisterForPreviewingWithContext:(id <UIViewControllerPreviewing>)previewing;
:UIViewController用于銷毀視圖控制器參與3D Touch的方法。- (NSArray <id <UIPreviewActionItem>> *)previewActionItems;
:在Peek時希望提供一些快捷選項,需要重寫該方法用于設置快捷選項。該方法需要在目標控制器重寫,即你想push或present到的那個控制器!
(2、)支持3D Touch的視圖控制器協議:UIViewControllerPreviewingDelegate
- (nullable UIViewController *)previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location;
:當用戶在預覽視圖控制器中按下源視圖時調用。previewingContext:預覽視圖控制器的上下文對象。location:在源視圖的坐標系中觸摸的位置。返回希望提供預覽的視圖控制器。如果返回nil則沒有peek效果。- (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit;
:當進入Pop狀態時,系統會調用此方法。viewControllerToCommit -- 提供預覽的試圖控制器。
(3、)預覽視圖控制器的上下文對象協議類:UIViewControllerPreviewing
(不要在自定義類中使用此協議!!!)
@property (nonatomic, readonly) UIGestureRecognizer *previewingGestureRecognizerForFailureRelationship;
:可以同時識別其他手勢。@property (nonatomic, readonly) id<UIViewControllerPreviewingDelegate> delegate;
:代理@property (nonatomic, readonly) UIView *sourceView
:響應用戶觸摸的視圖。@property (nonatomic) CGRect sourceRect;
設置sourceView響應區域的范圍,在對象的方法previewingContext: viewControllerForLocation:
中設置此屬性的值。如果源視圖是自定義的TableView視圖,則可以將屬性設置為用戶觸摸的行的frame。
(4、)預覽行為快捷項 協議類:UIPreviewActionItem
?該協議只有一個只讀屬性:
-
@property(nonatomic, copy, readonly) NSString *title;
:獲取標題。
(5、)預覽行為類:UIPreviewAction
:服從協議 -- UIPreviewActionItem
@property(nonatomic, copy, readonly) void (^handler)(id<UIPreviewActionItem> action, UIViewController *previewViewController);
:block 屬性,包含一個快捷項和預覽控制器。+ (instancetype)actionWithTitle:(NSString *)title style:(UIPreviewActionStyle)style handler:(void (^)(UIPreviewAction *action, UIViewController *previewViewController))handler;
:使用指定的標題,樣式和處理程序創建一個快速行動。
其中style是枚舉類:
typedef NS_ENUM(NSInteger,UIPreviewActionStyle) {
UIPreviewActionStyleDefault=0,
UIPreviewActionStyleSelected,
UIPreviewActionStyleDestructive,
} NS_ENUM_AVAILABLE_IOS(9_0);
(5、)預覽行為組類:UIPreviewActionGroup
:服從協議 -- UIPreviewActionItem
-
+ (instancetype)actionGroupWithTitle:(NSString *)title style:(UIPreviewActionStyle)style actions:(NSArray<UIPreviewAction *> *)actions;
:使用指定的標題,樣式和數組的快速行動創建一個快速行動組。
2、具體使用:以在tableView中使用為例
(1、)首先要遵循UIPreviewInteractionDelegate協議,然后在需要支持3D Touch的視圖上注冊,注意:注冊前最好檢驗一下是否支持3D Touch
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == headerTitleArray.count-1) {
NewestDataTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:NewestDataTableViewCellID forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.model = self.totalArray[indexPath.section][indexPath.row];
cell.wordFont = wordFont;
//注冊支持 3D Touch
[self registerPreviewingWithDelegate:self sourceView:cell];
return cell;
}else{
NewestMajorityTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:NewestMajorityTableViewCellID forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.model = self.totalArray[indexPath.section][indexPath.row];
cell.wordFont = wordFont;
//注冊支持 3D Touch
[self registerPreviewingWithDelegate:self sourceView:cell];
return cell;
}
}
- (void)registerPreviewingWithDelegate:(id<UIViewControllerPreviewingDelegate>)delegate sourceView:(UITableViewCell *)cell{
if ([self respondsToSelector:@selector(traitCollection)]) {
if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)]) {
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
// 注冊
[self registerForPreviewingWithDelegate:delegate sourceView:cell];
}
}
}
}
(2、)實現兩個協議方法:
#pragma 3D Touch Method
- (nullable UIViewController *)previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location{
NSIndexPath * indexPath = [self.newestTableView indexPathForCell:(UITableViewCell *)[previewingContext sourceView]];
NewestContentDetailViewController * contentDetailVC = [[NewestContentDetailViewController alloc] init];
// 自定義的方法,因為這里會和點擊方法中代碼重復,所以這里處理了一下,抽成了一個方法
[self setModelWithViewController:contentDetailVC withIndexPath:indexPath];
// 設置響應區域
CGRect rect = CGRectMake(0, 0, previewingContext.sourceView.kWidth, previewingContext.sourceView.kHeight);
previewingContext.sourceRect = rect;
return contentDetailVC;
}
- (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit{
[self.navigationController pushViewController:viewControllerToCommit animated:YES];
}
- (void)setModelWithViewController:(NewestContentDetailViewController * )viewController withIndexPath:(NSIndexPath *)indexPath
{
NewestDataModel * model = self.totalArray[indexPath.section][indexPath.row];
viewController.model = model;
..... //此處省略部分代碼!
}
這樣基本的pop和peek就完成了,如果還要做更多的操作 --- 在Peek時希望提供一些快捷選項,需要進行第三步:
(3、)在Peek時提供一些快捷選項:重寫-previewActionItems
方法。該項操作需要在目標控制器,即將要跳轉到的那個控制器里進行!!!
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems
{
UIPreviewAction * collectAction = [UIPreviewAction actionWithTitle:@"收藏" style:(UIPreviewActionStyleDefault) handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
// 做后續操作
}];
UIPreviewAction * shareAction = [UIPreviewAction actionWithTitle:@"分享" style:(UIPreviewActionStyleSelected) handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
// 做后續操作
}];
UIPreviewAction * cancelAction = [UIPreviewAction actionWithTitle:@"取消" style:(UIPreviewActionStyleDestructive) handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
// 做后續操作
}];
UIPreviewActionGroup * cancelGroup = [UIPreviewActionGroup actionGroupWithTitle:@"更多" style:UIPreviewActionStyleDestructive actions:@[shareAction, cancelAction]];
return @[collectAction, cancelGroup];
}
三、在UIWebView和:WKWebView中啟用3D Touch功能:
這個只需要設置9.0后UIWebView或WKWebView新增的屬性allowsLinkPreview
為YES即可。該功能主要針對打開的webView中存在其他鏈接,可以對這些跳轉其他鏈接的入口出使用3D Touch功能。
all are over~