UINavigationController push pop动
2021-06-16 本文已影响0人
Gavin_盖文
一、需求:优化系统push pop动画卡顿问题。
二、实现思路:UINavigationController子类中拦截push pop方法,屏蔽系统动画,用自己的动画。
代码如下:
BaseNavigationController.h文件
#import <UIKit/UIKit.h>
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));
结合以上说明自己运行起来就更明朗啦!!!
(写的不对和补充的地方望指出纠正,谢谢!)