0Day Forums
RootViewController Switch Transition Animation - Printable Version

+- 0Day Forums (https://0day.red)
+-- Forum: Coding (https://0day.red/Forum-Coding)
+--- Forum: Objective-C (https://0day.red/Forum-Objective-C)
+--- Thread: RootViewController Switch Transition Animation (/Thread-RootViewController-Switch-Transition-Animation)

Pages: 1 2


RootViewController Switch Transition Animation - homospory993039 - 07-21-2023

Is there any way to have a Transition/animation effect while replacing an existing viewcontroller as rootviewcontroller with a new one in the appDelegate?


RE: RootViewController Switch Transition Animation - Sirmyelinated498 - 07-21-2023

in AppDelegate.h:

#define ApplicationDelegate ((AppDelegate *)[UIApplication sharedApplication].delegate)]

in your Controller:


[UIView transitionWithView:self.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
ApplicationDelegate.window.rootViewController = newViewController;
}
completion:nil];



RE: RootViewController Switch Transition Animation - tweedinesses637686 - 07-21-2023

just try this. Works fine for me.

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];
}];

EDIT:

This one is better.

- (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);
}
}];
}



RE: RootViewController Switch Transition Animation - gonifs341825 - 07-21-2023

I found this and works perfectly:

in your 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];
}];
}


in your app


if (!app) { app = (AppDelegate *)[[UIApplication sharedApplication] delegate]; }
[app changeRootViewController:newViewController];


credits:

>


RE: RootViewController Switch Transition Animation - ormand37 - 07-21-2023

In order not to have problems with transition flip later on in the app is good to clear the old view from the stack as well

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];
}];


RE: RootViewController Switch Transition Animation - Mramur5 - 07-21-2023

I am posting Jesus answer implemented in swift. It takes viewcontroller's identifier as an argument, loads from storyboard desiredViewController and changes rootViewController with animation.

**Swift 3.0 Update:**

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 Update:**


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;
}

After, you have a very simple usage from anywhere:

let appDelegate = AppDelegate.sharedAppDelegate()
appDelegate?.changeRootViewControllerWithIdentifier("YourViewControllerID")

**Swift 3.0 update**

let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.changeRootViewController(with: "listenViewController")


RE: RootViewController Switch Transition Animation - franciscojgi - 07-21-2023

The correct answer is you don't need to replace the `rootViewController` on your window. Instead, create a custom `UIViewController`, assign it once and let it display one child controller at a time and replace it with animation if needed. You can use the following piece of code as a starting point:

*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
}
}

And the way you use it is:

...
let rootController = FrameViewController()
rootController.display(UINavigationController(rootViewController: MyController()))
window.rootViewController = rootController
window.makeKeyAndVisible()
...

The example above demonstrates that you can nest `UINavigationController` inside `FrameViewController` and that works just fine. This approach gives you high level of customization and control. Just call `FrameViewController.display(_)` any time you would want to replace the root controller on your window, and it will do that job for you.


RE: RootViewController Switch Transition Animation - Proprosiphonal693 - 07-21-2023

This is an update for swift 3, this method should be in your app delegate, and you call it from any view controller, via a shared instance of the app delegate

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)
}
The part that is missing from various questions above, is

self.window?.makeKeyAndVisible()
Hope this helps someone.


RE: RootViewController Switch Transition Animation - mons331219 - 07-21-2023

I propose my way which it is working fine in my project, and it offers me good animations. I have tested other proposals found in this post, but some of them do not work as expected.

- (void)transitionToViewController:(UIViewController *)viewController withTransition:(UIViewAnimationOptions)transition completion:(void (^)(BOOL finished))completion {
// Reset new RootViewController to be sure that it have not presented any controllers
[viewController dismissViewControllerAnimated:NO completion:nil];

[UIView transitionWithView:self.window
duration:0.5f
options:transition
animations:^{
for (UIView *view in self.window.subviews) {
[view removeFromSuperview];
}
[self.window addSubview:viewController.view];

self.window.rootViewController = viewController;
} completion:completion];
}



RE: RootViewController Switch Transition Animation - bacchae133 - 07-21-2023

Nice sweet animation (tested with Swift 4.x):

extension AppDelegate {
public func present(viewController: UIViewController) {
guard let window = window else { return }
UIView.transition(with: window, duration: 0.5, options: .transitionFlipFromLeft, animations: {
window.rootViewController = viewController
}, completion: nil)
}
}

Call with

guard let delegate = UIApplication.shared.delegate as? AppDelegate else { return }
delegate.present(viewController: UIViewController())