解决导航栏推出一个透明的视图控制器闪屏的问题
随便百度一下,发现答案千篇一律,所谓把backgroudColor改成不透明就可以了,但如果需求一定要透明呢?
首先我们创建一个类TransitionAnimator,集成NSObject,并遵循<UIViewControllerAnimatedTransitioning>代理,记得要引入<UIKit/UIKit.h>。
在TransitionAnimator.h里申明一个bool类型的属性
@property(nonatomic,assign,getter= isPresenting) BOOL presenting;
用此属性帮我们判断是导航栏push还是pop。
在TransitionAnimator.m文件里
写所遵循协议里的两个代理,一个是动画时间,一个是动画内容。
- (NSTimeInterval)transitionDuration:(id)transitionContext {
return0.5f; //返回动画时间
}
- (void)animateTransition:(id)transitionContext{
//获取推走的控制器以及推出的控制器
UIViewController *fromVC = [transitionContextviewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContextviewControllerForKey:UITransitionContextToViewControllerKey];
if(self.presenting) {
//如果是push动作的话
//先把view放进容器里
[transitionContext.containerView addSubview:fromVC.view];
[transitionContext.containerView addSubview:toVC.view];
//设置基本参数,设置目的控制器在源控制器的左边
toVC.view.frame=CGRectMake(fromVC.view.frame.size.width,0, fromVC.view.frame.size.width, toVC.view.frame.size.height);
[UIViewanimateWithDuration:[selftransitionDuration:transitionContext]
animations:^{
//源控制器推出窗口
fromVC.view.frame=CGRectMake(-fromVC.view.frame.size.width,0, fromVC.view.frame.size.width, fromVC.view.frame.size.height);
toVC.view.frame=CGRectMake(0,0, toVC.view.frame.size.width, toVC.view.frame.size.height);
}completion:^(BOOLfinished) {
[transitionContextcompleteTransition:YES];
}];
}else{
//如果是pop动作的话
[transitionContext.containerViewaddSubview:fromVC.view];
[transitionContext.containerViewaddSubview:toVC.view];
toVC.view.frame=CGRectMake(-toVC.view.frame.size.width,0, toVC.view.frame.size.width, toVC.view.frame.size.height);
[UIViewanimateWithDuration:[selftransitionDuration:transitionContext]
animations:^{
fromVC.view.frame=CGRectMake(toVC.view.frame.size.width,0, fromVC.view.frame.size.width, fromVC.view.frame.size.height);
toVC.view.frame=CGRectMake(0,0, toVC.view.frame.size.width, toVC.view.frame.size.height);
}completion:^(BOOLfinished) {
[transitionContextcompleteTransition:YES];
}];
}}
在你要执行推出的视图控制器里,导入TransitionAnimator.h这个文件,导入代理<UINavigationControllerDelegate>
在此控制器里增加以下代码
- (void)viewDidAppear:(BOOL)animated{
self.navigationController.delegate=self;
[super viewDidAppear:animated];
}
- (void)viewDidDisappear:(BOOL)animated{
if(self.navigationController.delegate==self) {
self.navigationController.delegate=nil;
}
[super viewDidDisappear:animated];
}
并添加代理方法,在代理方法里创建一个TransitionAnimator类的对象,并返回这个对象即可
- (id)navigationController: (UINavigationController*)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController*)fromVC toViewController:(UIViewController*)toVC{
TransitionAnimator *animator = [TransitionAnimator new];
animator.presenting=YES;
return animator;
}
在你要pop的viewController里也添加push视图控制器里一模一样的代码,只不过把animator.presenting = NO;即可
这样push和pop都不会出现推出透明的view闪屏的烦人东西了。
效果图:
样式 我设定的是点击click按钮push下一页 推出后到FViewCOntroller效果就是我点击Menu,从右侧推出一个视图控制器,但是我仍然可以看到主Controller的view上的字,点击click按钮,推出FViewController,仍然可以看到主Controller的view上的字,而且向右push,向左pop不会有闪屏的问题,动画效果也在。当然你也可以自定义推出动画,改变<UIViewControllerAnimatedTransitioning>代理里第二个代理方法里的fromVC和toVC的frame即可,也可以添加一些3D效果。
此外,在代理方法里可以用operation来判断是push还是pop。