UINavigationController subclass with custom back button - iphone

I know I can set custom back button from the view controller itself, something like:
- (void)setBackButton
{
UINavigationBar* navBar = self.navigationController.navigationBar;
UIButton* backButton = [navBar backButtonWith:[UIImage imageNamed:#"navigationBarBackButton.png"]
highlight:nil
leftCapWidth:14.0];
[backButton addTarget:self action:#selector(backButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:backButton] autorelease];
}
- (void)backButtonTapped:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
The problem is that I need to do it for all my view controllers...
One solution is to put this code in some BasicViewController and all my view controllers will subclass it.
But my question is can I subclass the UINavigationCotroller itself and set it's nab bar left button to this custom button?

The right way to do this is using UIAppearance
It provides methods on UIBarButtonItem such as
- (void)setBackButtonBackgroundImage:(UIImage *)backgroundImage forState:(UIControlState)state barMetrics:(UIBarMetrics)barMetrics
and
- (void)setBackButtonBackgroundVerticalPositionAdjustment:(CGFloat)adjustment forBarMetrics:(UIBarMetrics)barMetrics

No. It would be better to have a custom UIViewController that handles this behavior.

Related

Custom back button for NavigationController for every screen

I have been trying to subclass the UINavigationController class for modifying things like background image, navigation bar size, back button, tittle font and so on.
After a couple of hours and a lot of reading I have understand that I should not subclass the UINavigationController class...
I would like to have specific design and transfer that design to all screens that use my custom NavigationController...
SO far I haven't fount any elegant solution for this, most of the solutions are based on configuring something for showing in the next screen only (next view).
How can I achieve this? Maybe using categories?
Thanks in advance.
I am showing code for custom leftbarbutton of UINavigationcontroller. You can add this code in each view controller and for both button( right and left)
leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
[leftButton setImage:[UIImage imageNamed:#"Yourcutomeimage.png"] forState:UIControlStateNormal];
leftButton.frame = CGRectMake(0, 0, 30, 30);
[leftButton addTarget:self action:#selector(youraction:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:leftButton]autorelease];
//or
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:leftButton]autorelease];
Hope, this will help you..
Yes #Nit is right, this is the way to customize the UINavigationController, but if you don't want to do it for every UIViewController you have, you can create a UIViewControllerBase class, which is a subclass of UIViewController and in viewDidLoad method, set all your buttons the way #Nit has described and then make every UIViewController you have to be a subclass of your UIViewControllerBase class.
If you want to add a custom back button to uinavigationcontroller you should use navigationItem.backBarButtonItem and implement it in the class where you initialize the uinavigationcontroller.
Sample :-
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"btnImage.png" style:UIBarButtonItemStyleBordered target:youtarget action:#sel(your action)];
self.navigationItem.backBarButtonItem = backButton; [backButton release];
I have outlined my solution in this answer: https://stackoverflow.com/a/16831482/171933
Basically, you create a category on UIViewController and call one single method in every viewWillAppear method of your view controllers.

iPhone custom navigation bar with custom UIBarButtonItems

I'm trying to create a custom navigation bar with title and two custom baritems.
What I've done so far:
1. subclass a UINavigationBar
2. override -(void) drawRect:(CGRect)rect method, to draw image as a background
Now I get stuck when making right bar button item.
In my CustomBar class I've overriden pushNavigationItem method as follows:
- (void)pushNavigationItem:(UINavigationItem *)item animated:(BOOL)animated {
[super pushNavigationItem:item animated:NO];
item.rightBarButtonItem.customView.frame = CGRectMake(250, 5, 60,30);
}
and in my view controller I've done something like:
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:myButton];
self.navigationController.navigationItem.rightBarButtonItem = barButton;
[self.navigationController.navigationBar pushNavigationItem:self.navigationItem animated:NO]
but I always get SIGABRT when calling
[super pushNavigationItem:item animated:NO];
If I leave that line out, everything runs fine, but there is no button in the navigation bar.
What is the proper way to add custom bar button item to custom navigation bar?
EDIT:
For clarification, I've added an image.
This is what I need.
I'm trying to create the logout button on the right
Have you tried removingnavigationController while setting the item ? I used to do that for setting the title, never used to get the title.
Try [[self navigationItem] setRightBarButtonItem:yourButton];
In your case :
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:myButton];
self.navigationItem.rightBarButtonItem = barButton;`

UINavigationController and titleView

My application fit inside a UINavigationController.
Simply I setted up a MyUIViewController as rootViewController of navigationController and than I set up a customTitleView for the navigationItem of myViewController inside viewDidLoad.
Now when I push a newViewController I expect to see the previous customTitleView (as described by Apple NavigationController reference) but it doesn't.
What's wrong?
A little part of code below and the Apple UINavigationController Reference
"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."
- (void)viewDidLoad {
[super viewDidLoad];
[self.navigationItem setTitleView:customTitleView];
}
Maybe the "default title view" means "nothing"? I interpreted it as the previous titleView.
EDIT
I'm trying a work around but I have some other issues.
The work around is:
In every ViewController that I push inside the NavigationController I setup in viewDidLoad the titleView getting it from the rootViewController
UiView *originalContainer = [[[self.navigationController.viewControllers objectAtIndex:0] navigationItem] titleView]
I create a newTitleView and I put inside the originalContainer.subviews (UIButton) cause I need the Target action from it.
All works perfectly for the first pushed controller but if I push another viewController in the stack (the second one pushed) I loose every reference to the navigationController. Every instance variables are nil.
This values are getted inside the viewDidLoad
firstViewControllerPushed.navigationController = (UINavigationController*)0x6693da0
firstViewControllerPushed.parentViewController = (UINavigationController*)0x6693da0
secondViewControllerPushedFromFirstViewControllerPushed.navigationController = 0x0
secondViewControllerPushedFromFirstViewControllerPushed.parentViewController = 0x0
It seems that the secondViewControllerPushed lives nowhere!!
How it's possible?
I double checked that I correctly push the viewController instead of present it modally
Couse this issue I'm not able to make a right setup of the newTitleView for the secondViewControllerPushed.
This is a hack in a half but I feel it gives you a bit more control in the viewController you are working in. So below is a small method I have setup and then I just call it in viewDidLoad - [self setUpNavBar];
And using [UIButton buttonWithType:101] is perfectly fine as it passed Apple Validation.
- (void) setUpNavBar
{
[self.navigationController setNavigationBarHidden: NO animated:YES];
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
self.title = #"Settings";
UIButton* backButton = [UIButton buttonWithType:101]; // left-pointing shape
[backButton addTarget:self action:#selector(backAction) forControlEvents:UIControlEventTouchUpInside];
[backButton setTitle:#"Back" forState:UIControlStateNormal];
UIBarButtonItem* backItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
self.navigationItem.leftBarButtonItem = backItem;
[backItem release];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Logout"
style:UIBarButtonItemStylePlain target:self
action:#selector(logoutAction)] autorelease];
}

How to create navigation bar item in the custom Navigation Bar in iPhone?

I have created one custom view and added a web view as subview of that custom view. And i have created one navigation bar in programmatically. Now i want to create one Left or Right navigation bar buttons in that view.
navigBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
navigBar.tintColor = [UIColor blackColor];
[self.view addSubview:navigBar];
UIBarButtonItem *homeButton = [[UIBarButtonItem alloc] initWithTitle:#"Home" style:UIBarButtonSystemItemAction target:self action:#selector(homeButtonAction)];
navigBar.rightBarButtonItem = homeButton; // it's not supports
How can i create navigation bar item in the custom navigation bar?, i want to remove the custom view. So please Help me out!
Thanks.
On your navigationbar reference you could invoke the two methods:
- (void)pushNavigationItem:(UINavigationItem *)item animated:(BOOL)animated
- (UINavigationItem *)popNavigationItemAnimated:(BOOL)animated
In your custom view controller class write something like this:
self.navigationItem.leftBarButtonItem = yourButton;
self.navigationItem.rightBarButtonItem = yourSecondButton;
So you could write something like this:
[myNavBarReference pushNavigationItem:self.navigationItem animated:NO];
rightBarButton is defined for UINavigationItem. See the documentation for the UINavigationItem and for the UINavigationBar (Specially Adding Content to a Navigation Bar).
The method to use is - (void)pushNavigationItem:(UINavigationItem *)item animated:(BOOL)animated
See http://developer.apple.com/library/ios/documentation/uikit/reference/UINavigationItem_Class/Reference/UINavigationItem.html
You would invoke methods to self.navigationItem.

How to add uitoolbar to uitableviewcontroller?

I have an UITableViewController which I would like to add UIToolbar to with one button. In the
- (void)viewDidLoad;
method of UITableViewController I have:
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(pressButton1:)];
self.navigationItem.title = #"Some title";
self.navigationItem.leftBarButtonItem = button;
}
Unfortunately I don't see the toolbar when I run my app.
Any hints? Should I do something more?
The navigationItem property of a view controller is useless if that controller is not displayed inside a UINavigationController.
If your view controller is inside a navigation controller I don't know what the problem is.
Otherwise you can use an UINavigationItem but you need to create a UINavigationBar yourself.
Either in the Interface Builder (add a UINavigationBar and add a UINavigationItem, then connect the UINavigationItem to a property outlet declared your view controller (you don't need to connect the Bar).
Or in your code :
UIBarButtonItem *item = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self action:#selector(pressButton1:)];
UINavigationItem* navItem = [[UINavigationItem alloc] init];
navItem.rightBarButtonItem = item;
navItem.title = #"Your title";
naviBar = [[UINavigationBar alloc] init];
naviBar.items = [NSArray arrayWithObject:navItem];
naviBar.frame = CGRectMake(0.0, 0.0, self.view.frame.size.width, 44.0);
[self.view addSubview:naviBar];
[navItem release];
Your method requires an autorelease:
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *button = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(pressButton1:)] autorelease];
self.navigationItem.title = #"Some title";
self.navigationItem.leftBarButtonItem = button;
}
There's nothing wrong with your code per se. Your question states you want to add an UIToolBar to your view? Really? Or do you just want to add a button to the NavigationItem for UITableView?
If you don't have to use a UITableViewController and are not using a UINavigationController in your app already, you can set your view controller up as a regular UIViewController with a toolbar and tableview.
To do this in IB, drag out a UIViewController object and add a toolbar and tableview. Hook up outlets for both and set the delegate and datasource of the tableview to Files Owner. Add any other toolbar items or buttons and give them outlets and methods if you need them for buttons, etc. In your ViewController.h file, make sure you sign it up to conform to the UITableViewDataSource and UITabBarDelegate:
#interface ViewController : UIViewController <UITableViewDataSource, UITabBarDelegate>
From there, just build out your tableview delegate and datasource methods like you normally would, and write your button action methods for any buttons you added to the toolbar.
You just didn't show the toolbar. It is hidden by default. To fix it, you just put this line of code:
self.navigationController.toolbarHidden = NO;
I tried it and it worked. Just make sure that you put in the implementation file's viewDidLoad method.