When should AutoLayout Constraints Be Created While Using the UIViewControllerTransitioning Protocol - ios

I'm trying to create a custom container view controller. I want to use the standard ViewControllerTransitioning pattern for animating the addition of child views, but I'm a bit stuck. I'm writing this container view controller completely in code, as the number of child view controllers can vary.
I've already looked at this tutorial and it has helped me very much, but I can't figure out this step.
The flow of adding a new child view controller is currently like this:
'MyContainerVc'.addNewSubViewController
Call UIViewController.addChildViewController
Create transitioning context
Fetch animator
Animate
'Container View'.addSubview
Create autolayout positioning/height constraints
The positioning/height constraints can be created (and are) in the container view, as the container view controller does not need to control them, but the width constraint needs to be created in the container view controller, as the child vcs can specify a preferredContentSize.width to my container vc. The container vc will try to respect the child vcs' preferences as much as possible and base the width constraints on it as much as possible.
I'm not sure when the constraint for the width of the subviews can be created. The constraint needs to be enforced before the animation is performed, as the width should be defined before the child view appears. However, I cannot activate it before the child view has been added as a subview and if I activate it after the animation has completed, the width is not defined properly during the animation.
The animator should only use the transitioningContext and use the addSubview method of the container view, as it should be agnostic to what kind of transition it is animating.
Also, is creating the AutoLayout constraints in addSubview the best way to go or should it be done somewhere else, e.g. in didAddSubview?
Some advice is very appreciated!

I think I figured it out. I'm going to create a delegate protocol that specifies a function that tells the container view controller to create the width constraint and I'll call that method in addSubview of the container view.

Related

Same size of Container View and its child view

I have an iOS project where I have my main view Controller, A, and another ViewController B. B is embedded in A as a child view controller. The whole thing is set up in Interface Builder using a Container View.
Now, B has some logic where it reacts to pan gestures to resize its view. This all works fine, the problem is that the Container View always stays the same size and does not resize with B's root view. I want the Container View's size to stay in sync with the root view of B.
What is the best approach for this? Is there any way to set this up in Interface Builder? The only feasible solution I found so far was to create a BDelegate, which A listens to and then resizes the Container View. Is there an easier way to achieve this?
thanks
Thanks to your answers, I got pointed in the right direction - specifically, that this is not possible the way I thought it was.
There is no way to have constraints between the views of a parent view controller and a child view controller - neither in IB, nor in code
As far as I can see, there are two ways to solve this:
Don't use a second UIViewController. Make the root view of your child view controller an actual subview of yourself, and just have a single UIViewController.
Do not use auto layout. Manage the frame of your child view controller's view manually, and have delegate callbacks back to your parent view controller where necessary. In those delegate callbacks, your parent view controller can react to size changes of the child view controller's view.
equalHeight and equalWidth constraints should solve your problem

Is there a way to make one view a subview of another in Interface Builder without actually dragging it inside the other view?

In this xib, I have three views: the main view and two container views which go inside it. Since you can't hide/show views in IB, it isn't practical to actually have the container views inside the main view since they just obscure each other. By moving them outside the main view like this, I can design them easily, but I must add them to the main view inside the controller's viewDidLoad. Is there a way I could have done this in IB?
Note: I know you can push a new controller for this specific kind of control, but I don't feel like coming up with another example just to ask the question.

Access properties of container view's superview

What I want to achieve:
when the user presses a button in the view controller in the container view I want it to be able to access and change a property of the super view of which the container view is a subview in.
Is this possible? I have seen a lot of questions about the super view being able to access the subview's properties but I would really like for the container view to be able to access the superview's property.
Use property parentViewController as self.parentViewController and access all the properties you want.
Actually, what you are trying to do is wrong from architectural point of view. When a parent has an access to child is ok, when child has an access to parent — not ok. You break a modular structure of your app. You cannot reuse your views after that.

In iOS, using storyboard, how to setup a view controller inside a container view?

I have created and drawn out a custom UIViewController called AutocompleteVC in my Main storyboard. AutocompleteVC will be used in several different places/storyboards and with different dimensions.
For example, in my Transit storyboard, shown below,, there is a custom UIViewController called TransitVC, shown on the left. In TransitVC, I have a container view with an IBOutlet called autocompleteContainerView. autocompleteContainerView has a segue called autocompleteEmbedSegue to a generic UIViewController, shown on the right in red.
The goal is to have TransitVC hold AutocompleteVC inside autocompleteContainerView. But I'm having trouble getting this to work. The reason I want to do this inside a container view is so I can use autolayout to set constraints on it. Otherwise, I know how to do this purely in code.
I believe my approach might be flawed. What is the correct approach to do this if I want to maximize storyboard usage.
I'm not sure what you are asking. Setting up a parent/child relationship with a container view is very easy, exactly as you have outlined. Just create a container view inside the parent view controller, create the child view controller scene, and then control-drag from the container view to the child view controller to create the embed segue.

iOS container view controller - Why does transitionFromViewController need the fromViewController?

When using custom container view controller, I don't quite understand why the presenting view controller needs to specify the from, because being the container class, it should already know what's in the view hierarchy, no?
transitionFromViewController:toViewController:duration:options:animations:completion:
Container view controllers sometimes need to put the views of the contained controllers into specific subviews of their own view. (For example, a SplitViewController reimplementation might have left and right positioning views holding the master and detail controller views respectively.) Providing the fromViewController tells UIViewController where in the view hierarchy the new controller's view should be inserted, and also which specific view should be removed after the animation.
(contrary to another answer, the frames of the views aren't set for you at all. You do that, before the call, and in the animation block. The "Creating Custom Container View Controllers" system guide in the docs has a pretty good example.)
As it happens, actually using transitionFromViewController:... appears to be optional. You can manage your view hierarchy manually, with or without animations, and it works fine. I'm still forming my opinions, but I think I prefer to do it manually, to more easily handle cases where one of the VCs is nil.
This is done this way to allow you to have a view controller that has views with viewControllers in it. The from defines the originating view controller and gives the system the ability to position the animations appropriately.
Imaging you had a view with 4 views in it like tiles. the main view controller can consecutively call this on its "child" view controllers and with the from -> to specification, it won't make the assumption that the caller is the from viewController.

Resources