解决导航栏推出一个透明的视图控制器闪屏的问题

2016-08-09  本文已影响273人  EdwardSelf

随便百度一下,发现答案千篇一律,所谓把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。

上一篇下一篇

猜你喜欢

热点阅读