開源轉場庫HYBControllerTransitions

首發博客:標哥的技術博客

中文文檔

HYBControllerTransitions是自定義圍場動畫API封裝類庫,使用簡便。使用者不需要了解太多轉場動畫知識,即可輕鬆接入項目使用。

這是一個給開發者們提供自定義push、pop、dismiss和present轉場動畫的開源組件。現在庫中支持泡泡放大縮小圍場、模態半屏轉場和移動切換轉場(KeyNote某轉場效果)。對於開發者們來說,這是一個很不錯的開源庫。開發者不需要了解轉場知識,只需要簡單一個API就可以實現對應的功能。

如果想要更深入地學習,請在源碼中查看對應的註釋說明!

image

開源目標

在設計此類庫時,希望以最簡潔的API來實現轉場功能。如果不懂任何轉場知識的人,也能輕鬆使用,那纔算達到目標。

因此,如果您沒有學習過相關轉場方面的知識,請不要擔心,這個類庫不需要您掌握太多轉場的知識,只需要懂基本的OC語法即可輕鬆接入項目使用。

公共的屬性及API都封裝在HYBBaseTransition類型中,它遵守了需要實現轉場的所有協議並實現之。如果目前類庫中所提供的效果不滿足您的需求,您可以直接繼承於HYBBaseTransition於實現您希望得到的效果。

支持彈簧動畫效果

默認轉場動畫使用的不是彈簧動畫效果,如果覺得彈簧動畫效果更佳,僅需要設置爲YES即可。

/**
 *  Default is NO, if set to YES, it will be presented and dismissed with
 *  spring animation.
 */
@property (nonatomic, assign) BOOL animatedWithSpring;

當然,使用到彈簧自然需要設置其參數。不過作者都提供有默認值,都是經過調試過得到的值。如果覺得默認值所得到的效果不夠好,請自行調整參數:

/**
 * The initial Spring velocity, Only when animatedWithSpring is YES, it will take effect.
 * Default is 1.0 / 0.5. If you don't know, just use the default value.
 */
@property (nonatomic, assign) CGFloat initialSpringVelocity;

/**
 *  The Spring damp, Only when animatedWithSpring is YES, it will take effect.
 *
 *  Default is 0.5. If you don't know, just use the default value.
 */
@property (nonatomic, assign) CGFloat damp;

轉場類型動畫

目前所支持的動畫效果有以下:

  • Bubble Effect Transition:泡泡放大、縮小的動畫效果,僅支持模態呈現present/dismiss。
  • Modal Effect Transition:半屏呈現轉場,支持設置縮放係數、呈現高度等,僅支持模態呈現present/dismiss。
  • Move Push/Pop Transition:移動切換轉場效果,僅支持push/pop模式。

Buble Effect Transition

present時,以泡泡圓形放大;dismiss時,以泡泡圓形縮小至起點。當需要實現此轉場效果時,請使用HYBBubbleTransition類型。效果圖如下:

image

如何使用

使用起來非常簡單,只需要一個API且只在一處調用即可。比如,現在有HYBModalBubbleViewController,它有一個點擊事件,在點擊後會回調onPresent函數,然後配置如下即可實現轉場:

