Animation transitions

Đã lâu rồi không viết một bài gì, nhân tiệc việc ở cty đang ít, mình có viết 1 bài làm seminar cho các thành viên trong team về việc tạo animation giữa các viewcontroller. Bài viết cũng chỉ là sự tổng hợp của các tut đã có trên mạng, mình chỉ cố viết lại theo cách đơn giản nhất để ai cũng có thể tiếp cận. Giờ public cho mọi người cùng thưởng thức.

Ngoài lề chút, hiện tại thì trên mạng có trang này http://samvlu.com/ viết về quá trình 100 ngày code swift và có bán bài giảng. :smiley: Mình định chơi 1 trang tương tự nhưng open source. Hi vọng sẽ sớm ra mắt mọi người.

Giới thiệu

Bắt đầu từ IOS7, apple hỗ trợ tạo animation lúc chuyển viewcontroller. Quá trình chuyển đổi được hỗ trợ bao gồm:

  • NavigationController
  • TabbarController
  • Presentations và dismiss

Mình sẽ tập trung vào custom animation pushpop với NavigationController. Với các phương thức chuyển viewcontroller khác thì làm tương tự.

Mô hình hóa

Giả sử bạn có 2 viewcontroller A và B, bây giờ bạn muốn push từ A sang B.

Đầu tiên, ta cần khởi tạo transtion và xác định được 2 viewcontroller cần di chuyển, lúc này A đang được chứa bởi container(là view chứa để control việc di chuyển)

Tiếp theo add viewcontroller B vào container đang chứa A.

Cuối cùng là thực hiện animation chuyển đổi giữa 2 màn hình, quá trình kết thúc khi A được remove khỏi container

Implement

Để thực hiện được mô hình trên, ta sử dụng những protocol sau

UINavigationControllerDelegate

Protocol có 2 method giúp ta xác định được cách thức transition

- (nullable id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
                          interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController NS_AVAILABLE_IOS(7_0);

- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                   animationControllerForOperation:(UINavigationControllerOperation)operation
                                                fromViewController:(UIViewController *)fromVC
                                                  toViewController:(UIViewController *)toVC  NS_AVAILABLE_IOS(7_0);

Hàm đầu tiên dùng để tạo animation khi touch vào màn hình, trả về object implement UIViewControllerInteractiveTransitioning.

Hàm thứ hai xác định cách thức push/pop khi ta click action (next/back) trên thanh navigation bar, trả về object implement UIViewControllerAnimatedTransitioning. Các params giúp ta xác định được fromVC là viewcontroller nào, toVC là viewcontroller nào. Ở trường hợp di chuyển từ A sang B thì A là fromVC và B là toVC.
Cuối cùng là param operation, đây là enum gồm có 3 value để xác định trạng thái push hay pop

 UINavigationControllerOperationNone,
 UINavigationControllerOperationPush,
 UINavigationControllerOperationPop,

UIViewControllerAnimatedTransitioning

có 2 phương thức

- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext;

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;

Để thực hiện animation ta cần 2 thông số, thông số đầu tiên là duration, hàm đầu tiên giúp ta xác định được điều đó. Phương thức thứ hai dùng để implement animation chuyển đổi. Trong hàm này ta cần đưa ra thông báo để biết được quá trình push/pop được hoàn thành

[transitionContext completeTransition:![transitionContext transitionWasCancelled]];

Example

Bước 1: Tạo ra object implement protocol UIViewControllerAnimatedTransitioning, trước hết xác định duration

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return 0.25;
}

Định nghĩa một animation đơn giản


/**
 * using example in 
 * https://www.objc.io/issues/5-ios7/view-controller-transitions/ 
 */

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    //1.
    UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    //2.
    [[transitionContext containerView] addSubview:toViewController.view];
    toViewController.view.alpha = 0;

    //3.
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        fromViewController.view.transform = CGAffineTransformMakeScale(0.1, 0.1);
        toViewController.view.alpha = 1;
    } completion:^(BOOL finished) {
        fromViewController.view.transform = CGAffineTransformIdentity;

        //4.
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];

    }];

}

Phân tích chút nào:

  • Bước 1: xác định toViewController và fromViewController
  • Bước 2: add toViewController.view vào trong container
  • Bước 3: thực hiện animation.
  • Bước 4: thông báo animation kết thúc qua câu lệnh completeTransition

Bước 2:
Tạo object implement protocol UINavigationControllerDelegate, trong object này ta cần truyền vào object đã implement UIViewControllerAnimatedTransitioning trước đó.

-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                 animationControllerForOperation:(UINavigationControllerOperation)operation
                                              fromViewController:(UIViewController *)fromVC
                                                toViewController:(UIViewController *)toVC
{
    // return your custom animation transition
}

Bước 3
Setting ở viewcontroller, như ở trên ta có viewcontroller A -> B. Ở A ta cần làm như sau trước khi push.

//1.
self.navigationController.delegate = /* your custom UINavigationControllerDelegate */;
//2.
[self.navigationController pushViewController:B animated:YES];

Ở bước này ta đã có thể push/pop với animation, nhưng để full service ta sẽ gắn thêm interactive animations. Tuy nhiên ở giới hạn bài viết này mình sẽ chỉ nói về animation cho push và pop. Bạn có thể tìm hiểu chi tiết hơn ở ví dụ của trang objc.io

Một animation mình làm

gif

Bài viết có tham khảo

3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?