Segues vs. UIViewControllerAnimatedTransitioning - ios

While searching how to perform custom animations when transitioning from one controller to another I found some info about UIViewControllerAnimatedTransitioning.
So the question is: why do we even need this if we have custom segues? Are they interchangeable or not? If yes, why does Apple provide two ways of doing the same task?

Some differences:
Segues can only be used with storyboards.
Animator objects can be used programmatically, or along with segues.
Animator objects allow you to set a customized final position and size for your new view controller.
Animator objects can be configured to do special animations with navigation controllers and collection views.
Animator objects also allow interactive transitions using UIViewControllerInteractiveTransitioning, which segues don't.

Related

Ways of changing view in Xcode

I'm new in Swift and I have a question: What are the best ways to change view in xcode? What's the difference between using segue and instantiateViewController?
Apple explains it best in their documentation:
"You can initiate the presentation of a view controller programmatically or using segues. If you know your app’s navigation at design time, segues are the easiest way to initiate presentations. For more dynamic interfaces, or in cases where there is no dedicated control to initiate the segue, use the methods of UIViewController to present your view controllers."
Source: https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/PresentingaViewController.html#//apple_ref/doc/uid/TP40007457-CH14-SW1
I like to use segues for connecting view controllers in my storyboard, and for easily passing data to the presented VC. I programmatically present view controllers when I want to customize the animation and/or size of the presented controller. Another reason to programmatically initialize a VC is when you just want its view added as a sub-view of your current VC. You would likely do this with an AVPlayerViewController for example.

iOS subview custom transition

When presenting a UIViewController that implements UIViewControllerTransitioningDelegate it is easily possible to customize the viewtransition.
Now I would like to know if I can customize a viewtransition for a subview? Lets say I have a tapable tile that currently flips when tapped (UIViewAnimationOptionTransitionFlipFromRight). Although that is a very nice effect I rather would like to customize this transition. But I do not know how to start..
To clarify I would like to use an AnimationController<UIViewControllerAnimatedTransitioning> to handle my subviewtransition - is that possible?
Any suggestions?
Well this is not possible out of the box but there are some ways to achieve that but this will need some deeper knowledge of how the custom transition are working in detail.
Here are two articles describing what you are looking for in detail:
Custom Container View Controller Transitions
http://www.objc.io/issue-12/custom-container-view-controller-transitions.html
Interactive Custom Container View Controller Transitions
http://www.iosnomad.com/blog/2014/5/12/interactive-custom-container-view-controller-transitions
Answering with regards to your comment : you cannot.
From UIViewControllerAnimatedTransitioning protocol documentation :
Adopt the UIViewControllerAnimatedTransitioning protocol in objects that implement the animations for a custom view controller transition. The methods in this protocol let you define an animator object, which creates the animations for transitioning a view controller on or off screen in a fixed amount of time.
This protocol is only for UIViewControllers (and its descendants), and UIView doesn't inherit from it.

Accessing linked Segues created in a Storyboard

I am trying to create a class that is similar in functionality to the UITabBarController, but with some fundamentally different functionality. It is called a dropdownViewController and has a primary content view with a UITabBar-like interface at the top of the screen that allows for other UIViewControllers to be modally presented and dismissed over this primary viewController.
I would like this class to be able to be set up using the storyboard to some extent, and I have created a custom Segue that connects my dropDownViewController class with each of its child viewControllers.
My current solution is to assign identifiers to each of the Segues that are then stored in array within the dropdownViewController. I can call the segues programmatically using the performSegueWithIdentifer: method, but this solution isn't as flexible or intuitive as I would like to to be.
Right now, all the custom Segues that I have setup are connected to the "manual" triggered segue in the storyboard connections panel for the dropdownViewController. (I would put screenshots but this is my first post)
However, I want to mimic the functionality of the UITabBarController class, which has an alternate triggered segue in the storyboard connections panel called viewControllers that each of its child views are assigned to. Unless there are some compile-time macros handling these story board interactions, I assume that the UITabBarController uses these connections to determine what it's view controllers are. However, I can't figure out how to setup this functionality with my own class
After searching around for a solution, it seems likely that this is functionality Apple kept for its own use and is limited to their own classes as a feature in Xcode, but if anyone has solutions or ideas it would be greatly appreciated.
I haven't tried this, but I think you should be able to do it with your own custom segues. In the perform method, you would just add the destination view controller to the source view controller's (DropDownViewController) array of view controllers. In the DropDownViewController's viewDidLoad method (or maybe in an initializer or awakeFromNib, not sure which is most appropriate), you would execute all these segues so that they run right after the controller is loaded like is done for a tab bar controller.

Subclass UICollectionViewTransitionLayout for automatic UINavigationViewController transition animation

Is it possible to subclass UICollectionViewTransitionLayout to change the automatic (e.g. non-interactive) animation when pushing/popping a view controller onto/off a UINavigationController stack?
Apples documentation and some articles in the internet suggest it should be possible:
If you want to provide more than just a linear transition from the old to new layout over time, you need to subclass and provide the layout attributes for items yourself
…but I didn’t find a way yet.
I would like to use UICollectionViewController’s useLayoutToLayoutNavigationTransitions to push one collection view controller on top of another (using the same data source). The two view controllers use different subclasses of UICollectionViewLayout which I want to transition using custom UICollectionViewLayoutAttributes that need to be keyframed and modified by the transitionProgress.
I was hoping, just implementing collectionView:transitionLayoutForOldLayout:newLayout: would do the trick, but that method only is called when transitioning interactively.
The best way I could come up with for the pushing is to call startInteractiveTransitionToCollectionViewLayout:completion: on the UICollectionView and pushing the new view controller without animation in the completion handler. For popping the view controller I would hook into -viewWillDisappear: of the view controller and check for the current view controller in the stack; if it is not there, I could again perform startInteractiveTransitionToCollectionViewLayout:completion:
Somehow I guess there is a better way…

Best way of handling pan gestures

I want to handle transitions between two instances of the same view controller class, using pan gestures.
I've read almost every transitions can be handled by segues, but is it the same when using pan gestures?
Segues don't seem to be a good fit for this kind of transitions.
For the moment, I have a master view controller which instantiates to sub view controllers. The gesture related code resides in the master view controller.
It works well, but I believe there has to be a solution where all the controller management stuff is done in the storyboard.
What is the best place in my code to handle this kind of transitions?
It sounds to me like what you want is a UIPageViewController set up to scroll instead of page curl (That's a settable property) A page view controller would do all the work for you.
There is a sample app in the Xcode docs called PhotoScroller that shows how to set this up. It does lots of other stuff too, (pinch to zoom and image tiling) but you can ignore that.
If you can't get a UIPageViewController to give you the transition you want then you might need to build your own custom parent view controller class. Embedding a single child using a container VC and an embed segue is trivial. I haven't tried to embed multiple children in the same container yet. using embed segues yet. I've done transitions between child VCs using the "manual" parent/child VC calls that were added in iOS 5
I've found a really great article on the way to implement custom transitions with iOS 7, whether they're interactive or not: http://www.captechconsulting.com/blog/tyler-tillage/ios-7-tutorial-series-custom-navigation-transitions-more
It comes with a very detailed demo.
Animations should be classes implementing the UIViewControllerAnimatedTransitioning or UIViewControllerInteractiveTransitioning protocols.
The code using the gesture recognizer can reside in those classes.
The animation can then be returned in the following methods of your navigation controller delegate:
navigationController:animationControllerForOperation:fromViewController:toViewController:
navigationController:interactionControllerForAnimationController:
This way I can plug the animation to whatever controller I want to.
I hope it could help someone.

Resources