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.
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).
i´ve created a UINavigationController in my appdelegate and initialized it with my "modelselectionViewController". This VC has different uibuttons and when touched, a new VC ("modelViewController") is pushed on the navigationstack.
This "modelViewController" acts as my template view and has a uitabbarcontroller with different tabs. The first VC is shown immediately but any changes on the navigationcontroller doesn´t work. I would like to set the name of the title but that navigationcontroller is null.
NSLog(#"navi: %#",
self.navigationController);
If i change my code to push the different VC when touching the different tabs, navigation works but only with a third level of navigation hierachy.
I want to know if it´s possible to use only one navigationcontroller for all my different tabs. Hope i made my setup clear. Appreciate all your help. thanks
I think you might want to read Combining ViewControllers.
In general, you should have the tabbar controller as a 'root' controller, not as a 'child' controller. A quick search in Apple's doc didn't yield a formal 'forbidden', but it might be.
If you create a UITabBarController from a view that's managed in a UINavigationController (ie: if you create a navigationcontroller first, and it's still around when you create the tabbarcontroller), you're starting a fight with the frameworks. Here's the admonishment from the docs on combining viewcontroller interfaces:
An application that uses a tab bar
controller can also use navigation
controllers in one or more tabs. When
combining these two types of view
controller in the same user interface,
the tab bar controller always acts as
the wrapper for the navigation
controllers. You never want to push a
tab bar controller onto the navigation
stack of a navigation controller.
Doing so creates an unusual situation
whereby the tab bar appears only while
a specific view controller is at the
top of the navigation stack. Tab bars
are designed to be persistent, and so
this transient approach can be
confusing to users.
I read that as "if it doesn't break something that we haven't thought of on the next update, we might reject the app anyway because it's 'confusing to users.'"
I suppose you could kill the whole navigation hierarchy and the navigationcontroller if you don't need to return there (like if you just used it for a one-time setup screen). Or you can look into other options for navigating within a viewcontroller that's managed by the navigationcontroller.
One thing to try might be to navigate to a UITableView, and use its cells to push a modal view onto the navigation stack. That would be familiar to users and also jive with the intent of the navigation classes.
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.
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.)