Swifterswift: UIWindow extension to switch the rootViewController with animation

Created on 14 May 2018  路  3Comments  路  Source: SwifterSwift/SwifterSwift

Add an extension to change rootViewController in a UIWindow with animation, duration, UIViewAnimationOptions and a completion handler.

good first issue help wanted new extension

Most helpful comment

Nice job @ratulSharker, thanks for adding the screenshot as well 馃挴, my only comment is we want to give users more options to choose other animations.

I'm using the following implementaion, it uses UIViewAnimationOptions to give users the freedom to choose from; curl, dissolve, flip, ..

public extension UIWindow {

    /// Switch current root view controller with a new view controller.
    ///
    /// - Parameters:
    ///   - viewController: new view controller.
    ///   - animated: set to true to animate view controller change _(default is true)_.
    ///   - duration: animation duration in seconds _(default is 0.5)_.
    ///   - options: animataion options _(default is .transitionFlipFromRight)_.
    ///   - completion: optional completion handler called when view controller is changed.
    public func switchRootViewController(to viewController: UIViewController, animated: Bool = true, duration: TimeInterval = 0.5, options: UIViewAnimationOptions = .transitionFlipFromRight, _ completion: (() -> Void)? = nil) {

        guard animated else {
            rootViewController = viewController
            return
        }

        UIView.transition(with: self, duration: duration, options: options, animations: {
            let oldState = UIView.areAnimationsEnabled
            UIView.setAnimationsEnabled(false)
            self.rootViewController = viewController
            UIView.setAnimationsEnabled(oldState)
        }, completion: { _ in
            completion?()
        })
    }

}

All 3 comments

Hi @omaralbeik , i have following implementation regarding this issue

public func switchRootVC(to viewController: UIViewController, duration: TimeInterval, completion: @escaping () -> Void) {
        viewController.view.alpha = 0.0
        viewController.view.frame = CGRect.init(x: 0, y: frame.size.height, width: frame.size.width, height: frame.size.height)
        addSubview(viewController.view)

        UIView.animate(withDuration: duration, animations: { 
            viewController.view.alpha = 1.0
            viewController.view.frame = self.frame
        }) { (_) in
            self.rootViewController = viewController
            completion()
        }
    }

with duration = 1.0 it look like following

Output

It will restrict the developer to the animation provided in the switchRootVC implementation. Will it be overkill to provide interface for providing custom animation by the callee of this method ?

Please share your thought.

Nice job @ratulSharker, thanks for adding the screenshot as well 馃挴, my only comment is we want to give users more options to choose other animations.

I'm using the following implementaion, it uses UIViewAnimationOptions to give users the freedom to choose from; curl, dissolve, flip, ..

public extension UIWindow {

    /// Switch current root view controller with a new view controller.
    ///
    /// - Parameters:
    ///   - viewController: new view controller.
    ///   - animated: set to true to animate view controller change _(default is true)_.
    ///   - duration: animation duration in seconds _(default is 0.5)_.
    ///   - options: animataion options _(default is .transitionFlipFromRight)_.
    ///   - completion: optional completion handler called when view controller is changed.
    public func switchRootViewController(to viewController: UIViewController, animated: Bool = true, duration: TimeInterval = 0.5, options: UIViewAnimationOptions = .transitionFlipFromRight, _ completion: (() -> Void)? = nil) {

        guard animated else {
            rootViewController = viewController
            return
        }

        UIView.transition(with: self, duration: duration, options: options, animations: {
            let oldState = UIView.areAnimationsEnabled
            UIView.setAnimationsEnabled(false)
            self.rootViewController = viewController
            UIView.setAnimationsEnabled(oldState)
        }, completion: { _ in
            completion?()
        })
    }

}

Any iOS 13 implementation for the same ? This gives me blank screen in iOS 13

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SD10 picture SD10  路  3Comments

omaralbeik picture omaralbeik  路  5Comments

fanglinwei picture fanglinwei  路  5Comments

fanglinwei picture fanglinwei  路  3Comments

AYastrebov picture AYastrebov  路  3Comments