- (void)onPresent {
  HYBBubbleFromBottomController *vc = [[HYBBubbleFromBottomController alloc] init];
  vc.modalPresentationStyle = UIModalPresentationCustom;

  // Remember to own it strongly
  // Because delegate is weak reference, and it will be released after out of the function body.
  self.bubbleTransition = [[HYBBubbleTransition alloc] initWithPresented:^(UIViewController *presented, UIViewController *presenting, UIViewController *source, HYBBaseTransition *transition) {
    // You need to cast type to the real subclass type.
    HYBBubbleTransition *bubble = (HYBBubbleTransition *)transition;

    // If you want to use Spring animation, set to YES.
    // Default is NO.
//    bubble.animatedWithSpring = YES;
    bubble.bubbleColor = presented.view.backgroundColor;

    // 由於一個控制器有導航,一個沒有,導致會有64的誤差,所以要記得處理這種情況
    CGPoint center = [self.view viewWithTag:1010].center;
    center.y += 64;

    bubble.bubbleStartPoint = center;
  } dismissed:^(UIViewController *dismissed, HYBBaseTransition *transition) {
    // Do nothing and it is ok here.
    // If you really want to do something, here you can set the mode.
    // But inside the super class, it is set to be automally.
    // So you do this has no meaning.
    transition.transitionMode = kHYBTransitionDismiss;
  }];
  vc.transitioningDelegate = self.bubbleTransition;

  [self presentViewController:vc animated:YES completion:NULL];
}

這裏會present HYBBubbleFromBottomController這個控制器類,但是HYBBubbleFromBottomController對象什麼也不需要做,就可以直接實現了轉場。

是不是真的很簡單呢?

如果想要了解更多功能功能,請在源代碼中查看類中所提供的所有公開屬性,幾乎都有默認值,若不需要修改,直接使用默認值就可以了。

注意事項:一定要將代理設置爲對應的轉場類對象。而且一定要在當前控制器強引用該轉場類對象,因爲設置爲轉場代理,只是弱使用,如果沒有強引用,它就會被釋放掉:

// 代理不再是設置爲self,而是設置爲轉場對象
vc.transitioningDelegate = self.bubbleTransition;

當需要實現半屏呈現且帶縮放效果的轉場動畫時,可以使用此HYBModalTransition類。它僅支持present/dismiss模式。它提供了更多的屬性設置,稍候講解。效果如下:

image

如何使用

使用非常簡單。假設在HYBModalHalfController有一個點擊事件,點擊後會回調onPresent函數,只需要在此函數中實現即可:

- (void)onPresent {
  HYBModalHalfDetailController *vc = [[HYBModalHalfDetailController alloc] init];

  self.transition = [[HYBModalTransition alloc] initWithPresented:^(UIViewController *presented, UIViewController *presenting, UIViewController *source, HYBBaseTransition *transition) {
    HYBModalTransition *modal = (HYBModalTransition *)transition;
    modal.scale = (CGPoint){0.95, 0.95};

    // If you don't specify, it will use default value
//    modal.presentedHeight = 350.0;

    // If you don't want to, set to YES or do no set.
    modal.shouldDismissOnTap = YES;

    // Default is NO, if set to YES, it will use spring animation.
    modal.animatedWithSpring = YES;

    // Default is YES. including navigation bar when take snapshots.
    // When has navigation bar, if set to NO, it looks not so good.
//    modal.scapshotIncludingNavigationBar = NO;
  } dismissed:^(UIViewController *dismissed, HYBBaseTransition *transition) {
    // do nothing
    // 註釋掉也沒有關係,內部已經自動設置了。
    transition.transitionMode = kHYBTransitionDismiss;
  }];

  vc.transitioningDelegate = self.transition;
  [self presentViewController:vc animated:YES completion:NULL];
}

對於HYBModalHalfDetailController控制器類,什麼也不需要操作。這是不是有點太過於簡單了?對於dismissed這個block,其實這裏完全可以設置爲nil,因爲不需要做任何操作,默認就自動設置了mode。

支持帶導航截圖

如果當前控制器類有導航,最好還是連導航條也一起生成截圖,這樣效果會好很多。默認就是YES。如果不希望如此,請手動設置爲N:

/**
 *  Whether to include navigation bar when take snapshots.
 *  Default is YES. If NO, it has only the presenting view.
 */
@property (nonatomic, assign) BOOL scapshotIncludingNavigationBar;

支持手勢點擊自動Dismiss

在彈出來之後,默認是添加了點擊手勢,可以自動dismiss。默認爲YES,如果不希望如此,請手動設置爲NO:

