淺談3D Touch(2) -- UITouch && Peek && Pop

UITouch

之所以先說UITouch是因為從Peek到Pop這個過程中,相信其內(nèi)部用到了這個東西,我們來看一下iOS9在這個UITouch中加了哪些東西:

  • UIForceTouchCapability
    • UIForceTouchCapabilityUnknown //3D Touch檢測失敗
    • UIForceTouchCapabilityUnavailable //3D Touch不可用
    • UIForceTouchCapabilityAvailable //3D Touch可用

這3個枚舉值就是我們來判斷設(shè)備是否開啟3D Touch功能,可以在UIViewController生命周期的viewWillAppear中我們是這么判斷的:

if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
{
    xxxxxxxx
}

當然在生命周期內(nèi),如果用戶有意修改了設(shè)備的3D Touch功能,我們還有一個地方來重新檢測:

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection

剛剛說了Peek和Pop和這個有關(guān),對的,就是這個類中的force屬性以及他的最大值maximumPossibleForce,我們在UIView上做一個簡單的實驗

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    NSLog(@"%f",touch.force);
    self.backgroundColor = [UIColor colorWithRed:(touch.force / touch.maximumPossibleForce )green:0 blue:1 alpha:1];
    
}

按的越重,這個view的red就越大

img_3

img_4

為了得到maximumPossibleForce值,我故意在這個函數(shù)中加上了

if (touch.force == touch.maximumPossibleForce)
{
    NSLog(@"%f",touch.force);
}

輸出發(fā)現(xiàn)當3D touch開的時候這個值為20/3,所以得到結(jié)論force是從0~20/3
從Peek到Pop也正是根據(jù)這個值大于某個指定的值時觸發(fā)

Peek & Pop

剛剛說了Peek和Pop的觸發(fā)和UITouch的force有關(guān),在切入正題之前我們還要將觸發(fā)這2個事件的另一個東西:

previewActionItems

我們創(chuàng)建一個PeekViewController,在這個利用到了UIPreviewAction 和 UIPreviewActionGroup 2個iOS9新加的類型和他們的初始化方法我們重寫

- (NSArray <id <UIPreviewActionItem>> *)previewActionItems

從而來定義previewActionItems,這里沒什么難度直接上代碼

- (NSArray<id<UIPreviewActionItem>> *)previewActionItems
{
    
    // 生成UIPreviewAction
    UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"Action 1" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Action 1 selected");
    }];
    
    UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"Action 2" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Action 2 selected");
    }];
    
    UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"Action 3" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"Action 3 selected");
    }];
    
    UIPreviewAction *tap1 = [UIPreviewAction actionWithTitle:@"tap 1" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"tap 1 selected");
    }];
    
    UIPreviewAction *tap2 = [UIPreviewAction actionWithTitle:@"tap 2" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"tap 2 selected");
    }];
    
    UIPreviewAction *tap3 = [UIPreviewAction actionWithTitle:@"tap 3" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) {
        NSLog(@"tap 3 selected");
    }];
    
    // 塞到UIPreviewActionGroup中
    NSArray *actions = @[action1, action2, action3];
    NSArray *taps = @[tap1, tap2, tap3];
    UIPreviewActionGroup *group1 = [UIPreviewActionGroup actionGroupWithTitle:@"Action Group" style:UIPreviewActionStyleDefault actions:actions];
    UIPreviewActionGroup *group2 = [UIPreviewActionGroup actionGroupWithTitle:@"Action Group" style:UIPreviewActionStyleDefault actions:taps];
    NSArray *group = @[group1,group2];
    
    return group;
}

我們發(fā)現(xiàn)他是一個二維結(jié)構(gòu),所以能展示的東西還是非常多的。

好了準備工作到此結(jié)束,我們切入正題
在ViewController中,創(chuàng)建一個label作為觸發(fā)的view

_label = [[UILabel alloc] initWithFrame:CGRectMake(10, 300, self.view.frame.size.width - 20, 100)];
_label.userInteractionEnabled = YES;
_label.textAlignment = NSTextAlignmentCenter;
_label.backgroundColor = [UIColor yellowColor];
_label.font = [UIFont boldSystemFontOfSize:20];
_label.text = @"Peek && Pop";
[self.view addSubview:_label];

然后檢測是否可以使用3DTouch,如果可以就注冊:

- (void)check3DTouch
{
    // 如果開啟了3D touch
    if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
    {
        [self registerForPreviewingWithDelegate:(id)self sourceView:_label];
        
    }
}

最后我們來寫Peek和Pop的代理方法

  • peek:
- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location
{
    //防止重復(fù)加入
    if ([self.presentedViewController isKindOfClass:[PeekViewController class]])
    {
        return nil;
    }
    else
    {
        PeekViewController *peekViewController = [[PeekViewController alloc] init];
        return peekViewController;
    }
}

這個代理在按的過程中會進來多次,但是我們并不需要多個peek對象,所以如果觸發(fā)的self.presentedViewController和我們想要的peekViewController已經(jīng)是同一個了,那就return nil,我們按label在出現(xiàn)peekViewController的時候向上移動我們能看到剛剛創(chuàng)建的previewActionItems的2個group

img_5

點開一個就能看到我們沒個group的items

img_6

點擊就會觸發(fā)我們剛剛在block中定義的事件

  • Pop:
    在Peek的基礎(chǔ)上不要向上移動,而是按得更重一些,個人感覺已經(jīng)到了maximumPossibleForce這個時候觸發(fā)代理:
- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit
{
    PopViewController *popViewController = [[PopViewController alloc] init];
    [self showViewController:popViewController sender:self];
}

這時候我們看到了PopViewController

img_7

當然我們在PopViewController還需要給他加個dismiss的方法,讓他可以回去

好了,官方說的所有3D Touch的功能都介紹好了,這是我的Demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 3D Touch簡介 2015年,蘋果發(fā)布了iOS9以及iphone6s/iphone6s Plus,其中最具有創(chuàng)...
    愛恨的潮汐閱讀 439評論 0 2
  • 前言 關(guān)于這篇文章 由于iPhone 6S發(fā)布不到一年的時間,很多新特性、新技術(shù)還未普遍,不管是3D Touch的...
    Tangentw閱讀 4,741評論 8 18
  • 3D Touch簡介 2015年,蘋果發(fā)布了iOS9以及iphone6s/iphone6s Plus,其中最具有創(chuàng)...
    簡簡蝸牛閱讀 717評論 0 0
  • 前言 對于3DTouch很多人都已經(jīng)并不陌生了,因為iPhone 6s想必大家都已經(jīng)體驗過了,深度按壓帶來的體驗仁...
    Smallwolf_JS閱讀 1,796評論 4 10
  • 3D Touch介紹 從iPhone 6s開始,產(chǎn)品都添加了一項硬件屬性,叫做3D touch。作為屏幕的一部分,...
    歪筆書生_閱讀 708評論 0 0

友情鏈接更多精彩內(nèi)容