【iOS Framework】新特性3DTouch

一、按壓圖標 彈出菜單

 

WeChat_1469066154.jpeg

像上圖那樣,按壓圖標 彈出菜單。這是應用最多的場景。那麼如何實現呢?有兩種方法:git

 

靜態的:

在info.plist添加以下鍵值對,每個Item表明一個標籤按鈕,你能夠添加標題,副標題,可使用系統圖標,也可使用你本身的圖片資源做爲圖標,只需添加你的圖片名稱便可。下面列舉經常使用的鍵值對:github

/*
     經常使用鍵值對
     
     UIApplicationShortcutItemTitle  標題

     UIApplicationShortcutItemType   類型能夠設置標識符
   
     UIApplicationShortcutItemIconType   圖標類型,可設置系統圖標樣式

     UIApplicationShortcutItemSubtitle   副標題

     UIApplicationShortcutItemUserInfo   可存放一個字典,經過這個傳值

*/

屏幕快照 2016-07-21 上午10.06.28.png

 

​下面列舉系統支持的圖標類型,根據你的需求來獲取吧。數組

屏幕快照 2016-07-21 上午10.04.12.png

 

動態的:

//建立圖標3DTouch 菜單
- (void)codeAddItems{
    
    //系統風格的icon
    UIApplicationShortcutIcon *share = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeShare];
    
    //使用自定義圖標
    UIApplicationShortcutIcon *saoyisao = [UIApplicationShortcutIcon iconWithTemplateImageName:@"erweima"];
    
    //建立快捷選項 type 標識符
    UIApplicationShortcutItem * item1 = [[UIApplicationShortcutItem alloc]initWithType:@"com.occode.app.share" localizedTitle:@"分享" localizedSubtitle:@"分享副標題" icon:share userInfo:nil];
    
    UIApplicationShortcutItem * item2 = [[UIApplicationShortcutItem alloc]initWithType:@"com.mycompany.app.saoyisao" localizedTitle:@"掃一掃" localizedSubtitle:@"掃一掃副標題" icon:saoyisao userInfo:nil];
    
    //添加到快捷選項數組
    [UIApplication sharedApplication].shortcutItems = @[item1,item2];
    
}

 

運行效果:瀏覽器

 

小結:

動態標籤不能覆蓋靜態標籤,但能夠追加,最多支持四個標籤。微信

 

點擊標籤後的響應

app未啓動時:

點擊後,咱們能夠從launchOptions中捕捉到UIApplicationShortcutItem,從而根據其類型來處理咱們想要的結果:app

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

 

捕捉UIApplicationShortcutItem,此時咱們須要return NO而不是YES;函數

//若是是從快捷選項標籤啓動app,則根據不一樣標識執行不一樣操做,而後返回NO
UIApplicationShortcutItem *shortcutItem = [launchOptions valueForKey:UIApplicationLaunchOptionsShortcutItemKey];
if (shortcutItem) {
    //根據Item的類型來進一步處理
   [self showForItem:shortcutItem];
    return NO;
}

 

app在後臺時:

須要實現下面這個函數:測試

- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler;字體

 

具體實現以下: 

//若是app在後臺,經過快捷選項標籤進入app,則調用該方法
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler {

    //判斷先前咱們設置的快捷選項標籤惟一標識,根據不一樣標識執行不一樣操做
    [self showForItem:shortcutItem];
    
    if (completionHandler) {
        completionHandler(YES);
    }
}

 

 

二、Peek 與 Pop

首先來看看微信的效果圖:

 

Peek,偷偷一看,即輕按預覽:

 

具體實現步驟以下:

第一步:讓控制器遵照代理<UIViewControllerPreviewingDelegate>

第二步:判斷該設備是否支持3DTouch

//判斷是否支持3DTouch
- (BOOL)isValidForceTouch{
    return self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable;
}

第三步:若是支持3DTouch,則給這個cell註冊3DTouch預覽功能,遵照代理

//給這個cell註冊3DTouch預覽功能
[self registerForPreviewingWithDelegate:self sourceView:cell];

第四步:實現Peek協議方法

