RootViewController切换转换animation
有什么办法有一个过渡/animation效果,而用一个新的appDelegatereplace现有的viewcontroller作为rootviewcontroller?
当然。 只需将rootViewController
的切换包装在一个转换块中即可:
[UIView transitionWithView:self.window duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{ self.window.rootViewController = newViewController; } completion:nil];
我发现这一点,并完美的作品:
在你的appDelegate中:
- (void)changeRootViewController:(UIViewController*)viewController { if (!self.window.rootViewController) { self.window.rootViewController = viewController; return; } UIView *snapShot = [self.window snapshotViewAfterScreenUpdates:YES]; [viewController.view addSubview:snapShot]; self.window.rootViewController = viewController; [UIView animateWithDuration:0.5 animations:^{ snapShot.layer.opacity = 0; snapShot.layer.transform = CATransform3DMakeScale(1.5, 1.5, 1.5); } completion:^(BOOL finished) { [snapShot removeFromSuperview]; }]; }
在你的应用程序
if (!app) { app = (AppDelegate *)[[UIApplication sharedApplication] delegate]; } [app changeRootViewController:newViewController];
积分:
我张贴耶稣答复快速实施。 它将viewcontroller的标识符作为参数,从storyboard desiredViewController加载,并用animation改变rootViewController。
Swift 3.0更新:
func changeRootViewController(with identifier:String!) { let storyboard = self.window?.rootViewController?.storyboard let desiredViewController = storyboard?.instantiateViewController(withIdentifier: identifier); let snapshot:UIView = (self.window?.snapshotView(afterScreenUpdates: true))! desiredViewController?.view.addSubview(snapshot); self.window?.rootViewController = desiredViewController; UIView.animate(withDuration: 0.3, animations: {() in snapshot.layer.opacity = 0; snapshot.layer.transform = CATransform3DMakeScale(1.5, 1.5, 1.5); }, completion: { (value: Bool) in snapshot.removeFromSuperview(); }); }
Swift 2.2更新:
func changeRootViewControllerWithIdentifier(identifier:String!) { let storyboard = self.window?.rootViewController?.storyboard let desiredViewController = storyboard?.instantiateViewControllerWithIdentifier(identifier); let snapshot:UIView = (self.window?.snapshotViewAfterScreenUpdates(true))! desiredViewController?.view.addSubview(snapshot); self.window?.rootViewController = desiredViewController; UIView.animateWithDuration(0.3, animations: {() in snapshot.layer.opacity = 0; snapshot.layer.transform = CATransform3DMakeScale(1.5, 1.5, 1.5); }, completion: { (value: Bool) in snapshot.removeFromSuperview(); }); } class func sharedAppDelegate() -> AppDelegate? { return UIApplication.sharedApplication().delegate as? AppDelegate; }
之后,你从任何地方都有一个非常简单的用法:
let appDelegate = AppDelegate.sharedAppDelegate() appDelegate?.changeRootViewControllerWithIdentifier("YourViewControllerID")
Swift 3.0更新
let appDelegate = UIApplication.shared.delegate as! AppDelegate appDelegate.changeRootViewController(with: "listenViewController")
//快速:
UIView.transitionWithView(self.window!, duration: 0.5, options: UIViewAnimationOptions.TransitionFlipFromLeft, animations: { self.window?.rootViewController = anyViewController }, completion: nil)
试试这个吧 为我工作得很好。
BOOL oldState = [UIView areAnimationsEnabled]; [UIView setAnimationsEnabled:NO]; self.window.rootViewController = viewController; [UIView transitionWithView:self.window duration:0.5 options:transition animations:^{ // } completion:^(BOOL finished) { [UIView setAnimationsEnabled:oldState]; }];
编辑:
这一个更好。
- (void)setRootViewController:(UIViewController *)viewController withTransition:(UIViewAnimationOptions)transition completion:(void (^)(BOOL finished))completion { UIViewController *oldViewController = self.window.rootViewController; [UIView transitionFromView:oldViewController.view toView:viewController.view duration:0.5f options:(UIViewAnimationOptions)(transition|UIViewAnimationOptionAllowAnimatedContent|UIViewAnimationOptionLayoutSubviews) completion:^(BOOL finished) { self.window.rootViewController = viewController; if (completion) { completion(finished); } }]; }
为了不在转换过程中出现问题,稍后在应用程序中清除旧视图也是很好的select
UIViewController *oldController=self.window.rootViewController; [UIView transitionWithView:self.window duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ self.window.rootViewController = nav; } completion:^(BOOL finished) { if(oldController!=nil) [oldController.view removeFromSuperview]; }];
在AppDelegate.h中:
#define ApplicationDelegate ((AppDelegate *)[UIApplication sharedApplication].delegate)]
在你的控制器中:
[UIView transitionWithView:self.window duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{ ApplicationDelegate.window.rootViewController = newViewController; } completion:nil];
正确的答案是你不需要replace你的窗口上的rootViewController
。 相反,创build一个自定义UIViewController
,分配一次,让它显示一个孩子控制器,并根据需要replaceanimation。 您可以使用下面的一段代码作为起点:
Swift 3.0
import Foundation import UIKit /// Displays a single child controller at a time. /// Replaces the current child controller optionally with animation. class FrameViewController: UIViewController { private(set) var displayedViewController: UIViewController? func display(_ viewController: UIViewController, animated: Bool = false) { addChildViewController(viewController) let oldViewController = displayedViewController view.addSubview(viewController.view) viewController.view.layoutIfNeeded() let finishDisplay: (Bool) -> Void = { [weak self] finished in if !finished { return } oldViewController?.view.removeFromSuperview() oldViewController?.removeFromParentViewController() viewController.didMove(toParentViewController: self) } if (animated) { viewController.view.alpha = 0 UIView.animate( withDuration: 0.5, animations: { viewController.view.alpha = 1; oldViewController?.view.alpha = 0 }, completion: finishDisplay ) } else { finishDisplay(true) } displayedViewController = viewController } override var preferredStatusBarStyle: UIStatusBarStyle { return displayedViewController?.preferredStatusBarStyle ?? .default } }
而你使用它的方式是:
... let rootController = FrameViewController() rootController.display(UINavigationController(rootViewController: MyController())) window.rootViewController = rootController window.makeKeyAndVisible() ...
上面的例子演示了你可以嵌套在FrameViewController
UINavigationController
,并且工作得很好。 这种方法为您提供高水平的定制和控制。 只要调用FrameViewController.display(_)
任何时候你想要replace窗口上的根控制器,它会为你做这个工作。
这是swift 3的更新,这个方法应该在你的应用程序委托中,并且你可以从任何视图控制器通过应用程序委托的共享实例
func logOutAnimation() { let storyBoard = UIStoryboard.init(name: "SignIn", bundle: nil) let viewController = storyBoard.instantiateViewController(withIdentifier: "signInVC") UIView.transition(with: self.window!, duration: 0.5, options: UIViewAnimationOptions.transitionFlipFromLeft, animations: { self.window?.rootViewController = viewController self.window?.makeKeyAndVisible() }, completion: nil) }
以上各种问题中缺less的部分是
self.window?.makeKeyAndVisible()
希望这有助于某人。