What to do when UIBarButtonItem are not visible in UINavigationBar? - iphone

Hello Everyone
I am writing a simple code in ViewDidLoad, and class is child of UITableViewController, like below but buttons are not visible, while title is visible,
Another thing that I am clicking a button which in ViewDidLoad method ViewController.m, and which is call a method, code of that method is as below
//Code of button target method
-(void)statusMethod {
NSLog(#"statusMethod");
Status *ob=[[Status alloc]init];
[self presentModalViewController:ob animated:YES];
}
//Code of ViewDidLoad of Status.m
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, width, 43)];
navBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self.view addSubview:navBar];
[navBar release];
UIBarButtonItem *home = [[UIBarButtonItem alloc] initWithTitle:#"HOME" style:UIBarButtonItemStylePlain target:self action:#selector(homeMethod)];
self.navigationItem.rightBarButtonItem = home;
UIBarButtonItem *add = [[UIBarButtonItem alloc] initWithTitle:#"Add" style:UIBarButtonSystemItemAdd target:self action:#selector(addMethod)];
self.navigationItem.leftBarButtonItem = add;
UILabel *label = [[UILabel alloc] initWithFrame:
CGRectMake(10,10,width-20,25)];
label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
label.text = #"Status";
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont systemFontOfSize:25];
label.textAlignment = UITextAlignmentCenter;
[navBar addSubview:label];
[label release];
Any Idea, what is problem in code?
I you don't understand, then u can ask me again,
I will praise, if I will get solution of my problem

It seems like self.navigationItem is only looked at by the UINavigationController (controller, not bar). The bar itself isn’t going to check that.
So you should either
1) Use a real UINavigationController which comes with its own navigationBar and will handle the navigationItems for you. The self.navigationItem code above will work in that case. (you should consider self.navigationItem.title = #"Status";)
If your UITableViewController is going to be pushing stuff on and off the navigation stack, this is the path you should take in any case.
2) Use the UINavigationBar’s own navigation item. Except it doesn’t seem to come with a navigation item, so you have to add your own:
UINavigationItem *navItem = [[UINavigationItem alloc] initWithTitle:#"Status"];
[navBar setItems:[NSArray arrayWithObject:navItem]];
[navItem release];
and then set the left and right buttons as
[navBar topItem].leftBarButtonItem = add;
[add release];
[navBar topItem].rightBarButtonItem = home;
[home release];
Dealing with UINavigationController/UINavigationBar/UINavigationItem can be confusing, but luckily Apple has a decent explanation of how all these things work together at the top of its UINavigationController documentation.

Related

label is not visible in UIToolBar

I am attempting to set a label into a subclassed UIToolBar. I am first creating the label, then converting it to a UIBarButtonItem and setting them to the toolbar, but the toolbar just appears blank.
here is my code in my init method of my subclassed toolbar
NSMutableArray *items = [[NSMutableArray alloc] init];
// prep the total label
_totalLabel = [[UILabel alloc] init];
_totalLabel.font = [_totalLabel.font fontWithSize:15];
_totalLabel.textColor = [UIColor whiteColor];
_totalLabel.text = NSLocalizedString(#"TOTAL", nil);
_totalLabel.frame = CGRectMake(0, 0, 100, 44);
_totalLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleTopMargin;
_totalLabel.layer.borderWidth = 2;
_totalLabel.layer.borderColor = [UIColor greenColor].CGColor;
_totalLabel.backgroundColor = [UIColor clearColor];
UIBarButtonItem *spacer2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[items addObject:spacer2];
UIBarButtonItem *total = [[UIBarButtonItem alloc] initWithCustomView:_totalLabel];
[items addObject:total];
[self setItems:items];
any idea whats wrong?
Where are you calling this code from? If you have it in initWithFrame: or initWithCoder: it will not work.
Try this:
- (void)layoutSubviews {
[super layoutSubviews];
if(self.items.count == 0) {
//Your code here
}
}
That will get it working. The question is though should you be doing this in layoutSubviews? Probably not. You could also put a setup method on your UIToolbar and call that at a later point in your application.
This is not a uitoolbar. this is a navigation bar so please remove navigationbar and add toolbar . Try this type .

can I add a UIBarButtonItem completely IB free?

I created a nav bar and a label programmatically in my view controller. Now I want to add a "done" button but cant seem to find a way without using IB....is there any way to do that?
Here is my view controller's viewDidLoad:
//Adding navBar programmatically
CGFloat width = self.view.frame.size.width;
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0,0,width,52)];
navBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self.view addSubview:navBar];
//Adding label to navBar programmatically
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10,2,width-20,14)];
label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
label.text = #"TITLE";
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont systemFontOfSize:22];
label.shadowOffset = CGSizeMake(1,1);
label.textColor = [UIColor whiteColor];
label.textAlignment = UITextAlignmentCenter;
[navBar addSubview:label];
//Adding back button to navBar programmatically
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStylePlain target:self action:#selector(dismissView:)];
self.navigationItem.leftBarButtonItem = rightButton;
Last part obviously doesnt work...
Thanks for any help!
Why are you not using a UIToolBar instead?
To add buttons to a UINavigationBar, you need to create a UINavigationItem. If you're using UINavigationBar as part of UINavigationController (as is the common case), this is done automatically, as a standalone view, you have to do this yourself.
UINavigationItem *item = [[[UINavigationItem alloc] initWithTitle:#""] autorelease];
item.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(dismissView:)] autorelease];
[navBar setItems:[NSArray arrayWithObject:item] animated:NO];
The navigationItem is only used when you push a viewcontroller in a navigationcontroller
in your case you need to use
-pushNavigationItem:animated:
on the UINavigationBar
Check the docs for more details:
http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UINavigationBar_Class/Reference/UINavigationBar.html

