ios 3D Touch功能的實現


ios9中3D Touch功能是一個新的亮點,這個方便快捷的功能實現也比較簡單,廢話不多說直接上代碼,

一.3D Touch功能添加分為兩種(1).靜態標簽 (2).動態標簽

(1).靜態添加

這個方法是在app的plist文件中添加如下圖的鍵值對,

先添加了一個UIApplicationShortcutItems的數組,這個數組中添加的元素就是對應的靜態標簽,在每個標簽中我們需要添加一些設置的鍵值:

必填項(下面兩個鍵值是必須設置的):

UIApplicationShortcutItemType 這個鍵值設置一個快捷通道類型的字符串 

UIApplicationShortcutItemTitle 這個鍵值設置標簽的標題

選填項(下面這些鍵值不是必須設置的)

UIApplicationShortcutItemSubtitle 設置標簽的副標題

UIApplicationShortcutItemIconType 設置標簽Icon類型

UIApplicationShortcutItemIconFile  設置標簽的Icon文件

UIApplicationShortcutItemUserInfo 設置信息字典(用於傳值)

(2).動態標簽

動態標簽是我們在程序運行過程中動態添加上去的,可以修改或者直接取消,與之相關的類,主要有三個:

UIApplicationShortcutItem 創建3DTouch標簽的類

UIMutableApplicationShortcutItem 創建可變的3DTouch標簽的類

UIApplicationShortcutIcon 創建標簽中圖片Icon的類

 @interface UIApplicationShortcutItem : NSObject <NSCopying, NSMutableCopying>
 //下面是兩個初始化方法 通過設置type,title等屬性來創建一個標簽,這里的icon是UIApplicationShortcutIcon對象,我們后面再說
 - (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;

接下來就是創建標簽

 /**
  *  手動添加3D touch功能
  */
 -(void)init3DTouchActionShow:(BOOL)isShow{
     
     /** type 該item 唯一標識符
      localizedTitle :標題
      localizedSubtitle:副標題
      icon:icon圖標 可以使用系統類型 也可以使用自定義的圖片
      userInfo:用戶信息字典 自定義參數,完成具體功能需求
      */
     
     UIApplication *application = [UIApplication sharedApplication];
     UIApplicationShortcutIcon *icon1 = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeLove];
     UIApplicationShortcutItem *item1 = [[UIApplicationShortcutItem alloc]initWithType:KTouchItemPublicPosition localizedTitle:@"我就是我" localizedSubtitle:@"還有什么" icon:icon1 userInfo:nil];
    
    UIApplicationShortcutIcon *icon2 = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeShare];
     UIApplicationShortcutItem *item2 = [[UIApplicationShortcutItem alloc]initWithType:KTouchItemMyPublic localizedTitle:@"你就是你" localizedSubtitle:@"你知道" icon:icon2 userInfo:nil];
     
     UIApplicationShortcutIcon *icon3 = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeCompose];
     UIApplicationShortcutItem *item3 = [[UIApplicationShortcutItem alloc]initWithType:KTouchItemRecharge localizedTitle:@"他就是他" localizedSubtitle:@"我不知道" icon:icon3 userInfo:nil];
     
     UIApplicationShortcutIcon *icon4 = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeCompose];
     UIApplicationShortcutItem *item4 = [[UIApplicationShortcutItem alloc]initWithType:KTouchItemCheck localizedTitle:@"她就是她" localizedSubtitle:@"不信算了" icon:icon4 userInfo:nil];
     if (isShow) {
         application.shortcutItems = @[item1,item2,item3,item4];
    }else{
         application.shortcutItems = @[];
     }
 }

動態方法添加可以在某個條件下取消3D Touch功能,比如登陸之前取消3D Touch功能和登陸之后添加3D Touch功能,代碼中的UIApplicationShortcutIconTypeShare等是系統風格的icon,這里只是舉個例子直接拿來用,但是不知道審核的時候會不會被拒。

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;

這里有幾點需要注意:

1、快捷標簽最多可以創建四個,包括靜態的和動態的,靜態標簽會一直存在。

2、每個標簽的題目和icon最多兩行,多出的會用...省略

3、我們在app的入口函數:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

也需要進行一下判斷,在launchOptions中有UIApplicationLaunchOptionsShortcutItemKey這樣一個鍵,通過它,我們可以區別是否是從標簽進入的app,如果是則處理結束邏輯后,返回NO,防止處理邏輯被反復回調。

二.響應標簽的行為

當我們點擊標簽進入應用程序時,也可以進行一些操作,我們可以看到,在applocation中增加了這樣一個方法:

- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void(^)(BOOL succeeded))completionHandler NS_AVAILABLE_IOS(9_0);(要注意上面的第三點)

當我們通過標簽進入app時,就會在appdelegate中調用這樣一個回調,我們可以獲取shortcutItem的信息進行相關邏輯操作。

 #pragma mark -3Dtouch功能
 - (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void(^)(BOOL succeeded))completionHandler{
     //判斷先前我們設置的唯一標識
     NSLog(@"選擇了3Dtouch功能--%@",shortcutItem.type);
     UIViewController *myVC;
     if ([shortcutItem.type isEqualToString:KTouchItemPublicPosition]) {
         myVC = [[YBSPublicViewController alloc]initWithNibName:@"YBSPublicViewController" bundle:nil];
    }else if ([shortcutItem.type isEqualToString:KTouchItemMyPublic]){
         myVC = [[YBSPositionViewController alloc]initWithNibName:@"YBSPositionViewController" bundle:nil];
     }else if ([shortcutItem.type isEqualToString:KTouchItemRecharge]){
         myVC = [[YBSResumeViewController alloc]initWithNibName:@"YBSResumeViewController" bundle:nil];
     }else if ([shortcutItem.type isEqualToString:KTouchItemCheck]){
         myVC = [[YBSResumeViewController alloc]initWithNibName:@"YBSResumeViewController" bundle:nil];
     }
     YBSNavigationViewController *nav = [[YBSNavigationViewController alloc]initWithRootViewController:myVC];
     //設置當前的VC 為rootVC
     [self.window.rootViewController presentViewController:nav animated:YES completion:nil];
    
 }
這里面主要是做一個例子,顯示的視圖跳轉 要根據具體情況加上

效果圖

三. 3D Touch ViewController  彈出自定義的ViewContoller,向上滑動還有下一步的菜單可以顯示

首先在viewController的.m方法中添加下面代碼,判斷當前設備是否支持壓力感,並注冊delegate

//注冊3D Touch,先判斷是否可用
    if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable){
         [self registerForPreviewingWithDelegate:self sourceView:self.view];
         NSLog(@"3D Touch  可用!");
    }else{
         NSLog(@"3D Touch 無效");
    }

添加你想要彈出來的viewcontroller,

/**
 *  peek手勢
 */
-(UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location{
    
     // 獲取用戶手勢點所在cell的下標。同時判斷手勢點是否超出tableView響應范圍。
     if (![self getShouldShowRectAndIndexPathWithLocation:location]) return nil;
     //彈出視圖的初始位置,sourceRect是peek觸發時的高亮區域。這個區域內的View會高亮顯示,其余的會模糊掉
     previewingContext.sourceRect = sourceRect;
    //獲取數據進行傳值
    YBS3DTouchViewController *childVC = [[YBS3DTouchViewController alloc] init];
     return childVC;
}

/**
 *  pop手勢
 */
-(void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit{
     [self tableView:self.myTableView didSelectRowAtIndexPath:selectedPath];
}

/**
 *  獲取用戶手勢點所在cell的下標,同時判斷手勢點是否超出tableview的范圍
 */
- (BOOL)getShouldShowRectAndIndexPathWithLocation:(CGPoint)location {
    //坐標點的轉化,
    CGPoint tableLocation = [self.view convertPoint:location toView:self.myTableView];
    selectedPath = [self.myTableView indexPathForRowAtPoint:tableLocation];
    sourceRect = CGRectMake(0, selectedPath.row * KMessageRowHeight, ScreenHeight, KMessageRowHeight);
     // 如果row越界了,返回NO 不處理peek手勢
    NSLog(@"當前所在的行---%zd",selectedPath.row);
     return (selectedPath.row >= (self.messageArr.count+10)) ? NO : YES;
 }

接下來在添加的視圖中,添加向上滑顯示的菜單,上面代碼中YBS3DTouchViewController *childVC,視圖中我就是簡單定義了一個backView和一個label,下面是在-(NSArray<id<UIPreviewActionItem>> *)previewActionItems函數中定義你要顯示的菜單

/**
 *  3D Touch 上移顯示的視圖
 */
-(NSArray<id<UIPreviewActionItem>> *)previewActionItems{
    UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"我就是我" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"click---我就是我");
        
    }];
    
    UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"你還是你" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"click---你還是你");
    }];
    
    UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"她還是她" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"click---她還是她");
    }];
    //想要顯示多個就定義多個 UIPreviewAction
    NSArray *actions = @[action1,action2,action3];
    return actions;
}

在block里面進行的一個回調,在這里處理你的點擊事件,效果如下

學習的就這么多,有更多的,后面加上😊

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM