隨便百度一下,發(fā)現答案千篇一律,所謂把backgroudColor改成不透明就可以了,但如果需求一定要透明呢?
首先我們創(chuàng)建一個類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];
}];
}}
在你要執(zhí)行推出的視圖控制器里,導入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];
}
并添加代理方法,在代理方法里創(chuàng)建一個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閃屏的煩人東西了。
效果圖:



效果就是我點擊Menu,從右側推出一個視圖控制器,但是我仍然可以看到主Controller的view上的字,點擊click按鈕,推出FViewController,仍然可以看到主Controller的view上的字,而且向右push,向左pop不會有閃屏的問題,動畫效果也在。當然你也可以自定義推出動畫,改變<UIViewControllerAnimatedTransitioning>代理里第二個代理方法里的fromVC和toVC的frame即可,也可以添加一些3D效果。
此外,在代理方法里可以用operation來判斷是push還是pop。