UINavigationController Title not Applied - iphone

I am wondering why my UINavigationController is not letting me set a title. It lets me change the tint of the navigationBar, but the title and rightBarButtonItem I set just get ignored. Why?
Here's my code:
taps = 0;
UIView*controllerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
controllerView.backgroundColor = [UIColor whiteColor];
controller = [[UIViewController alloc] init];
[controller setView:controllerView];
[controllerView release];
navController = [[UINavigationController alloc] initWithRootViewController:controller];
navController.navigationBar.barStyle = 1;
navController.navigationItem.title = #"Setup";
UIBarButtonItem*item = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonSystemItemDone target:self action:#selector(dismissSetup:)];
navController.navigationItem.rightBarButtonItem = item;
[item release];
[self presentModalViewController:navController animated:YES];
[mp stop];
p.s: I know i'm not releasing some of the stuff I alloc'ed, I do that later!

set: self.title = #"This is my title"; in the viewController
(or in your case set controller.title = #"this is my title";)

The navigation controller updates the
middle of the navigation bar as
follows:
If the new top-level view controller has a custom title view,
the navigation bar displays that view
in place of the default title view.
To specify a custom title view, set
the titleView property of the view
controller’s navigation item.
If no custom title view is set, the navigation bar displays a
label containing the view
controller’s default title. The string
for this label is usually obtained
from the title property of the view
controller itself. If you want to
display a different title than the one
associated with the
view controller, set the title
property of the view controller’s
navigation item instead.
You want your UINavigationController to change its title depending on which viewcontroller is currently on top. So the way to go is to set the title in the viewcontrollers you are pushing onto the viewControllers array.
And by the way: I don't think navigationcontrollers are supposed to be presented modally:
Because the UINavigationController
class inherits from the
UIViewController class, navigation
controllers have their own view that
is accessible through the view
property. When deploying a navigation
interface, you must install this view
as the root of whatever view hierarchy
you are creating. For example, if you
are deploying the navigation interface
by itself, you would make this view
the main subview of your window. To
install a navigation interface inside
a tab bar interface, you would install
the navigation controller’s view as
the root view of the appropriate tab.

Related

"Back" button doesn't show up in UINavigationController

I'm using the following code to try to make a "back" button for my app, the view that this code is located is in a modal view (if that has any bearing?):
navBar = [[UINavigationController alloc] initWithRootViewController:tvController];
[navBar.view setFrame:CGRectMake(0, 0, 320, 460)];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle: #"Back"
style: self.navigationController.navigationItem.leftBarButtonItem.style
target: self
action: #selector(backAction)];
navBar.navigationItem.backBarButtonItem.enabled = YES;
[self.view addSubview:navBar.view];
The view does not show at all, thank you for any tips!
EDIT: Even if I use a leftBarButtonItem, it still does not show up, I think there is some problem with the self.navigationItem bit of my code?
You need to make sure that when you present the modal view that you wrap it in a UINavigationController, then you'll have a valid navigation bar to manipulate. Otherwise you'll change the navigationItem all you want but it won't show up because you're not in a navigationController.
So when you go to present the view controller you're probably doing something like this.
SomeViewController *someViewController = [[[SomeViewController alloc] init] autorelease];
[self presentModalViewController:someViewController animated:YES];
What you want to do is present it like this
SomeViewController *someViewController = [[[SomeViewController alloc] init] autorelease];
UINavigationController *navigationController = [[[UINavigationController alloc] initWithRootViewController:someViewController] autorelease]
[self presentModalViewController:navigationController animated:YES];
Then when you're in the modal view you'll have a valid navigation bar that you can manipulate. Altering the leftBarButtonItem at that point will actually do something and be visible.
If you're trying to make this show a back button though you're probably "doing it wrong" typically if you're presenting something modally like this you'd show a "done" button. However by wrapping this with a navigation controller like this it does allow the modal view to then push and pop view controllers and operate as a normal navigation stack. But the root of it should probably have a "done" button not a back to return back to its previous state.
The backBarButtonItem property needs to be defined on the previous item in your stack, i.e. on the view controller you are going back to, not the current one.
EDIT:
OK, I see now you are adding your own custom navigation bar. In that case, you cannot use the view controller's navigation item. You must instead push your own navigation items on to the navigation bar and access those instead. For example:
UINavigationItem *item = [[UINavigationItem alloc] initWithTitle:#"Back"];
item.leftBarButtonItem = ...;
[navBar pushNavigationItem:item animated:NO];

UISegmentedControl in a PopoverController with multiple view controllers

I would like to have a UISegmentedControl embedded in a PopoverController, similar to what is described in this SO question : UISegmentedControl embedded in a UINavigationBar/Item
The difference is that I have a different view controller for each view that I want to show in the popover, depending on the selected index on the Segmented Control. I'm not sure how I would go about doing this. Whenever I try to push a new view on top of the root view controller, the UISegmentedControl disappears. I would just like to switch between the two viewcontrollers, while keeping the UISegmentedControl visible. Is this even possible?
Thanks in advance!
If its a different viewController for each one of the segments on the segmentBar, you'll have to use a container viewController that adds the views of each of the viewController as a subview on itself or sets its view to that of the viewController's view. For example:
UIViewController* containerController = [[[UIViewController alloc] init] autorelease];
//Inside the viewDidLoad of the the ContainerController class, do the following:
//Initialize all three viewControllers
UIViewController* test1 = [[[UIViewController alloc] init] autorelease];
UIViewController* test1 = [[[UIViewController alloc] init] autorelease];
UIViewController* test1 = [[[UIViewController alloc] init] autorelease];
//set up the segment and add it to the container's navBar's title view.
[segmentedControl addTarget:self action:#selector(segmentValueChanged:) forControlEvents:UIControlEventValueChanged];
- (void)segmentValueChanged:(id)sender
{
//if first tab selected
[self.view removeAllSubviews];
[self.view addSubview:test1.view];
//if second tab selected
[self.view removeAllSubviews];
[self.view addSubview:test2.view];
//if third tab selected
[self.view removeAllSubviews];
[self.view addSubview:test3.view];
}
Instead of adding it as a subView, you might be able to just set self.view = test1.view. Obviously, you would use the container view to initialize the navController and put that navController inside the popover. Hope this helps!
If you are using presentModalViewController method to show your new view controller on the screen, it will always cover the entire screen and what ever is underneath it. That's just how it works.
As per docs:
On iPhone and iPod touch devices, the view of modalViewController is
always presented full screen. On iPad, the presentation depends on the
value in the modalPresentationStyle property.
The way to do it and still being able to control how the view controller is positioned is to create your own presentation method.

Maintain Title Bar in ModalViewController

When using the modalViewController, I found that that only way to keep a title bar and buttons on the screen that I jump to was to create a navigation controller and set the modalView screen as the rootView of the navigation controller (as below).
userNameViewController = [[UserNameViewController alloc] init];
UINavigationController *cntrol = [[UINavigationController alloc] initWithRootViewController:userNameViewController];
[self.navigationController presentModalViewController:cntrol animated:YES];
[userNameViewController release];
[cntrol release];
Why can't I simply this by using the original viewController as the modalView (as below)?
userNameViewController = [[UserNameViewController alloc] init];
[self presentModalViewController:userNameViewController animated:YES];
Because the navigation bar you usually see belongs to the navigation controller, not to its children view controllers.
You could create your own navigation bar and add it to your controller's view. However, it would require some relayout (and that's probably why it's easier to just recreate a navigation controller).

How to hide a tabbar at the app startup?

So, I want my app starts with a UIViewController(without seeing a tabbar), and then enter a UITableView with navigationbar and tabbar. the problem is that the Tabbar is visible at the app starts up, anyone can help on this will be very appreciated...
I think you should either send -presentModalViewController:animated: to your main UIViewController with the tab bar controller as an argument or just do this:
[myWindow addSubview: myTabBarController.view];
Make your app a navigation based application (rather than a tab bar based one) then add a tab bar on the UITableView.
There is help for adding the UITabBar here
I do it like this : in this case drawing a table view and map view (From the Locati application)
tabBarController = [[UITabBarController alloc] init]; // creates your tab bar so you can add everything else to it
searchTableViewController = [[SearchTableViewController alloc] init]; // creates your table view - this should be a UIViewController with a table view in it, or UITableViewController
UINavigationController *searchTableNavController = [[[UINavigationController alloc] initWithRootViewController:searchTableViewController] autorelease];
[searchTableViewController release]; // creates your table view's navigation controller, then adds the view controller you made. Note I then let go of the view controller as the navigation controller now holds onto it
searchMapViewController = [[SearchMapViewController alloc] init];
UINavigationController *mapTableNavController = [[[UINavigationController alloc] initWithRootViewController:searchMapViewController] autorelease];
[searchMapViewController release]; // does exactly the same as the first round, but for your second tab at the bottom of the bar.
tabBarController.viewControllers = [NSArray arrayWithObjects:searchTableNavController, mapTableNavController, nil]; //add both of your navigation controllers to the tab bar. You can put as many controllers on as you like
I found this pattern a long time ago. Sorry that I can't point at the original.
YOu then need to add the tabbarcontoller to the relevant view ([...view addSubView:tabBarController];) possibly setting frame first.

Custom UITabBarController Problems with View Controllers and Views

I'm writing a custom UITabBarController so I can fully control appearance of the tab bar. I've got it all working so I have an array of view controllers that it handles.
The controller has a main view which fills the screen, and inside it it has a UIView at the bottom for the tab bar. That tab bar view has a button for each view controller. When buttons are pressed I add the view controller's view to the main view, and set it's frame so that it doesn't cover the tab bar view:
controller.view.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height - kTabBarHeight);
This all works fine, and I can flick between the view controllers just fine. However, when I present a modal view controller, and then dismiss it, the current view controller's view becomes full screen and covers up my tab bar! I've tried setting the autoresizing masks to not resize, but is keeps happening.
I have also tried adding the view controllers view's to the bottom (below the tab bar) by using:
[self.view insertSubview:controller.view atIndex:0];
But when I do that, the tab bar is even visible above any modal views! Which is strange. I think there's something I'm not understanding so I would be grateful if someone can explain what I'm missing!
Thanks,
Mike
Try setting
controller.view.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height - kTabBarHeight);
in the controller's viewWillAppear method
Try this out. I think you want dynamic view controllers within tab bar controller.
-(void)applicationDidFinishLaunching:(UIApplication *)application {
// Add the tab bar controller's current view as a subview of the window
tabBarController.delegate=self;
tabBarController=[[UITabBarController alloc] init];
mainDashBoard=[[DashBoard alloc] initWithNibName:#"DashBoard" bundle:nil];
mainSearchView=[[SearchView alloc] initWithNibName:#"SearchView" bundle:nil];
mainMoreView=[[MoreView alloc] initWithNibName:#"MoreView" bundle:nil];
UINavigationController *nvCtr0=[[[UINavigationController alloc] init] autorelease];
UINavigationController *nvCtr1=[[[UINavigationController alloc] initWithRootViewController:mainDashBoard] autorelease];
UINavigationController *nvCtr2=[[[UINavigationController alloc] initWithRootViewController:mainSearchView] autorelease];
UINavigationController *nvCtr3=[[[UINavigationController alloc] initWithRootViewController:mainMoreView] autorelease];
UINavigationController *nvCtr4=[[[UINavigationController alloc] init] autorelease];//[[[UINavigationController alloc] initWithRootViewController:nil] autorelease];
tabBarController.viewControllers=[NSArray arrayWithObjects:nvCtr0,nvCtr1,nvCtr2,nvCtr3,nvCtr4,nil];
nvCtr0.tabBarItem.enabled=NO;
nvCtr4.tabBarItem.enabled=NO;
[window tabBarController.view];
}
I've managed to find a better way to control the appearance of the tab bar by simply inserting subviews to the top of the tab controllers tab bar. It's worked a treat!