SwifterSwift / SwifterSwift

A handy collection of more than 500 native Swift extensions to boost your productivity.

Home Page:https://swifterswift.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

UIWindow extension to switch the rootViewController with animation

omaralbeik opened this issue · comments

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

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?()
		})
	}

}
commented

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

I tested it in iOS 13.5 in simulator. It is working well.