/**
 *  When tap on the presenting view, should it automatically is dismissed.
 *
 *  Default is YES.
 */
@property (nonatomic, assign) BOOL shouldDismissOnTap;

支持設置縮放、高度

都提供了默認值,但是如果想要調整到一個讓您滿意的效果,也許這些屬性就可以幫助您實現:

/**
 *  Make the from view scale to the specified scale.
 *
 *  Default is (0.9, 0.9)
 */
@property (nonatomic, assign) CGPoint scale;

/**
 *  The height for destination view to present.
 *  
 *  Default is half of destination view, it means desView.frame.size.height / 2
 */
@property (nonatomic, assign) CGFloat presentedHeight;

Move Push/Pop Transition

類似於KeyNote的神奇移動效果push、pop動畫。效果圖如下:

image

使用起來也是很簡單的,不同於present/dismiss模式,由於push的時候還不能得到轉場過去的目標視圖,比如效果圖中的切換過去後看到的圖片控件。在創建控制器類的時候,控件是不存在的,因此只能使用其它的辦法來實現。

這裏所採用的方案是通過給UIViewController添加擴展屬性,如此就可以在創建UI的地方,將目標控件賦值。擴展所添加的屬性爲:

/**
 * Set a target view to show. When push, it will transition to
 * the target view. and when poped, it will pop from the target view.
 */
@property (nonatomic, strong, nonnull) UIView *hyb_toTargetView;

如何使用

假設當前控制器類爲HYBMoveViewController,它有一個collectionview,呈風格佈局顯示一個圖片列表。當點擊cell的時候,就切換(push)到HYBMoveDetailController控制器中顯示更多內容。

實現如下:


- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
  HYBMoveDetailController *vc = [[HYBMoveDetailController alloc] init];
  HYBGridModel *model = self.datasource[indexPath.item];
  vc.image = model.clipedImage;

  self.transition = [[HYBMoveTransition alloc] initWithPushed:^(UIViewController *fromVC, UIViewController *toVC, HYBBaseTransition *transition) {
    HYBMoveTransition *move = (HYBMoveTransition *)transition;
    HYBGridCell *cell = (HYBGridCell *)[collectionView cellForItemAtIndexPath:indexPath];
    move.targetClickedView = cell.imageView;

    move.animatedWithSpring = YES;
  } poped:^(UIViewController *fromVC, UIViewController *toVC, HYBBaseTransition *transition) {
    // Do nothing, unless you really need to.
  }];

  self.navigationController.delegate = self.transition;
  [self.navigationController pushViewController:vc animated:YES];
}

在點擊的時候,需要創建一個轉場對象,然後我們將導航類的代理設置爲這個轉場對象,如下:

self.navigationController.delegate = self.transition;

這樣就可以實現內部自動處理了。當push的時候,會回調pushed閉包,在這裏返回了轉場對象,需要提供相關屬性設置,才能實現。一定要傳targetClickedView屬性,這是被點擊的控件,也是用於切換效果用的。

在HYBMoveDetailController控制器中,在viewDidLoad這裏創建UI的地方,創建了一個圖片控件,然後如些設置:

// You must specify a target view with this.
self.hyb_toTargetView = imgView;

OK,到此就實現好功能了!

是否足夠簡單?

如何安裝

支持pod,可直接使用pod添加以下代碼到Podfile中:

pod 'HYBControllerTransitions', '~> 1.0.0'

如果您的工程不支持Pod,呆直接將HYBControllerTransitions目錄放到您的工程中即可!

源代碼

如果不想使用pod來安裝,或者想要看看demo,請到此處下載:HYBControllerTransitions

致謝

非常感謝andreamazz,學習了很多他的開源作品!

MIT LICENSE

Copyright (c) 2016 CoderJackyHuang. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the “Software”),
to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

發佈了498 篇原創文章 · 獲贊 35 · 訪問量 242萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章