creating apple ipad mail view

I am trying to create a view that looks like the following:
I know it's a UISplitView, however my issue is that on creating the UIToolBar that is below the UITableView to the left and also on how to create the icons on top of the detail view (the one with the trash can logo, reply, and new message). How do I do this?
If you look at the DetailView.xib for a UISplitView project in Interface Builder you can drag UIBarButtonItems onto the toolbar contained in it.
To get a toolbar in the popover controller you can just use the toobar that comes with a UINavigationController. The code below should give you an idea of how to do this. Add this code to RootViewController.
- (void)viewDidLoad
{
[super viewDidLoad];
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
//setup toolbar
self.navigationController.toolbarHidden = NO;
UIBarButtonItem *refreshItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:#selector(refresh:)];
[self setToolbarItems:[NSArray arrayWithObjects:refreshItem, nil]];
[refreshItem release];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(60.0, 10.0, 200.0, 21.0)];
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
label.text = #"This is a label on the toolbar";
[self.navigationController.toolbar addSubview:label];
[label release];
}

toolbar does not get populated

In my loadView methoad of my view controller I have the following code:
// Populate self.view and add some views/UI elements
// load Gender selection Bar
self.navigationController.toolbarHidden = NO;
self.navigationController.toolbar.tintColor = [UIColor colorWithRed:0 green:0.37 blue:0.5 alpha:1];
self.genderControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:NSLocalizedString(#"Male", nil), NSLocalizedString(#"Female", nil), nil]];
genderControl.segmentedControlStyle = UISegmentedControlStyleBar;
genderControl.frame = CGRectMake(0, 0, 200, 30);
genderControl.tintColor = [UIColor colorWithRed:0 green:0.37 blue:0.5 alpha:1];
[genderControl addTarget:self action:#selector(changeGender:) forControlEvents:UIControlEventValueChanged];
genderControl.selectedSegmentIndex = GENDER_MALE;
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:genderControl];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[[[self navigationController] toolbar] setItems:[NSArray arrayWithObjects:flexSpace, item, flexSpace, nil] animated:YES];
[item release];
However, if I load the view it displays the toolbar, but the Segmented Control does not get displayed. If I move my code to the viewWillAppear: method it works, but once I hide my view and redisplay it again the segmented control is gone anew.
Does anybody know this problem and/or has an idea how to solve it? Looks very strange to me.
Most of your code looks fine to me, and everything should work when called from the viewDidLoad or the loadView method.
However, when you use the included toolbar from the NavigationController, toolbar items are set on the ViewController rather than the toolbar itself. So replace this line:
[[[self navigationController] toolbar] setItems:[NSArray arrayWithObjects:flexSpace, item, flexSpace, nil] animated:YES];
With this:
[self setToolbarItems:[NSArray arrayWithObjects:flexSpace, item, flexSpace, nil] animated:YES];
Documentation here: http://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/setToolbarItems:animated:
You will also want to add this line:
[flexSpace release];
Are you sure that this code should be in loadView? Check the UIViewController docs: loadView is used for constructing your view controller's view entirely programmatically - nothing is loaded from a nib if you implement loadView. Should this code be in viewDidLoad instead? I see that you're not even creating and assigning the main UIView in your loadView method -- which you'd normally expect to see, e.g.:
self.view = [[[UIView alloc] init] autorelease];
If you did mean to implement loadView, as you have, you should add the above line for assigning your main view towards the top of the method, rather than later on.
Btw, perhaps don't bother calling [toolbar setItems] with animated=YES; not much point and I've seen the exact value of the animated parameter break things inexplicably in the past!

Proper way to add a title to a modal view controller's toolbar?

Right now I'm using this in my -viewDidLoad method:
UIToolbar *toolbar = [[UIToolbar alloc] init];
UIBarButtonItem *flexibleSpace = [UIBarButtonItem alloc];
flexibleSpace = [flexibleSpace initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
// Add a back button to allow user to close the modal view
NSString *back = NSLocalizedString(#"Back", nil);
UIBarButtonItem *backButton = [UIBarButtonItem alloc];
backButton = [backButton initWithTitle:back
style:UIBarButtonItemStyleDone
target:self
action:#selector(dismissModalViewControllerAnimated:)];
// Add a centered title to the toolbar
// I doubt this is the "correct" way to do this, but it seems to work.
// The "width" property of a UIBarButtonItem doesn't seem to correspond to
// the actual width if the button is flexible (i.e. the width isn't explicitly
// set), so I'm using this hack instead.
// This is obviously NOT an optimal solution. For one thing, if the button padding
// ever changes, it has to be changed manually here as well. For another, it is
// a pain to do this for every button I add to the toolbar, and furthermore the title
// is centered only according to its own width, not the toolbar's.
const CGRect toolbarFrame = [toolbar frame];
const CGFloat backWidth = [back sizeWithFont:[UIFont boldSystemFontOfSize:[UIFont buttonFontSize]]
constrainedToSize:toolbarFrame.size].width;
const CGRect titleFrame = {{0.0f, 0.0f},
{toolbarFrame.size.width - (backWidth * 2.0f), 50.0f}};
UILabel *titleLabel = [[UILabel alloc] initWithFrame:titleFrame];
[titleLabel setText:[self title]];
[titleLabel setBackgroundColor:[UIColor clearColor]];
[titleLabel setTextAlignment:UITextAlignmentCenter];
[titleLabel setFont:[UIFont boldSystemFontOfSize:20.0f]];
[titleLabel setTextColor:[UIColor whiteColor]];
[titleLabel setShadowColor:[UIColor colorWithWhite:0.0f alpha:0.5f]];
[titleLabel setShadowOffset:CGSizeMake(0.0f, -1.0f)];
UIBarButtonItem *titleItem = [[UIBarButtonItem alloc] initWithCustomView:titleLabel];
[titleLabel release];
NSArray *items = [[NSArray alloc] initWithObjects:flexibleSpace, titleItem, backButton, nil];
[flexibleSpace release];
[titleItem release];
[backButton release];
[toolbar setItems:items];
[items release];
[view addSubview:toolbar];
[toolbar release];
Does anyone have a better method for doing this? What I'm using feels like a major hack :(.
Edit:
Thanks for the suggestion Darren!
Here's what I'm using now, if anyone's interested:
First, in accordance with Darren's suggestion, I'm wrapping my modal view controller in a generic UINavigationController (which contains it's own UIToolbar, UINavigationBar, that comes with a title):
MyCustomViewController *myModalViewController = [[MyModalViewController alloc] init];
[myModalViewController setTitle:#"Foo"];
UINavigationController *modalNavController = [[UINavigationController alloc] initWithRootView:myModalViewController];
[myModalViewController release];
// This is intended to be presented in another view controller class
[self presentModalViewController:modalNavController animated:YES];
[modalNavController release];
Then in my -init method for the MyModalViewController class, I have this:
- (id)init
{
if (self = [super init]) {
UIBarButtonItem *backButtonItem = [UIBarButtonItem alloc];
backButtonItem = [backButtonItem initWithTitle:back
style:UIBarButtonItemStyleDone
target:[self navigationController]
action:#selector(dismissModalViewControllerAnimated:)];
[[self navigationItem] setRightBarButtonItem:backButtonItem];
[backButtonItem release];
}
return self;
}
This is a much cleaner solution than before. Thanks.
You should wrap your view controller inside a generic UINavigationController when you present the modal view:
MyCustomController* myController = [[MyCustomController alloc] init];
editor.title = #"My Title";
UINavigationController* modalController = [[UINavigationController alloc] initWithRootViewController:myController];
[self.navigationController presentModalViewController:modalController animated:YES];
[modalController release];
[myController release];
Your custom controller can specify its toolbar buttons in its init method:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:#selector(doCancel:)] autorelease];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave
target:self
action:#selector(doSave:)] autorelease];
}
return self;
}
You should be adding the title in the items property
i.e.
#property(nonatomic, copy) NSArray *items
where items is init with a title
initWithTitle:style:target:action:
See http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIToolbar_Class/Reference/Reference.html#//apple_ref/occ/instp/UIToolbar/items
and
http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIBarButtonItem_Class/Reference/Reference.html#//apple_ref/occ/instm/UIBarButtonItem/initWithTitle:style:target:action:
for the details.
Hope that helps
[Edit]
P.S. The UIBarButtonItem is also where you would be adding your buttons ;-)