伴著6S的發佈,iOS 9.0開始支持3D Touch功能。使用場景來分一共有三種情況。 一、基於UIViewController的擴展 1. 首先要註冊需要監聽重按手勢的 source view: 2. 重按手勢識別出來之後需要按照 協議去處理 peek 和 pop 事件,這個協議有兩個方法 3. ...
伴著6S的發佈,iOS 9.0開始支持3D Touch功能。使用場景來分一共有三種情況。
一、基於UIViewController的擴展
1. 首先要註冊需要監聽重按手勢的 source view:
```
- (id <UIViewControllerPreviewing>)registerForPreviewingWithDelegate:(id<UIViewControllerPreviewingDelegate>)delegate sourceView:(UIView *)sourceView NS_AVAILABLE_IOS(9_0);
- (void)unregisterForPreviewingWithContext:(id <UIViewControllerPreviewing>)previewing NS_AVAILABLE_IOS(9_0);
```
2. 重按手勢識別出來之後需要按照 UIViewControllerPreviewingDelegate
協議去處理 peek 和 pop 事件,這個協議有兩個方法
```
// 對應 peek 事件,返回的是一個預覽界面。
- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
UIViewController* previewVC;
// 期望展示的大小
previewVC.preferredContentSize = CGSizeZero;
// 源rect,除了這個rect之外的區域都會模糊
previewingContext.sourceRect = CGRectZero;
return previewVC;
}
```
```
// 對應 pop 事件,做一些對應處理
- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
}
```
3. 另外,對於 pop 出來的預覽界面,可以提供一些額外操作,這些操作需要添加在預覽VC裡面
```
// 添加一些 action
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems
{
// action
UIPreviewAction *action = [UIPreviewAction actionWithTitle:@"--" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
//do something
}];
// action group
UIPreviewActionGroup *previewGroup = 包含一組action;
return @[暴露的action,暴露的組];
}
```
4. XCode 7.1 之後的版本,如果支持 iOS 9.1 以上的系統,可以通過 XCode 直接把 segue 設置成 peek&pop 去實現這種效果。
二、APP 圖標重按
1. 靜態添加
在 Info.plist 中 添加 `UIApplicationShortcutItems ` 欄位,這個欄位下麵的每個字典結構定義了一個 Item,key 如下:
```
`UIApplicationShortcutItemType (required)`
一般取值和 bundle id 一致,用來判斷快速操作類型。
`UIApplicationShortcutItemTitle (required)`
標題
`UIApplicationShortcutItemSubtitle`
副標題,顯示在標題下麵
`UIApplicationShortcutItemIconType`
圖標
`UIApplicationShortcutItemIconFile`
自定義圖標文件,會覆蓋上面的icon type
`UIApplicationShortcutItemUserInfo`
自定義信息
```
靜態添加的無法修改,並且優先顯示。
2. 動態添加
也就是創建自定義的 `UIApplicationShortcutItem` 然後設置給 UIApplication。看代碼:
```
NSArray <UIApplicationShortcutItem *> *existingShortcutItems = [[UIApplication sharedApplication] shortcutItems];
UIApplicationShortcutItem *anExistingShortcutItem = [existingShortcutItems objectAtIndex: anIndex];
NSMutableArray <UIApplicationShortcutItem *> *updatedShortcutItems = [existingShortcutItems mutableCopy];
UIMutableApplicationShortcutItem *aMutableShortcutItem = [anExistingShortcutItem mutableCopy];
[aMutableShortcutItem setLocalizedTitle: @“New Title”];
[updatedShortcutItems replaceObjectAtIndex: anIndex withObject: aMutableShortcutItem];
[[UIApplication sharedApplication] setShortcutItems: updatedShortcutItems];
```
3. 獲取ShortcutItem信息
如果程式通過 action 啟動,那麼可以在`- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions` 函數的 `launchOptions`里通過[UIApplicationLaunchOptionsShortcutItemKey] 取得item 信息。
如果程式在後臺,觸發了 action 事件,會調用`application:performActionForShortcutItem:completionHandler:`這個函數。
三、基於UITouch的 force 屬性
UITouch現在有了 force屬性,用於表示用戶按壓的力度,基於此可以實現不同力度的一些不同處理。
基於 UIGestureRecognizer
以及 UITouch 的 force 屬性,可以很容易寫出自定義的重按手勢。
1.引入頭文件
```
#import <UIKit/UIGestureRecognizerSubclass.h>
```
2.定義識別過程
主要是根據 touch 的幾種狀態,來設置手勢的對應狀態,重按的檢測關鍵在於touch的力度大到是麽程度可以認為識別成功。
3.其他手勢阻斷
重按如果和 tap 手勢一起使用,如何讓兩個手勢同時都能識別出來呢,這就需要設置阻斷。我的 demo 中在手勢失敗之前,一直阻斷了 tap 手勢,否則 tap 會一直同時識別出來。最後與 tap 共存的狀態,同 longPress 和 tap 共存的狀態類似。
四、支持判斷
在 6s 以下的機型中是不支持重按的,可以基於機型和系統版本來判斷。還有一種情況就是用戶在支持重按的機型上禁用了重按功能。設置-通用-輔助功能-3D Touch
,此時就要通過UITraitCollection 的 forceTouchCapability 來判斷。
監聽這個值的變化,UIScreen, UIWindow, UIViewController, UIPresentationController, 以及 UIView 都實現了 UITraitEnvironment
協議。該協議有如下方法監聽變化
- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection
參考:
1.https://developer.apple.com/reference/uikit/uiapplicationshortcutitem
2.https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple\_ref/doc/uid/TP40009252