Changing current view in a uitabbar application iOS iPad - iphone

UIViewController *newView = [[UIViewController alloc] initWithNibName:#"NewView" bundle:[NSBundle mainBundle]];
tabBarController.selectedViewController = newView;
Why doesn't this work?

The selectedViewController property of a UITabBarController must be one of the tab bar's existing tabs (as defined in its viewControllers property). You may want to either push the new controller onto an existing tab (which would have to be a UINavigationController), or add the viewController to the viewControllers array.

Because that view controller isn't part of the UITabBarController.
If you look at the Apple reference for the selectedViewController property, you'd see:
The specified view controller must be
in the viewControllers array.
You need to add the view controller to UITabBarController, using the viewControllers property, so the view controller has a tab, so you can then select that view controller's tab.

Related

iPhone - change navigation controller's view, using a button in a subview

I have a navigation controller with a rootview.
The rootview contains buttons, which push new views onto the navigation controller correctly.
However, on this rootview, I also have subview (it's a scrolling preview like the appStore images, view made of 3 UIview items). On these UIViews, there is a button which I'd like to change the rootview navigation controller, like the other buttons.
At the moment, it builds and runs, but the new view is not pushed. Any ideas?
Click method on on the ScrollItem button:
MyViewController *newView = [[MyViewController alloc] initWithNibName:#"ManageMyPain" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:newView animated:YES];
... i guess it is because, self doesn't have a navigation controller, but the rootview does.
Thanks!!
The property "navigationController" is only being set in a view controller if he's pushed to the navigation controllers stack. your second view is a sub view of a push viewcontroller which means this property is NULL and will not do anything if you try pushing things to it.
Yes, it is because self.navigationController will be nil if you didn't push that controller on navigations stack or if you didn't set it manually.
So you just need to have reference to rootViewController.navigationController and then [navigationController pushViewController:newView animated:YES]; will work perfectly.

Any "non TabBar-template" based tutorial on how to add a UITabBar?

I would like to add a TabBar to an existing view-based application I already started just to allow the user to switch to other parts of the app like the "About" section and another section entitled "Saved Searches" to display a navigational content (saved searches list > specific search result > product details).
Any idea on how to do this ? All tutorials I found point me directly to a TabBar template.
Thx for helping,
Stephane
You could start off with the UITabBar Application Template and you'll realize it's very easy to do:
In your UIApplicationDelegate class, in the method
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Instantiate a UITabBarController like this:
UITabBarController *tabBar = [[UITabBarController alloc] init];
Then you set the view Controllers that will appear on the tab bar:
tabBar.viewControllers = viewControllers;
Which is a NSArray you can previously create with your UIViewController subclasses:
NSArray *viewControllers = [[[NSArray alloc] initWithObjects:vc1, vc2, vc3, nil] autorelease];
After this, you only have to set it as the root view controller of the window, or add it as a subview (it has the same effect, but the first approach doesnt work prior to iOS 4)
self.window.rootViewController = tabBar;
or
[self.window addSubView:tabBar.view];
And then
[tabBar release];
To achieve the kind of navigation that you say in your question, the view controllers you set to the tabBar should be instances of UINavigationController, which are very easy to create like this:
UINavigationController *vc1 = [[UINavigationController alloc] initWithRootViewController:firstViewControllerPage];
And inside them, you can push (navigate to) other view controllers doing:
[self.navigationController pushNavigationController:anotherViewController animated:YES];
Hope this brief review of it makes it a bit clear :)
You can create a new UITabBarController, and add it's view as a subview of your applications window. Then, add your other view controllers (for your "About" and "Saved Searches" sections) to that tab bar controller.
This can be done most easily in Interface Builder. In your MainWindow.xib, drag a Tab Bar Controller object onto the canvas. This will automatically create a tab bar with two items (one for each of the view controllers added). For each view controller under the tab bar controller, go to the identity inspector and change its class to your custom view controller subclass. Then, show the attributes inspector and there is a field "NIB Name" - again, set this to the appropriate nib name. Your custom controller views will then be loaded from their corresponding nib files. All that's left to do is name each tab in Interface Builder, and give it a graphic.
You can also do this programmatically if you don't like IB, by assigning the custom view controllers to the tab controller's viewControllers property, and assign a selectedViewController.
Hope this helps.
EDIT
Thought it might be helpful to show a little hierarchy! Your MainWindox.xib structure might look something like this:
AppDelegate
UIWindow
UITabBarController
UITabBar
AboutViewController (view loaded from "AboutViewController.xib")
Tab Bar Item - About
UINavigationController
Navigation Bar
SavedSearchesViewController - Root View Controller (view loaded from "SavedSearchesViewController.xib"
Tab Bar Item
And push appropriate view controllers from SavedSearchesViewController as normal to provide navigation content.

Having a Navigation Controller (as the main view) inside a tab bar controller

I've seen a bunch of different tutorials on how this is done. That's fine, I've set up my tab bar controller, have a navigation controller as one of its items, and then set my main view controller as the child of that navigation controller.
If I have an "About" UIBarButtonItem on the main navigation controller's bar, what's the best way of activating the About View Controller? It seems logical that it should be done in the AppDelegate through an IBAction method, but I also kind of feel like it could go in the main view controller some how...
Also, if I'm not initially setting the navigation controller (since I'm setting the tab bar controller as the root), how do I push the about view controller onto its view stack?
Create a UINavigationController and set your AboutViewController as your rootViewController for that navigationView. This way you will be able to set your navigationItem properties and also push view controllers with the self.navigationController property.
You need to set your main view controller under UINavigationController
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController: mainViewController];
Then in your main view controller you customize navigationItem property, you can put your UIBarButtonItem here.
self.navigationItem.rightBarButtonItem = your_about_button_here;

How to add a UINavigationController to my UITableViewControllerSubclass?

My app is a tab bar application, which one of the tabs is a TableViewController instead of a viewController which works fine (the table displays great) but where and how do I add UINavigationController to it? :-)
You can do this 2 different ways... in IB or code. If I'm dealing with a TabBar I usually do it in IB. All you have to do there is is drag a NavigationController object where your tableview object currently sits... then just make your tableviewcontroller the first child of your new navigation object.
TabBarController
-(Tab Bar)
-NavigationController
--(Navigation Item)
--TableViewController
or
If you want to do it in code... I would just set it up within your app delegate (usually because a tab bar is at the highest point in your app... meaning it appears right away after loading):
// Create a tabbar controller and an array to contain the view controllers
tabBarController = [[UITabBarController alloc] init];
NSMutableArray *localViewControllersArray = [[NSMutableArray alloc] initWithCapacity:numberOfTabs];
// setup the view controllers
UINavigationController *myNavigationController;
myNavigationController = [[UINavigationController alloc] initWithRootViewController:myTableViewController];
// add to tab bar controller
[localViewControllersArray addObject:myNavigationController];
tabBarController.viewControllers = localViewControllersArray;
// add the tab bar to the window
[window addSubview:tabBarController.view];
You should then release the objects you just created since they will be retained by the TabBarController and Navigation Controller. Hope this helps
As Ryan noticed you can make it easily using IB. Here is how you can achieve this:
Launch Xcode and create new Tab Bar Application project.
Under resources group find MainWindow.xib and double click it to open in Interface Builder.
Next, select Tab Bar Controller object and open Inspector window (Command + Shift + I).
Notice "View Controllers" section in Inspector () then click on View Controller popup and change value from View Controller to Navigation Controller.
That's it! Now you can use your UITableViewController subclass inside this UINavigationController.

Loading UINavigationController from another nib automatically by UITabBarController

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.