UINavigationController push pop动画自定义

一、需求:优化系统push pop动画卡顿问题。

二、实现思路:UINavigationController子类中拦截push pop方法,屏蔽系统动画,用自己的动画。

代码如下:

BaseNavigationController.h文件

#import 

NS_ASSUME_NONNULL_BEGIN

@interface BaseNavigationController : UINavigationController

@end

NS_ASSUME_NONNULL_END

BaseNavigationController.m文件

#import "BaseNavigationController.h"

@implementation BaseNavigationController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    if (animated) {
        CATransition *transition = [[CATransition alloc] init];
        transition.duration = 0.25;
        transition.type = kCATransitionPush;
        transition.subtype = kCATransitionFromRight;
        [self.view.layer addAnimation:transition forKey:nil];
    }
    [super pushViewController:viewController animated:NO];
}

- (UIViewController *)popViewControllerAnimated:(BOOL)animated {
    if (animated) {
        [self.view.layer addAnimation:[self popTransition] forKey:nil];
    }
    return [super popViewControllerAnimated:NO];
}

- (NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated {
    if (animated) {
        [self.view.layer addAnimation:[self popTransition] forKey:nil];
    }
    return [super popToViewController:viewController animated:NO];
}

- (NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated {
    if (animated) {
        [self.view.layer addAnimation:[self popTransition] forKey:nil];
    }
    return [super popToRootViewControllerAnimated:NO];
}

- (CATransition *)popTransition {
    CATransition *transition = [[CATransition alloc] init];
    transition.duration = 0.25;
    transition.type = kCATransitionPush;
    transition.subtype = kCATransitionFromLeft;
    return transition;
}

@end

知识点:
Core Animation包括属性动画(CAPropertyAnimation)、动画组(CAAnimationGroup)和转场动画(CATransition)。属性动画是作用图层(Layer)的动画属性,动画组是前者的组合。
不能做动画的属性或者图层之间的关系改动就要用到过度动画。
CATransition边写代码边加注释作为介绍:

CATransition *transition = [[CATransition alloc] init];
// 动画执行时间。测试时候想看效果可以把时间调长看看,看的很清晰
transition.duration = 0.25;
// 动画样式,下面有列出详情
transition.type = kCATransitionPush;
// 控制动画的方向
transition.subtype = kCATransitionFromRight;
// CATransition必须添加到navigationController的view.layer上,这个很重要!!!
[self.view.layer addAnimation:transition forKey:nil];
CAAnimation.h
/* Common transition types. */

CA_EXTERN CATransitionType const kCATransitionFade
    API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 淡入淡出
CA_EXTERN CATransitionType const kCATransitionMoveIn
    API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 慢慢进入并覆盖效果
CA_EXTERN CATransitionType const kCATransitionPush
    API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 推进效果
CA_EXTERN CATransitionType const kCATransitionReveal
    API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // 揭开效果

/* Common transition subtypes. */

CA_EXTERN CATransitionSubtype const kCATransitionFromRight
    API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
CA_EXTERN CATransitionSubtype const kCATransitionFromLeft
    API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
CA_EXTERN CATransitionSubtype const kCATransitionFromTop
    API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
CA_EXTERN CATransitionSubtype const kCATransitionFromBottom
    API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));

结合以上说明自己运行起来就更明朗啦!!!
(写的不对和补充的地方望指出纠正,谢谢!)

你可能感兴趣的:(UINavigationController push pop动画自定义)