Same size of Container View and its child view - ios

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

Related

When should AutoLayout Constraints Be Created While Using the UIViewControllerTransitioning Protocol

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.

Getting a VC to appear inside another VC

I have 2 ViewControllers.
VC1 has a 2 views inside it.
I want to get MenuUIVC to appear in one of my views belonging(child) to VC1.
I tried this code inside of VC1 but it didn't work.
MenuUIVC * menuViewVC = [[MenuUIVC alloc] init];
menuUIView = menuViewVC.view;
I expected to be able to see the MenuUIVC inside the view (menuUIView) which is a child of VC1. I have the IBOutlets all hooked up on the storyboard.
You can use Container views to get View Controller inside a View Controller. And, you can get the reference to it through prepareForSegue() method.
Links for description:
iOS Container View
The Easy Way to Switch Container Views in iOS
If you are using UIView, then why don't you use
[menuUIView addSubview:menuViewVC.view];
Another option is to use childviewcontrollers.
See these links for example:-
adding view controller as child view in ios
Add child view controller to current view controller
Using container or child view controller, gives you full fledge option of using View Controller properties, which you will not get in UIView.
Say for example, you can you orientation delegate methods, which you can't using in UIView class directly.
Hope this can help you.
Cheers
Sanjay
you can go for container view if you want to do it using IBOutlets & storyborad.
but if you want to do it using code then follow the below steps :
initialise & create parent view controller.
then add required child view as a subview with negative frame.
now change the frame with UIView animation whenever required. & do add tap gesture recogniser on part of screen other than the child view to remove it back to the initial position.

Is it bad practice to put UIViewControllers in other UIViewControllers?

I know there is the common practice in iOS development of having one UIViewController presented on the screen whose view is loaded from a XIB which will contain all the UIView subclasses in it.
While I was working on a pretty complex widget for an app, I decided to make the widget subclass a UIViewController instead of a UIView. This was because I thought a UIViewController was essentially a UIView with some helper methods around it. Then I could create a XIB for it (I know UIViews can have their own XIBs too), load the views it contains, place ITS view in the presented parent VC's view, and lay it out.
This works fine so far, but I'm wondering if this is bad practice and if I should just subclass a UIView instead and give it a normal NSObject controller. I am seeing some problems with this and I was wondering if anybody could address concerns I have with this approach?
EDIT NOTE: The widget VC does NOT relate to the VC view it is in and is reusable on ANY screen. So the answer is not subclassing the widget VC with the parent VC. The widget is INSIDE the parent VC, but it is NOT a parent VC.
EDIT NOTE 2: I am NOT using Storyboard. Only Autolayout, XIBs, and ARC.
Why can't we have VC's in VC's?
1) Can VC's be simply dropped into ANOTHER VC's XIB and be loaded easily as a subview?
2) I read here: When to use a UIView vs. a UIViewController on the iPhone?
The top answer explains how the VC controls rotation of the screen and laying out the subviews again, so if you add another VC, then the system will automatically think that THAT is the main VC and will attempt to rotate it instead, causing problems. Is this true? Or is he just talking about if you somehow got into a state where 2 VC's were "presented"? I wasn't sure if his answer applied to VC views that were SUBVIEWS of other VC views.
3) In general is this good practice? It certainly seemed more reasonable as it made loading the subview VC's view much easier.
Thanks!
It's absolutely fine. The answer to your problem is ContainerView.
Container View defines a region within a view controller's view subgraph that can include a child view controller. Create an embed segue from the container view to the child view controller in the storyboard.
You almost got it right. Yes, it's good to make a view controller for what you needed. But you shouldn't just add it's view to the parent view, you should also add the view controller as a child view controller of the first view.
You can add many views controllers as child view controllers of a view controller.
You can learn more about this here.

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