Please tell me which ViewControllers can be placed inside UINavigationViewContoller?
I.e. can I make a UINavigationViewController the root view for UITableViewController or UITabViewController?
Thank You
From the Apple docs:
initWithRootViewController:
Initializes and returns a newly
created navigation controller.
(id)initWithRootViewController:(UIViewController
*)rootViewController Parameters
rootViewController
The view controller that resides at the bottom of the navigation stack.
This object cannot be an instance of
the UITabBarController class.
So anything but an UITabBarController is fine
Related
I have UITabbarMoreController which contains a few UINavigationControllers. These UINavigationControllers then contain my custom view controllers.
So the hierarchy looks something like this:
UITabbarController
- UINavigationController
-> my custom UIViewController
- ...(other children of UITabbarController look the same)
From within my custom view controller I call [self parentViewController] which should return a UINavigationController. And this really happens, I really do get a UINavigationController, BUT only when the particular UINavigationController is NOT inside moreNavigationController.
Since I have many children controllers in the tabbar controller, the tabbar controller creates a moreNavigationController. If I open a viewcontroller that is under moreNavigationController and call [self parentViewController] it returns a mysterious object with class UIMoreNavigationController
I really need to get the UINavigationController that is parent of my view controller, not the UIMoreNavigationController. Also, I tried using [self navigationController] with the same result. How can I get reference to the real closest parent of my viewcontroller? Thanks for help in advance!
In short, you can't.
Apple always try to optimise their code. One of their optimisation here is to check whether the ViewController displayed in the list of its UIMoreNavigationController is of type UINavigationController. Because UIMoreNavigationController itself is a UINavigationController it does not want to create another UINavigationController. It's trying to avoid UINavigationController nesting.
When you look at the header file of UIMoreNavigationController you will notice it has a variable
UINavigationController* _originalNavigationController; which is accualy the original UINavigationController that you created and that you want to access. Unfortunetly you cant since UIMoreNavigationController is private.
Workaround (ugly)
Pass the reference of your NavigationController to its children when you push them on it's stack.
In the appdelagate, we have a UINavigationController and the view controllers as well. then in it we can initialize the navigation controller with the root view controller. And I understand why need them too.
However, in the sample code of my reference book(iPhone SDK Application Development, author: Jonathan Zdziarski), all view controller classes were added with a navigation controller as property, while they seem to be never used. So what is the meaning of having them as property in view controller classes?
e.g
#interface XYZViewController: UIViewController
{
UITextView *textView;
UIButton *button;
.....
.....
UINavigationController *navigationController;
}
-(void)...
.....
...
#end
One more question:
All UIViewController instances can have the property "navigationItem" once they are navigated. so what do this navigationItem refer to? does it refer to the navigation controller that is navigating the view controller?
UIViewController has navigationController property that is handled by the framework and it points to the parent UINavigationController if the view controller in question has one.
Check the documentation for more info:
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIViewController_Class/Reference/Reference.html
The same documentation will tell you that navigationItem is a UINavigationItem object that represents a view controller in the navigation bar. You can customise its appearance, like title, prompt, back button behaviour, etc.
That said, I have no idea why your book adds a navigationController property to UIViewController subclasses. It was added in iOS 2.0, a long time ago already... Anyway, you shouldn't need to add it, as it's provided in UIViewController class.
In my appDelagate I have a UIViewController called "FrontPage" which is basically a log in screen. Once the login has authenticated it removes itself from the superview and creates a tabbarcontroller, navigationcontroller (inside tabbar), and various UIViewControllers in the NC and on their own in the tab bar. I then push my TabBarVC.view to the windows subView.
It works but I was hoping after I set the windows subview to TabBarVC.view I could release the TabBarViewController to dealloc it and the appdelagate would own the TabBarVC, but when I do it's crashing.
As I'm typing this I'm realizing I never pass the actual TabBarVC, just the view but is there a way to do this?
Also if I completely FUBAR'd this up let me know.
You should set the window's rootViewController property to your UITabBarController instance similar to this:
// set the tab bar controller as our root view controller
[self.window setRootViewController:tabBarController];
To clarify, this will add the TabBarController, its view and all of its subviews to the window's view hierarchy for you and I would recommend you use this method for your login view controller as well.
You could make your UITabBarController an IBOutlet to the app delegate (or just keep the code you have that generates it). Make it a retained property of the app delegate, synthesize the property, and either create the UITabBarController in the app delegate (self.tabBarController = ...) or if you use an xib make the IBOutlet connection from the UITabBarController to the app delegate in the xib.
You could add the UITabBarController to the app's window, and then add the FrontPage UIViewController on top of it. Once you remove the FrontPage from the window, the UITabBarController will already be present underneath it.
I created "New Project" -> Tab Bar Application.
Then i changed from #interface FirstViewController : UIViewController to #interface FirstViewController : UINavigationController.
Then i changed file's owner from UIViewController to UINavigationController in xib file.
Then i updated view. But i don't see any label on the screen. Why? (i have some labels on xib)
Why are you subclassing UINavigationController and what are you trying to accomplish? UINavigationController does not display a view of it's own, just the navigation bar over some other view controller's view. In addition UINavigationController was not designed to be subclasses, hence the "This class is not intended for subclassing." warning in its class reference.
If you want to display your view controller as part of a navigation stack you should create an instance of UINavigationController, set that navigation controller as the view controller for one of your tabs, and then push an instance of your FirstViewController onto the UINavigationController.
I think I've found the cause: Document Info window in IB has a warning: "'Selected Navigation Controller (Second)' has nib name property set to 'SecondView.nib', but this view controller is not intended to have its view set in this manner."
Bummer.
I've built nib in Interface Builder that has UITabBarController at top level and switches between UINavigationControllers.
It works fine when everything is in a single nib file, but I'd like to use separate nib files for UINavigationControllers.
Starting with Apple's TabBar template, if I just change class of SecondView to UINavigationController, it all breaks:
and all I get is this:
// imgur has lost the image, sorry //
Is it possible to have separate file for UINavigationController without programmatically setting everything?
I would like TabBarController to handle loading and unloading of nibs.
Simply swap the UINavigationController with the FirstViewController.
So the hierarchy should be like this:
Tab bar controller
-----Tab bar
-----Navigation Controller
----------First View Controller
---------------Navigation Item
----------Tab bar item (First)
-----Navigation Controller
----------Second View Controller
---------------Navigation Item
----------Tab bar item (Second)
You set the nib of First View Controller in the inspector to the nib file containing the actual view objects (Since you are trying to split them into separate files, which is a good thing).
You have one tab, that tab has a navigation controller which loads First View Controller as its root view.
Done.
I haven't tried setting up UINavigationController via IB. I have multiple screens, each is stored in separate xib and there's a corresponding class that extends UIViewController. In applicationDidFinishLaunching I initialize UIViewControllers using xib's but then manually create UINavigationController, add navigation controller's view to window and push first view to navigation controller.
Not sure if that helps.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
navigationController = [[UINavigationController alloc] init];
FirstViewController * viewController = [[FirstViewController alloc]
initWithNibName:#"FirstView"
bundle:nil];
[navigationController pushViewController:viewController animated:NO];
[viewController release];
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
}
Above FirstViewController extends UIViewController, in IB you create your view then set File's owner class to your class (e.g. here FirstViewController) and connect the File's owner view to the UIView's view.
I believe you are looking for something like this. You would replace "whatever" with the name of you second nib file.
newNavController = [[UINavigationController alloc] initWithNibName:#"whatever" bundle:[NSBundle mainBundle]];
First, it looks like you have your UITabBarItems under the navigation controllers instead of directly under the UITabBarController. That may be part of your problem.
Second, when you add a UITabBarController in IB and and click on its icon in your list of top-level objects (your first screenshot), the attributes inspector will allow you to change the type of view controller for each of the tabs. Using this, you can change them all to navigation controllers, if you wish. Also, since you wanted to load custom views and view controllers from other nibs, if you look at the "View Controller" section at the bottom of the attributes inspector, you can select a nib from your project to load the view from. Assuming that nib's "File's Owner" is set to your UINavigationController subclass, it should all work fine.
All of this without a large amount of coding work, either. Let me know if you'd like screenshots for what I'm talking about in case you can't find these panels.
I found the same warning.I have kept all view controller in separate xib files. I got rid off it by removing .nib name and keeping it empty.