3D Touch 詳解

孤盞茗發表於2018-09-09

簡介

3D TouchiPhone6s以上機型並且是iOS9及以上系統而引入的三維觸控功能

作用:

  • 在主介面按主螢幕圖示可以立即訪問應用程式提供的功能
  • 在應用中,可以按檢視檢視其它內容得預覽

開關設定:

在3D Touch裝置上,可以在設定>通用>輔助功能>三維觸控中選擇開啟或者關閉touch功能,以及設定靈敏度

主螢幕Touch

使用者可以按住螢幕的應用圖示啟動touch提供的一組快速操作的功能,當使用者選擇其中某一項操作時,在appdelegate的應用委託中會收到回撥響應的資訊

目前最多支援應用顯示四個主螢幕的快速操作,在限制的範圍內,從選單中的最頂部位置開始,系統首先顯示靜態快速操作。當新增了四個靜態的快速操作後,即便新增動態快速操作也不會有任何響應。

有些應用中出現五項快捷操作。經過筆者的研究,分享應用的touch Item是上線後,系統統一為應用提供的功能,應用上線後系統為每一個應用提供了預設的分享touch功能

在應用首次啟動之前,主螢幕僅顯示程式的靜態快捷操作,首次啟動後,動態新增的操作也會顯示。如果使用者應用更新後尚未啟動更新,則主螢幕的快捷操作會響應之前操作,這個時候UIApplicationShortcutItemUserInfo就起到了關鍵性的作用,因為該鍵中應定義應用版本的資訊以響應不同版本的操作

設定Touch

設定靜態的touch

例項:

3D Touch 詳解

item旗下支援的鍵:

  • UIApplicationShortcutItemType 描述啟動項的祕鑰(必填)
  • UIApplicationShortcutItemTitle item的名稱(必填)
  • UIApplicationShortcutItemSubtitle item的輔助註釋(選填)
  • UIApplicationShortcutItemIconType item中系統提供icon的選項(選填)
  • UIApplicationShortcutItemIconFile 指定專案的中資源icon檔案(選填)大小為35x35 point
  • UIApplicationShortcutItemUserInfo 自定義的鍵值對(選填)

設定動態的touch

動態設定主要涉及一下兩個類:
  • UIApplicationShortcutIcon
該類系統目前僅提供三個類方法
//使用系統定義的icon建立
+ (instancetype)iconWithType:(UIApplicationShortcutIconType)type;
//使用資原始檔中的圖片資源建立
+ (instancetype)iconWithTemplateImageName:(NSString *)templateImageName;
//使用聯絡人建立
+ (instancetype)iconWithContact:(CNContact *)contact;
複製程式碼
  • UIApplicationShortcutItem
//僅定義啟動項的祕鑰以及名稱
- (instancetype)initWithType:(NSString *)type localizedTitle:(NSString *)localizedTitle;

- (instancetype)initWithType:(NSString *)type 
              localizedTitle:(NSString *)localizedTitle 
           localizedSubtitle:(NSString *)localizedSubtitle 
                        icon:(UIApplicationShortcutIcon *)icon 
                    userInfo:(NSDictionary<NSString *,id<NSSecureCoding>> *)userInfo;
複製程式碼
變換shortcutItem

可以通過UIApplicationShortcutItem設定可變的touch操作。動態設定的touch是可變的,apple中提供了變換Item的例項。

例項程式碼:

//該方法獲取到的items其實是上次設定的項
NSArray <UIApplicationShortcutItem *> *existingShortcutItems = [[UIApplication sharedApplication] shortcutItems];

UIApplicationShortcutItem *existingShortcutItem = [existingShortcutItems firstObject];
NSMutableArray <UIApplicationShortcutItem *> *updatedShortcutItems = [existingShortcutItems mutableCopy];
UIMutableApplicationShortcutItem *mutableShortcutItem = [existingShortcutItem mutableCopy];
NSInteger index = [existingShortcutItems indexOfObject:existingShortcutItem];

[mutableShortcutItem setLocalizedTitle: @"New Title"];

[updatedShortcutItems replaceObjectAtIndex: index withObject: mutableShortcutItem];
[[UIApplication sharedApplication] setShortcutItems: updatedShortcutItems];
複製程式碼

