Add Custom buttons to Navigation Controller - iphone

I'm trying to either add 3 custom buttons to my navigation controller toolbar on the top of my view or add a segmented control with 3 options. I have the following code on my app delegate for when i create my view controller(fwc) but the buttons dont appear.
/*
Set up the navigation controller for the Feeding Tab
*/
// instantiate the feedingViewController and set the title to Feedings
feedingViewController *fwc =
[[feedingViewController alloc] initWithNibName:#"feedingViewController"
bundle:[NSBundle mainBundle]];
//fwc.title = #"Feedings";
// set the tab bar item up and add it as feedingViewController's tab bar item
UITabBarItem *feedingTabBarItem =
[[UITabBarItem alloc] initWithTitle:#"Feedings" image:nil tag:0];
fwc.tabBarItem = feedingTabBarItem;
[feedingTabBarItem release];
// create a new nav controller for feedings and add root view
feedingNavController = [[UINavigationController alloc] init];
//Create the add button, need to change the selector to something though *****
UIBarButtonItem *add = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(newFeeding)];
//self.navigationItem.rightBarButtonItem = add;
UIBarButtonItem *flexibleSpaceButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil action:nil];
// Create and configure the segmented control
UISegmentedControl *sortToggle = [[UISegmentedControl alloc]
initWithItems:[NSArray arrayWithObjects:#"Ascending",#"Descending", nil]];
sortToggle.segmentedControlStyle = UISegmentedControlStyleBar;
sortToggle.selectedSegmentIndex = 0;
[sortToggle addTarget:self action:#selector(toggleSorting:)forControlEvents:UIControlEventValueChanged];
// Create the bar button item for the segmented control
UIBarButtonItem *sortToggleButtonItem = [[UIBarButtonItem alloc]initWithCustomView:sortToggle];
[sortToggle release];
// Set our toolbar items
feedingNavController.toolbarItems = [NSArray arrayWithObjects:
flexibleSpaceButtonItem,
sortToggleButtonItem,
flexibleSpaceButtonItem,
add,
nil];
feedingNavController.navigationController.navigationBarHidden=NO;
[sortToggleButtonItem release];
[add release];
// Push the feedingViewController on the nav stack and release it.
[feedingNavController pushViewController:fwc animated:NO];
[fwc release];

In order to use a UITabBar you would need a UITabBarController, which is different than the UINavigationController. A UITabBar has a fundamentally different use than a UISegmentedControl. It appears that the functionality you're trying to implement is not appropriate for a UITabBar. In your question description you mention trying to add these buttons to the "navigation controller toolbar on the top." A UINavigationController has a UINavigationBar, which is the bar that runs across the top, and a UIToolbar, which is the bar that appears at the bottom. The UIToolbar, by default, is set to hidden, but you get a UIToolbar for free whenever you create a UINavigationController (see the UINavigationController reference in Xcode).
Apple's NavBar demo shows how to put a UISegmentedControl into the UINavigationBar. Instead of a title, use a custom titleView to display the segmented control:
fwc.navigationItem.titleView = sortToggle;
If you want to put your add UIBarButtonItem in the UINavigationBar as well, you can use:
fwc.navigationItem.rightBarButtonItem = add;
Note that you shouldn't actually go about trying to customize the UINavigationController's navigation bar on your own. The proper way to customize is to have an individual view controller access it's own navigationItem and set the titleView and rightBarButtonItem with the items you want.
If you wish to approach your problem using a UIToolBar instead, meaning that your items will appear on the bottom of the screen, you can do something like this:
// Assume UIBarButtonItem *add, UIBarButtonItem *sortToggleButtonItem,
// and UIBarButtonItem *flexibleSpaceButtonItem are allocated
[fwc setToolbarItems:[NSArray arrayWithObjects:
flexibleSpaceButtonItem,
sortToggleButtonItem,
flexibleSpaceButtonItem,
add,
nil]];
[feedingNavController setToolbarHidden:NO];

Related

Adding buttons to custom navigation bar

In my viewDidLoad method I have the following:
navigBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonSystemItemAction target:self action:#selector(btnClicked:)];
[self.view addSubview:navigBar];
The button does not show up at all! What am I missing?
// create the navigation bar and add it to the view
UINavigationBar *navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[self.view addSubview:navigationBar];
// create a button
UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonSystemItemAction target:self action:#selector(btnClicked:)];
// create a UINavigationItem and add the button in the right hand side
UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:nil];
navItem.rightBarButtonItem = button;
// add the UINavigationItem to the navigation bar
[navigationBar pushNavigationItem:navItem animated:NO];
set button on navigation bar .then u create a BarButtonItem on navigation.
barbutton=[UIBarButtonItem alloc] ]initWithTitle......
navigation.navigationController.rightBarButton= barbutton;
First read this :
When you use a navigation bar as a standalone object, you are responsible for providing its contents. Unlike other types of views, you do not add subviews to a navigation bar directly. Instead, you use a navigation item (an instance of the UINavigationItem class) to specify what buttons or custom views you want displayed. A navigation item has properties for specifying views on the left, right, and center of the navigation bar and for specifying a custom prompt string.
A navigation bar manages a stack of UINavigationItem objects. Although the stack is there mostly to support navigation controllers, you can use it as well to implement your own custom navigation interface. The topmost item in the stack represents the navigation item whose contents are currently displayed by the navigation bar. You push new navigation items onto the stack using the pushNavigationItem:animated: method and pop items off the stack using the popNavigationItemAnimated: method. Both of these changes can be animated for the benefit of the user.
So basically what you need to do is :
[navigBar pushNavigationItem:self.navigationItem animated:NO];

How can I place a header image fixed at the top of my Tab Application?

I want to create a Tab Application with a header image that is always present, no matter what Tab Item is active.
The example would be Foursquare:
I want to be able to place buttons and have different information displayed on that header.
Is that a simple Navigation Bar or something else?
Usually, for each tab is associated a viewController. You can notice it in the boilerplate which xcode creates when you choose "Tabbed Application".
Then, in each viewDidLoad or in the init of each viewcontroller you can set:
self.navigationItem.titleView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image.png"]];
Then just change self.navigationItem.leftBarButtonItem and self.navigationItem.rightBarButtonItem with your controls on each viewController.
Edit:
In the appDelegate (in the didFinishLaunchingWithOptions method) you've to set something like this if you want use the navigationcontrollers:
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
UINavigationController *myNav1=[[UINavigationController alloc] initWithRootViewController:viewController1];
UINavigationController *myNav2=[[UINavigationController alloc] initWithRootViewController:viewController2];
UIImage *navBackgroundImg = [UIImage imageNamed:#"bg_navBar.png"];
UIImage *tabBackgroundImg = [UIImage imageNamed:#"bg_tabBar.png"];
[myNav1.navigationBar setBackgroundImage:navBackgroundImg forBarMetrics:UIBarMetricsDefault];//iOS 5 only
[myNav2.navigationBar setBackgroundImage:navBackgroundImg forBarMetrics:UIBarMetricsDefault];//iOS 5 only
[[UITabBar appearance] setBackgroundImage:tabBackgroundImg];//iOS 5 only
self.tabBarController.viewControllers = [NSArray arrayWithObjects:myNav1, myNav2, nil];
self.window.rootViewController = self.tabBarController;
Looks like a simple navigation bar, but they aren't exactly simple. You need to place/create a NavigationItem on the bar (after placing/creating the bar itself) and then set the titleView to a custom view with your image. According to the documentation the left bar button (close in your first screen) has to be nil or else the titleView is ignored. Though you can place buttons in this custom view for left buttons.
I found out the easiest thing to do is to write:
- (void)viewDidLoad
{
[[UINavigationBar appearance] setBackgroundImage:
[UIImage imageNamed:#"UINavigationBar.png"] forBarMetrics:UIBarMetricsDefault];
}
At my MainViewController, and all Navigation bars that get created on each view controller gets configured like that.

iPhone toolbar for entire app

I have my app base on navigationController. So i set the toolbar visible for some views and for others i didnt calling setToolbarHidden:NO or YES.
first question, this goes in viewWillAppear method ?
Then in my appDelegate, I put one item on the toolbar but is not being show.
can someone show me how can I use delegate protocol here so each view know what to do when a item is pressed??
my code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//create itemViewcontroller
EventosViewController *itemsViewController = [[EventosViewController alloc] init];
//create UINavigationcontroller, stack only contains itemviewcontroller
navController=[[UINavigationController alloc] initWithRootViewController:itemsViewController];
//navController will retain itemviewcontroller, we can release it
[itemsViewController release];
UIBarButtonItem *systemItem1 = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(pressButton1:)];
//Use this to put space in between your toolbox buttons
UIBarButtonItem *flexItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
//Add buttons to the array
NSArray *items = [NSArray arrayWithObjects: systemItem1, flexItem,nil];
//release buttons
[systemItem1 release];
[flexItem release];
//add array of buttons to toolbar
[navController.toolbar setItems:items animated:NO];
//set navController's view in window hierarchy
[[self window] setRootViewController:navController];
[navController release];
// Override point for customization after application launch.
[self.window makeKeyAndVisible];
return YES;
}
thx in advance!
The toolbar us hidden by default. The toolbarItems should be stored in the respective view controller, not the navigation controller.
From the documentation:
Displaying a Toolbar
In iOS 3.0 and later, navigation controller objects make it easy to provide a custom toolbar for each screen of a
navigation interface. The navigation controller object now manages an
optional toolbar in its view hierarchy. When displayed, this toolbar
obtains its current set of items from the toolbarItems property of the
active view controller. When the active view controller changes, the
navigation controller updates the toolbar items to match the new view
controller, animating the new items into position when appropriate.
The navigation toolbar is hidden by default but you can show it for
your navigation interface by calling the setToolbarHidden:animated:
method of your navigation controller object. If not all of your view
controllers support toolbar items, your delegate object can call this
method to toggle the visibility of the toolbar during subsequent push
and pop operations.
you can keep the toolbaritems like this
ThemeDetailViewController *themeDetail = [[ThemeDetailViewController alloc] init];
[self.navigationController pushViewController:themeDetail animated:YES];
themeDetail.toolbarItems = self.parentViewController.toolbarItems;

UIViewController: setToolbarItems vs navigationItem

my application has a UIViewController subclass which is being managed by a UINavigationController.
In the viewDidLoad of my UIViewController subclass, I was attempting to add a UIBarButtonItem to the toolbar like this:
settingsButton = [[UIBarButtonItem alloc] initWithTitle:#"Settings"
style:UIBarButtonItemStylePlain target:self action:#selector(viewSettings:)];
[self setToolbarItems:[NSArray arrayWithObject:settingsButton]];
this wasn't working out for me, so after some googling around, I tried this:
[[self navigationItem] setRightBarButtonItem:settingsButton];
which worked out fine. from reading the UIViewController documentation, I'm still confused about why setToolbarItems wasn't working. I verified in the debugger that the button was in the toolbarItems array in the viewDidAppear method. the button itself just wasn't appearing on my toolbar.
so, my question is, why didn't setToolbarItems work for me in the first code snippet?
I don't have the toolbar configured in my xib for this view controller at all, if that makes a difference.
Yes that make the difference.Whenever you see a bar on view by default for navigation based apps that is not a toolBar actually that is , navigation bar.so you can add item by referencing self.navigationItem.
[self setToolbarItems:[NSArray arrayWithObject:settingsButton]]; essentially populates the navigation controller's bottom toolbar - not the Left and Right top bar buttons.
The bottom toolbar is, by default, not displayed. To display it you must call [self.navigationController setToolbarHidden:NO]
Below is the relevant documentation - UINavigationController Class Reference
toolbar:
The custom toolbar associated with the navigation controller.
(read-only)
#property(nonatomic,readonly) UIToolbar *toolbar Discussion This
property contains a reference to the built-in toolbar managed by the
navigation controller. Access to this toolbar is provided solely for
clients that want to present an action sheet from the toolbar. You
should not modify the UIToolbar object directly.
Management of this toolbar’s contents is done through the custom view
controllers associated with this navigation controller. For each view
controller on the navigation stack, you can assign a custom set of
toolbar items using the setToolbarItems:animated: method of
UIViewController.
The visibility of this toolbar is controlled by the toolbarHidden
property. The toolbar also obeys the hidesBottomBarWhenPushed property
of the currently visible view controller and hides and shows itself
automatically as needed.
try to use
[toolbar setItems:[NSArray arrayWithObject:settingsButton] animated:YES];
instad of :
[self setToolbarItems:[NSArray arrayWithObject:settingsButton]];
shani
On ipad apps, you've got to set toolbar items to the "topViewController" (yes this is counter-intuitive).
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:catView];
UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithTitle:#"item 1" style:UIBarButtonItemStylePlain target:nil action:nil];
UIBarButtonItem *item2 = [[UIBarButtonItem alloc] initWithTitle:#"item 2" style:UIBarButtonItemStylePlain target:nil action:nil];
[nav setToolbarHidden:NO animated:YES];
// WRONG: [nav setToolbarItems:[NSArray arrayWithObjects:addButton, nil]];
// CORRECT (for ipad apps):
[nav.topViewController setToolbarItems:[NSArray arrayWithObjects:item1, item2, nil] animated:NO];
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:nav];

iPhone -- adding a button to a navigation bar created when the user selects a tab in the moreNavigationController

My tab bar has ten tabs. Six of these are therefore shoved into the "More" tab. Several of them do not have UINavigationControllers. I.e, the tab is controlled by a UIViewController subclass that is not a navigation controller.
When the user selects one of these, the appropriate view controller come sup, with a UINavigationBar at the top.
I want to add a button to that navigation bar. How can I do that?
Thanks.
Well, if you want to do this programmatically, then I would suggest replacing each of your viewControllers in your UITabBar with UINavigationControllers that house the respective view controllers.
So, your old code looks something like this:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
UITabBarController *tbc = [[[UITabBarController alloc]init]autorelease];
[window addSubview:tbc.view];
UIViewController *mapVC = [[[UIViewController alloc] init]autorelease];
NSArray *tabViewControllerArray = [NSArray arrayWithObjects:self.mapVC, nil];
tbc.viewControllers = tabViewControllerArray;
}
New code should be:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
UITabBarController *tbc = [[[UITabBarController alloc]init]autorelease];
[window addSubview:tbc.view];
UIViewController *mapVC = [[[UIViewController alloc] init]autorelease];
// add the viewController to a UINavigationController
UINavigationController *mapNav = [[[UINavigationController alloc] initWithRootViewController:mapVC]autorelease];
// put the nav controller in the array instead
NSArray *tabViewControllerArray = [NSArray arrayWithObjects:mapNav, nil];
tbc.viewControllers = tabViewControllerArray;
// this code adds a right button to the mapBav navigationBar
// this uses a custom view, but you could use a standard UIBarButtonItem too
NSArray *items = [NSArray arrayWithObjects: [UIImage imageNamed:#"flag-icon.png"], nil];
UISegmentedControl *tableControl = [[[UISegmentedControl alloc] initWithItems:items]autorelease];
tableControl.segmentedControlStyle = UISegmentedControlStyleBar;
UIBarButtonItem *segmentBarItem = [[[UIBarButtonItem alloc] initWithCustomView:tableControl] autorelease];
self.navigationItem.rightBarButtonItem = segmentBarItem;
}
There are two ways to go about it.
Just use a UINavigationController for each tab, with your view controller in it. But it sounds like you don't want to do this, so:
Put a UINavigationBar in using Interface Builder. nav bar http://cl.ly/395fb8c0a9e9df781897/content
You can then drag in UIBarButtonItems and configure them to your liking, also in IB. buttons http://cl.ly/7501d3e8e5d57dac5e00/content