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.
Related
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.
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).
When Switching between two view controllers, what's the difference between addSubView or using a navigation controller and using pushViewController?
In my app, I have a few set up screens in the beginning before a game calculator starts (which has a lot of view switching in between, and a lot of ViewControllers are reused).
In that case, should I set up a navigation controller in the AppDelegate or in the RootViewController, or just use addSubView in the first few set up screens and add a navigation controller where my calculator views start after the set up screens?
The difference is that with addSubiview, you add a view to another, which therefore will contain it. The navigation controller actually manages a stack of VC, in which the next view isn't included in the previous.
Another diference is about parameters, addSubview will accept a view as argument, while the other will accept a view controller.
Typically, a navigation controller is used when displaying hierarchical content (in a table view most of the time), that allow the user to go deeper in details, or getting back to previous levels.
I'm getting confused on view controllers and would love a straight example. Here's the preamble:
I have a UIViewController with a matching .xib.
By default IB gives me a single View in the Document window.
I can make it appear by telling my UIWindow to addSubview:controller.view and bringSubviewToFront:controller.view
Here's the questions:
Should I add another View to the ViewController in IB? Or is there a better, programmatical way?
How do I tell the ViewController to switch between the Views?
From the ViewController downward, what does the code look like to achieve this?
I'm trying things but just making a mess so I thought I'd stop and ask...
Note that every button, label, image, etc. in your main view controller is actually a view in itself, however I've interpreted your question to mean that you want to manage multiple full-screen views or "screens". Each screen should have its own view controller to manage it. So to get the terminology right, a view-controller is an object that manages a single full-screen view (or almost full screen if it's nested inside a navigation controller or tab bar controller for example) and a view is the big area managed by the view controller as well as all the sub-views (images, buttons, labels, etc.) within it (they are all UIView sub-classes). The view controller manages all of them on that screen, if you want another screen/page then you should create a new view controller to manage it.
The root view controller (the one you add to the window) can be a plain old normal view controller that you've designed in IB, however it's probably more useful if you use a navigation controller or a tab bar controller and add your designed view controller to that - then you can push additional view controllers as needed.
Another way (if you don't want navigation or tab-bar style) would be to transition to other view controllers directly in the main window using whatever transitions you like (or just replace the old one). We'll leave that for now though.
Any sub-views of your main view controller (the one you've designed in IB) will be automatically loaded from the nib file, but you can also add your own views programatically if you want (typically you would use one or the other, i.e. nibs or programatically, but you can mix and match if you want). To do it programatically, override loadView in the view controller and then call [super loadView]; then do [self.view addSubView:myOtherView]; (create the myOtherView first of course). Note that the first time .view is accessed on your view controller, it actually calls loadView to create the view, so inside loadView it's important to call [super loadView]; before trying to access self.view :D
To switch between views, using the navigation or tab bar controllers makes it very easy. So put your main view controller inside (for example) a navigation controller and put the navigation controller in the window, so you've got window->navigationController->myController. Then from an action method in your view controller (you can hook up the action methods in IB), for example when an "about" button is pressed do this:
- (void)doAbout
{
// Create the about view controller
AboutViewController* aboutVC = [AboutViewController new];
// Push the view controller onto the navigation stack
[self.navigationController pushViewController:aboutVC animated:YES];
[aboutVC release];
}
Note that the about view controller is created programatically here - if your about view is designed in IB then instead use initWithNibName:bundle: to create it.
And that's how you manage multiple screens.
For my application, I have one UIViewController and about 8 UIViews. The views are all properties of the view controller, linked via the Interface Builder (IBOutlet). So when the view controller loads, all of the views are also loaded, and I have built-in methods to switch back and forth between the different views.
Is it bad to have them all linked to one view controller -- should each view have its own view controller? Because they're all linked to one, I'm assuming they're all in memory at the same time and are never released because the view controller itself is never released.
What is the standard practice for this?
If you have a bunch of views that will always be on-screen at the same time, then they should be controlled by one UIViewController.
If you have a bunch of views that will alternate between completely controlling the screen, then each view should have its own UIViewController.
If you have a single view that's always on-screen that delegates part of the screen to another view that can change, then you should have a UIViewController to manage the main view as well as one UIViewController per subview.
(Any time you have a view that can sometimes be on-screen and sometimes be off-screen, you should probably be using a UIViewController to manage its lifespan.)