// peek 預覽
- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location{
    //按壓的行
    NSIndexPath * indexPath = [_tableView indexPathForCell:(UITableViewCell *)[previewingContext sourceView]];
    //預覽界面
    ShowViewController * showVC = (ShowViewController *)[self vcForSBID:kShowVCId];
    showVC.title = @"我是按進來的";
    showVC.text = [self selectedTextForRow:indexPath.row];
    //臨時顯示自定義的導航
    [showVC showTitle];
    
    return showVC;
}

看下運行效果:

Pop,重按進入:

第五步:實現Pop協議方法

//pop 進入
- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit{
    ShowViewController * showVC = (ShowViewController *)viewControllerToCommit;
    //隱藏咱們臨時的導航,由於進入後有真正的導航
    [showVC hideTitle];
    [self showViewController:viewControllerToCommit sender:self];
}

運行效果圖:

三、預覽菜單

先來看看微信的效果圖:

 

 

咱們只須要在預覽控制器裏實現以下方法,返回一個UIPreviewActionItem的數組:

//peek 時上滑出現的菜單
- (NSArray<id<UIPreviewActionItem>> *)previewActionItems {
    // 普通樣式
    UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"Aciton1" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Aciton1");
    }];
    
    //已被選擇的樣式 後面有個對勾
    UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"Aciton2" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Aciton2");
    }];
    
    //警示樣式(紅色字體)
    UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"Aciton3" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Aciton3");
    }];
    
    NSArray *actions = @[action1,action2,action3];
    
    return actions;
}

運行效果圖:

四、關於導航、按壓視圖大小、預覽視圖的比例等

關於導航欄:

細心地同窗發現,預覽的界面是沒有導航欄的,微信是怎麼實現的呢?我在試了不少方法,發現「在peek是顯示一個自定義的導航欄,pop時隱藏自定義的導航欄」是一個可行的辦法(若是哪位同窗知道更好的辦法能夠聯繫本人!!)。

 

關於按壓視圖大小:

有時候咱們只想按壓某一個區域來預覽,而不是整個cell,也許是cell上的label,或view上的某一個區塊,這時候咱們能夠改變顯示的上下文視圖的Rect來改變:

previewingContext.sourceRect = CGRectMake(0, 0, 300, 20);

 

關於預覽視圖比例:

預覽視圖的大小是能夠改變的,若是你按壓的是一個圖片,pop出圖片瀏覽器,顯然效果不是那麼理想,咱們能夠根據圖片的大小來設置預覽視圖的大小:

// peek 預覽
- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location{
    
    //預覽界面
    PhotoViewController * pvc = [[PhotoViewController alloc]init];
    pvc.image = _imageView.image;
    
    //設置預覽視圖的比例 能夠看出 預覽視圖的寬高比例 圖片的比例是一致的
    pvc.preferredContentSize = CGSizeMake(_imageView.image.size.width, _imageView.image.size.height);
    
    return pvc;
}

 

預覽視圖比例演示效果以下:

 

五、捕獲「壓力值」

經過touchesBegan、touchesMoved等方法來捕獲,獲取force值:

//按住移動or壓力值改變時的回調
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    NSArray *arrayTouch = [touches allObjects];
    UITouch *touch = (UITouch *)[arrayTouch lastObject];

    NSLog(@"move壓力 = %f",touch.force);
    
    //label顯示壓力值
    _textLabel.text = [NSString stringWithFormat:@"壓力%f",touch.force];

    self.view.backgroundColor = [self colorForForce:touch.force];
}

經測試發現壓力的範圍是0.06666...~6.6666...,須要注意的是 這裏的force 」壓力「值 並非以牛頓爲單位的物理上的力,而表明的是一個相對的參考系 咱們經過0.666... ~ 6.666... 來模擬壓力的小和大。例如:我吧force值和顏色對應起來,按得越重,背景顏色就越黑。

 

效果以下:

 

六、結束語

3DTouch用處還未被徹底挖掘,但願iOS Coder能夠用它開發出更有意思的產品和功能。

 

七、Demo地址

github:

https://github.com/ly918/Demos

相關文章
相關標籤/搜索