應用的響應操作

在Appdelegate中實現協議以驅動快捷操作的響應

- (void)application:(UIApplication *)application 
performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem 
  completionHandler:(void (^)(BOOL succeeded))completionHandler;
  
  完成操作後,應使用對應的布林值完成處理程式
複製程式碼

當應用程式未啟動,此時通過快捷touch啟動專案時:

系統會先回撥- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions代理

然後再呼叫- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler的回撥。

此種情況apple建議在didFinishLaunchingWithOptions中獲取launchOptionsUIApplicationLaunchOptionsShortcutItemKey鍵值的相關資訊以處理Touch的快捷啟動,此時返回NO後,系統不會再回撥- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler

快速預覽

前期狀態判斷

在使用快速預覽的時候,需要判斷Touch的可用性,並且需要注意用在執行程式時關閉Touch功能

例項:

//遵守UITraitEnvironment協議

1.判斷是否可用來決定的是否註冊touch檢視
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
    //註冊touch檢視
}

2.監聽Touch開關變化
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    
}
複製程式碼

相關API

  • UIViewController
//使用者在Touch向上滑動時顯示的快捷操作
@property(nonatomic, readonly) NSArray<id<UIPreviewActionItem>> *previewActionItems;

//註冊檢視參與Touch預覽功能,指定源檢視響應觸控
- (id<UIViewControllerPreviewing>)registerForPreviewingWithDelegate:(id<UIViewControllerPreviewingDelegate>)delegate 
                                                         sourceView:(UIView *)sourceView;

//取消註冊的上下文標識
- (void)unregisterForPreviewingWithContext:(id<UIViewControllerPreviewing>)previewing;

複製程式碼
  • UIViewControllerPreviewing
//sourceView的邊界,動畫啟動的定位
@property(nonatomic) CGRect sourceRect;
//Touch手勢
@property(nonatomic, readonly) UIGestureRecognizer *previewingGestureRecognizerForFailureRelationship;
//Delegate
@property(nonatomic, readonly) id<UIViewControllerPreviewingDelegate> delegate;
//源檢視
@property(nonatomic, readonly) UIView *sourceView;
複製程式碼
  • UIViewControllerPreviewingDelegate
/* 當使用者在預覽檢視控制器中Touch的時候回撥
 *
 *  previewingContext 預覽檢視控制器上下文物件
 *  location 觸控在源檢視座標系中的位置
 *  返回顯示對應的控制器,可以通過返回nil,禁用預覽
 */
- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext 
              viewControllerForLocation:(CGPoint)location;

//Touch響應點後的操作,一般推出需要顯示的檢視控制器
- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext 
     commitViewController:(UIViewController *)viewControllerToCommit;

複製程式碼
  • UIPreviewAction
/* 建立一個快捷操作
 *
 *  title 動作的標題
 *  style 快捷操作的型別
 */
+ (instancetype)actionWithTitle:(NSString *)title 
                          style:(UIPreviewActionStyle)style 
                        handler:(void (^)(UIPreviewAction *action, UIViewController *previewViewController))handler;

//快捷操作呼叫的快
@property(nonatomic, copy, readonly, nonnull) void (^handler)(id<UIPreviewActionItem> action, UIViewController *previewViewController);

複製程式碼
  • UIPreviewActionGroup
/* 快捷操作組
 *
 *  title 組的標題
 *  style 組的型別
 */
+ (instancetype)actionGroupWithTitle:(NSString *)title 
                               style:(UIPreviewActionStyle)style 
                             actions:(NSArray<UIPreviewAction *> *)actions;
複製程式碼
  • UIPreviewActionItem
//快速行動的標題
@property(nonatomic, copy, readonly) NSString *title;

複製程式碼

具體實現步驟

  1. 先判斷Touch開關狀態以及監聽開關狀態的變化
  2. 需要預覽的檢視源控制遵守UIViewControllerPreviewingDelegate協議,並實現相關的代理
  3. 如果需要設定Touch預覽向上滑動顯示快捷操作,則在預覽檢視控制器設定previewActionItems屬性即可

下載例項

相關文章