addChildViewController and presentViewController - ios5

iOS 5 introduces the concept of custom container view controller and provides API like addChildViewController. Question: can you add a view controller as a child and still present it using presentViewController? Does doing the latter automatically make it a child view controller of the presentingViewController?

That's not how it's supposed to be used.
The parent/child relationship is for when a view controller has subviews that are managed by their own view controllers, for example a UITabBarController, where the parent view controller draws the tabs and the child view controllers draw the content of each tab.
If you present a view controller using presentViewController, it generally takes over the whole screen, or appears in a modal so that the presenting view controller is no longer in control. In that scenario there's no reason for the presenter to be the parent because it doesn't need to cooperate with the presented controller - it just gets out of the way until the presented controller is dismissed again.
Why is it that you wanted to do this? If it's just so that the view controllers have a reference to one another and can pass data, there are other ways to do this (e.g. the delegate pattern, NSNotifications, or even just a property linking the two).

Related

How do I put two UIViewController vertically in UIKit?

I want to put two UIViewController in one screen simultaneously in UIKit. However, I couldn't find the solution.
Like this:
I want to display both UINavigationController and Admob Banner in one screen and independently. The one doesn't affect the other.
Could you tell me how to do this?
You want to use view controller containement. The easiest way to do this is as follows.
Open your storyboard.
Add a view controller. Let's call it "Parent". Give it a unique identifier.
Tap the "+" to add a new component to your parent view controller. Search on "Container" and drag 2 container views onto your parent view controller. Those container views will contain the content view of your 2 view controllers. Set up the constraints on those container views so they are laid out top and bottom as you show in your picture.
Next add view controllers for view controller 1 and view controller 2 to your storyboard. (you can also add links to view controllers from other storyboards, but I'll ignore that.) Lets call those Child1 and Child2.
Control-drag from each container in Parent onto the child view controller you want to appear in that container. When prompted, select that you want to create an "embed segue".
An embed segue tells your app that it should load the child view controllers when Parent is loaded, and make their content views subviews of the container views.
In Parent, the PrepareForSegue() method will fire as each child view controller has been initialized and its view is getting ready to be loaded. At that point you can pass information to the child view controllers, set up delegate links, etc. (Note that you can't, and shouldn't, manipulate the child view controller's view hierarchies directly. Instead, pass data to the child view controllers using proprerties or methods of those view controllers, and have the children's viewDidLoad methods install that data into the views as needed.

Access Controls of Second View controller from the First Controller

I have an application which has a single window controller and 2 view controllers.I have created a segue from a button within the main View Controller to the second View Controller;to show a modal window.
Is it possible to access the controls located within the second view controller by creating an outlet within the .swift file of the first view controller. i.e.:access controls within the second view controller from the first view controller.
What are you trying to achieve?
generally speaking - No. Button, labels, or view loaded by a view controller are only in scope (loaded into memory) when the view controller's view is displayed.
Very rarely would you need to initialize the view controller and make a method call before the view is displayed, so the real question is why are you wanting to do this.
Keep in mind its is called "view controller" i.e it controls the current views objects.
I believe there is flaw in your design by wanting to do this.
Making the assumption that the first view controller is not destroy when loading the second (i.e the second is a popup):
To properly communicate between the two view controllers you need two parts.
When performing the segue you need set parameter being passed to the second view controller.
https://developer.apple.com/documentation/appkit/nssegueperforming
Inorder to communicate back to first view controller you need to implement a delegate. I.e the second view controller delegates work back to the first:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html - view the section on delegation.

positioning UIViewController containment children

I was reading the documentation:
You need to decide how many children can be displayed by your view
controller at once, when those children are displayed, and where
they appear in your view controller’s view hierarchy.
But in which method should I position the view controller children's view? Say I have two UIViewController in the container and I want one next to the other.. how do I do this?
In one of my articles I demonstrated how to create a simple dashboard app using UIViewController Containment.
http://www.highoncoding.com/Articles/848_Creating_iPad_Dashboard_Using_UIViewController_Containment.aspx
Each of the child view controllers has a view property. You can set the frame of those views when you add them to your own view.
It depends on the context of the situation that you may have. If you need to display all of the children when displaying the view for the first time, then add the view controllers and views in viewDidLoad ( if using a xib or nib) or in loadView ( if done programatically). If you need to show the child view controllers on demand, like after the touch of button, then you can add the child view controller and associated view in a separate method.
You will need to layout the views of the child view controllers as you would layout any other subviews. Remember view controller containment is just another ways of allowing you to modularize your code.
Check out this link which helps explain how to add the child view controllers: Animate change of view controllers without using navigation controller stack, subviews or modal controllers?
Here is a simple sample project that shows how to add child view controllers:https://github.com/toolmanGitHub/stackedViewControllers
Good Luck!

iPhone - nested views & controllers

Is it possible to have a single iPhone screen with its view loaded from a xib by that screen's UIViewController, but then another UIView within that screen with content loaded from a separate xib file? If so, is it possible to have that nested view's events handled by a separate custom UIViewController subclass from the rest of the screen? If both of these things are possible, are they also advisable?
It is possible. Apple suggests against having more than one UIViewController active on screen at once, so they would advise against. I would suggest only doing it if the reason for the second view controller is navigation or modal.
A view controller with the purpose of loading other view controllers, like a navigation controller, needs some screen space for itself and uses the rest to load another view controller. That is fine. The criteria here is that only one controller is presenting content while the other is presenting navigation.
A view controller could load another view controller to perform some limited task like selecting an item from a list or entering some text. The second view controller might only fill part of the screen. The criteria here is that the one controller behaves modally and will only be displayed long enough to get some user input.
As for the general case of splitting the screen between two view controllers that are presenting content, the Apple suggestion is that you have a single class derived from UIViewController manage the views. If the view is complex enough to warrant other controllers, then derive them from NSObject and have the master view controller manage the child controllers along with the views. The child controllers would have the master controller as a delegate, and the master controller would pass views to the child controllers to manage but not own.

Can a UIViewController add itself to a UINavigationController

I'm starting an app where I'd like to have multiple view controllers. Some of the views will be displayed inside of a navigation controller. I can create a navigation controller and then add another instantiated view controller to it. But what I'd like to do, is just instantiate a view controller that has its own view and is the root view controller of a navigation view controller. So when I instantiate the view controller, I'd like for it create a navigation controller and push "self" on to it. When I do it my simulator crashes and the details don't really give a reason. The console does not display anything. Any ideas. My reason for this is to separate out logic without have a view controller that simply creates a navigation controller and then pushes another view controller on it as the root view controller.
I'm not entirely sure if I understand your question correctly. Why would it be preferable if the view controller pushed itself to the navigation controller? I mean, you have to instantiate your view controller at some point in code (either app delegate or another view controller) anyway. Why can't you just create the navigation controller there, instantiate your VC and then push it onto the nav controller? As far as I can see, this doesn't involve creating any additional view controllers.
Anyway, having a view controller decide by itself where it is used (ie. pushed onto), is not best practice. This way you lose the flexibility of using it in other contexts. Always try to couple your components as loosely as possible.