UINavigationBarItem programmatically - ios

I have view controller which is inherited from UINavigationController.
On viewDidLoad I want to set rightBarButtonItem.
I do following.
UINavigationItem* navItem = self.navigationItem;
UIButton* btnOptionsView = [[UIButton alloc] init];
[btnOptionsView setImage:[UIImage imageNamed:#"options.png"]
forState:UIControlStateNormal];
[btnOptionsView sizeToFit];
UIBarButtonItem* btnOptions = [[UIBarButtonItem alloc] initWithCustomView:btnOptionsView];
navItem.rightBarButtonItem = btnOptions;
but the button is invisible, in debug mode I have noticed that btnOptions.width is 0, and also I can't set the title for navItem, something like this
[navItem setTitle:#"title"]
does not change the title of UINavigationItem.

You should not subclassing UINavigationController. From apple documentation:
The UINavigationController class implements a specialized view
controller that manages the navigation of hierarchical content. This
class is not intended for subclassing. Instead, you use instances of
it as-is in situations where you want your application’s user
interface to reflect the hierarchical nature of your content.

try to change the title of the button

Related

UIButtonBarItem looks wrong

I think this is going to be a stupid question, but I can't seem to find the answer. I have a few simple lines of code to put a button in the navigation bar:
UIBarButtonItem *cancelButton=[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:#"button-cancel.png"] style:UIBarButtonItemStylePlain target:self action:#selector(cancelPressed:)];
UINavigationItem *item = [[UINavigationItem alloc] init];
item.leftBarButtonItem = cancelButton;
item.hidesBackButton = YES;
[self.navigationBar pushNavigationItem:item animated:NO];
This button works fine, but it looks like this:
Any thoughts?
You probably want to create the bar button item using a custom view, where the custom view is a UIButton:
UIImage *cancelImage = [UIImage imageNamed:#"button-cancel"];
UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
cancelButton.frame = (CGRect){CGPointZero, cancelImage.size);
[cancelButton setImage:cancelImage forState:UIControlStateNormal];
UIBarButtonItem *cancelBarButton = [[UIBarButtonItem alloc] initWithCustomView:cancelButton];
Set your button (cancelButton) size according to the size of the button-cancel.png.
stopButton.frame = CGRectMake ();
Instead, create a custom type UIButton with your image. Set the target and selector of the UIbutton to what you wish the bar button item to do. Then initialize the bar button item as follows:
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
Where button is your UIButton using the desired image.
UIBarButtonItem/initWithImage: is typically used for making iconic buttons - not buttons that have text in them.
If you just want to change how the common textual UIBarButtonItem looks, you just need to set the background image of your bar button item. This way you don't have to have images for each button that contain your button text.
Docs: - (void)setBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics
You can also set this app-wide by calling setBackgroundImage: on the UIBarButtonItem appearance proxy.
Lastly, note that you'll likely need to create a resizeable image to pass to setBackgroundImage. This will let your single image accomodate any button size. See UIImage/resizeableImageWithCapInsets:resizingMode: (iOS6) or UIImage/stretchableImageWithLeftCapWidth:topCapHeight: (pre iOS6)
You can certainly do what #Wain suggests but there are drawbacks. For one, your press-handler will no longer be sending a UIBarButtonItem as the 'sender'. That may not seem like much until you have a common handler that suddenly needs to determine if the sender is a UIBarButtonItem or a UIButton, or if you want to present a UIPopoverController against this BarButtonItem (but you only have the UIButton reference...)

How to create Navigation bar with back button on it?

I am very new to iOS App Development.
In my app I am trying to navigate from second view to first view using navigation bar back button, but while drag and drop the navigation bar in the view I am just able to get the bar with title.
I am really worried and I am not sure what I am doing wrong? I am using Xcode 4.3. and storyboard to design the view.
What i am getting now
Looking for
Thanks for your help guys
Xcode handles this for you.
Highlight your first controller. Go to the menu bar and click Embed In > Navigation Controller. Now using UIButton or something, control-click and drag from your first view controller's button to your second view controller and make it a Push segue. The back button won't appear, but if you run it, it will be there.
So you should have 3 views in storyboard. The Navigation Controller, your first view controller, and your second view controller.
Here is one way to do it using code.
if you want to get a plainButton in the navigation like the iphone`s backButton (only one view), you must add image, i think there is no other way.Of course , if you have 2 or more viewcontrollers , you will use navigationItem.backBarButtonItem without add image .But the first viewcontroller do not have the backButton.
the code like this:
navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
UINavigationItem *navigationItem = [[[UINavigationItem alloc] initWithTitle:#"Detail"] autorelease];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 70, 30)];
[button setImage:[UIImage imageNamed:#"plain.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonClicked:)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc]
initWithCustomView:button];
navigationItem.leftBarButtonItem = buttonItem;
[buttonItem release];
[button release];
[navigationBar pushNavigationItem:navigationItem animated:NO];
[self.view addSubview:navigationBar];

iOS Custom Back Button without calling method in every View Controller

I would like a more elegant solution to changing the back button for an Application's Navigation Bar. All the answers I've seen only talk about customizing a button and then adding at least one line of code to each View Controller for the new button to display.
I have a category where I modify the Navigation Bar's background and Title. It's a category of UINavigationBar. The category calls willMoveToWindow: to call methods each time a new view is pushed on the Navigation Controller.
So here's how the code to create a new button would look:
- (void)applyCustomButton{
UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 26, 26)];
[backButton setImage:[UIImage imageNamed:#"arrow-left"] forState:UIControlStateNormal];
[backButton setShowsTouchWhenHighlighted:TRUE];
[backButton addTarget:self action:#selector(popViewControllerAnimated:) forControlEvents:UIControlEventTouchDown];
UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
[self.navigationItem setLeftBarButtonItem:barButtonItem];
}
The problem here is that self.navigationItem won't work here. I don't want to bore you with all the things I tried categorizing, but that property only works on View Controllers (I think)?
You don't have to give me a solution for the code above, maybe you have a better way of customizing the Back Button on the Navigation Bar without having to write code on every View Controller Class I have. I just hate repetition because maintaining code like that sucks.
Thanks in advance.

UINavigationBar with a 'Back' button. Create with XIB

My question is next:
In interface builder i create UINavigationBar and I want to create 'Back' button item, but I dont see any button.
I use this code:
UIBarButtonItem *myBarButtonItem = [[UIBarButtonItem alloc] init];
myBarButtonItem.title = #"Back";
mynavBar.backItem.backBarButtonItem = myBarButtonItem;
mynavBar - this is my IBOutlet.
Thanks for help!
You can use a navigation bar as a standalone control or in conjunction with a navigation controller. When you use a navigation bar as a standalone control you use a navigation item (an instance of the UINavigationItem class) to specify what buttons or custom views you want displayed.
So in your case you would use something like this:
UIBarButtonItem *myBarButtonItem = [[[UIBarButtonItem alloc] init] autorelease];
myBarButtonItem.title = #"Back";
UINavigationItem *right = [[[UINavigationItem alloc] initWithTitle:#"Hello!"] autorelease];
right.leftBarButtonItem = myBarButtonItem;
[mynavBar pushNavigationItem:right animated:YES];
You may want to look into using UINavigationViewController though.
If you want a custom button on the left, use mynavBar.leftBarButtonItem instead of backItem.
The backItem will only be visible, after you presented another viewcontroller via pushViewController:. (If you didn't set you own backbutton, the default backButton with the title of the previous viewController will be created automatically.)
//edit: perhaps you look for that:
Draw custom Back button on iPhone Navigation Bar
I think this is the actual way apple want this to be implemented.
Put UINavigationBar
Set outlet to the UINavigationItem
This is the catch
Override navigationItem property to return the UINavigationItem you created.
That's it.
-(UINavigationItem *) navigationItem
{
return self.navigationItem1;
}
If your navigationItem is still in the UINavigationBar, I think you will need to have a strong outlet to the UINavigation Bar too. Please correct me if I am wrong here.

UINavigationController barstyle property changes layout

I have a modal view controller which displays a navigation controller. The navigation controller in-turn has a regular UIViewController as its root view controller. The only UI element that the above-mentioned UIViewController has is a UISwitch.
Now here's the problem: When I change the barStyle property of the navigation controller, the layout of the UISwitch inside the UIViewController changes. Here's what I am talking about:
If I don't set the barStyle property, here's what I get:
http://img535.imageshack.us/img535/2281/plaini.png
The UISwitch is now in its 'exepected' place.
Now if I set the barStyle property,
navController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
Notice that the UISwitch is behind the navigation bar:
http://img853.imageshack.us/img853/2377/blackya.png
Here's the code for the UISwitch in the UIViewController:
- (void)viewDidLoad
{
UISwitch* mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(20, 20, 100, 100)];
[self.view addSubview:mySwitch];
[mySwitch release];
}
Can someone help me understand what's happening?
The Frame shifts when you use the UIBarStyleBlackTranslucent (which is actually deprecated) property because it assumes you want your view to be underneath
The Apple Documentation says to use the following since UIBarStyleBlackTranslucent is deprecated:
navController.navigationBar.barStyle = UIBarStyleBlack;
navController.navigationBar.translucent = YES;
You could try shifting your view back in the correct place or try using the following:
navController.navigationBar.tintColor = [UIColor blackColor];
navController.navigationBar.translucent = YES;

Resources