User default transition for UIViewController

I am developing a library and I want to provide a default custom transition between two view controllers, the user can also provide his own implementation, the first idea that comes to my mind is to override the UIViewController and implement the UIViewControllerTransitioningDelegate and then users can subclass my CustomTransitionViewController , this is the best way to do it? any restrictions? Is there a more elegant way to use only protocols, for example, with a default implementation?

 import UIKit class CustomTransitionViewController: UIViewController, UIViewControllerTransitioningDelegate { required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.transitioningDelegate = self } override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil:Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) self.transitioningDelegate = self } func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8) } func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8) } } 
+7
ios uiviewcontroller swift swift-protocols
source share
2 answers

I think one of the most elegant (and protocol-oriented) ways to do this would be with the UIViewControllerTransitioningDelegate extension. Extend the protocol and implement the standard implementation for animationController(forPresented: presenting: source:) and animationController(forDismissed:) . The extension will look something like this:

 extension UIViewControllerTransitioningDelegate where Self: UIViewController { func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8) } func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8) } } 

Then ask your users to expand their view controllers to comply with this protocol. Since you have already met the only requirements in the protocol extension, all they need to do is add a conformance declaration, for example:

 class MyViewController: UIViewController, UIViewControllerTransitioningDelegate { } 

If you want to extend all of the UIViewController to do this, you can do this with an empty extension:

 extension UIViewController: UIViewControllerTransitioningDelegate { } 

That should work. In my opinion, this is a very clean, elegant solution that does not require an unnecessary subclass. It also makes it easier to provide different implementations of animationController(forPresented: presenting: source:) and animationController(forDismissed:) in each view controller. Your users can simply add their own implementations of the two above functions, wherever they want. In addition, you do not need to deal with dirty Objective-C objects, such as related objects.

If you provide this functionality in some pre-packaged package, and you want to hide the base implementation, you can declare your own protocol, make it a sub- UIViewControllerTransitioningDelegate , extend it similarly and coordinate your users with your user protocol instead of UIViewControllerTransitioningDelegate :

 protocol MyProtocol: UIViewControllerTransitioningDelegate { //Add your own requirements (if you have any). } extension MyProtocol where Self: UIViewController { func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8) } func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8) } //Satisfy your requirements (or let your users do it). } class MyViewController: UIViewController, MyProtocol { } extension UIViewController: MyProtocol { } 

Whichever route you choose, this solution gives you what you want without having to deal with extraneous subclasses or ugly Objective-C concepts. Good luck!

+5
source share

You can also just make an extension for the UIViewController , which performs all the necessary actions and additionally matches your protocol, which allows the user to disable the default transitions.

As an example:

 protocol ThorsHammer { var isDefaultTransitionEnabled: Bool { get set } } extension UIViewController: ThorsHammer { var isDefaultTransitionEnabled: Bool { /* this part sucks */ } // Check if the default transition should happen and // do some transition magic } 

How to add saved properties to extensions, you can see.

All this, if you can find a way to set transitioningDelegate somehow in the extension, otherwise you have to subclass it .

0
source share

All Articles