Custom back button for NavigationController for every screen - iphone

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.

Related

UINavigationController subclass with custom back button

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.

UIActionSheet with UIPickerView and Done, Next, Previous buttons

i am trying to implement an action sheet that contains a picker view and a segmented control bar with a previous button, next button and done button like the image as follows http://imgur.com/8wVMy. I currently am able to make it look like this http://imgur.com/AXn6H. I was wondering if someone could help me get the picker view to sit on the bottom and just make it look a little better. Thanks for any help.
Unless you're targeting very old versions of iOS (i.e. versions earlier than 3.2), the best way to do it is to take a completely different approach.
As of 3.2, any UIResponder (which includes all UIViews) can return a UIView from its inputView property to show that view instead of the keyboard when the view becomes the first responder. This even works for views that normally don't become first responder or don't display the keyboard at all. It's simple:
Design your popup view, as you would any other view.
Ensure that your widget view returns YES from canBecomeFirstResponder.
Ensure that your widget view returns an instance of your popup view from inputView.
More details are available in the documentation.
Also, BTW, if you're on an iPad you should probably use a UIPopoverController to display a UIPickerView instead of either of these methods. Apple may actually require this if you intend to get your app in the app store.
The next and previous buttons are actually showing your images to segmentedController Within a toolbar. To get it You have to define the segmentedController and UIToolbar on. H. Next add the DataSource and UIPickerView
Then in the viewDidLoad create objects and define Their properties. For example:
if (keyboardToolbar == nil) {
keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
[keyboardToolbar setBarStyle:UIBarStyleBlackTranslucent];
segControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Anterior", #"Siguiente", nil]];
[segControl setSegmentedControlStyle:UISegmentedControlStyleBar];
[segControl setTintColor:[UIColor blackColor]];
segControl.frame = CGRectMake(5, 7, 150, 33);
segControl.momentary = YES;
[segControl addTarget:self action:#selector(segSelected:) forControlEvents:UIControlEventValueChanged];
UIBarButtonItem *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *aceptar = [[UIBarButtonItem alloc] initWithTitle:#"Hecho" style:UIBarButtonItemStyleDone target:self action:#selector(cerrarTeclado:)];
//aceptar.width = 70.0f;
[keyboardToolbar setItems:[[NSArray alloc] initWithObjects: extraSpace, aceptar, nil]];
[keyboardToolbar addSubview:segControl];
}

how to determine that the navigation bar's back button has been clicked and then showing a alert

working on a game based project.i am having a view controller as GameScreen.
on the top of Gamescreen having a navigation bar with back button(default).Now if user clicks on back button i have to show alert.
so how to determine "backbutton got clicked."?
any suggestion?
Thanks
In your viewdidload method :
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:#"back_button.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(cancel:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:button] autorelease];
In the cancel method:
- (IBAction) cancel:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
or show your alert view
}
Otherwise also you can just override the method if you do not want a custom back button.
Your UINavigationBarDelegate has got a nice method for that, called shouldPopItem.
You can override that in your delegate and show there the alert. This gives you also a chance to cancel the going-back (popping).
Stopping the self.navigationItem.leftBarButtonItem from exiting a view - here you go maddy, answers the question in a different context but same basis -

Back button on UINavigationController

I know that it could seem strange but i need to add a back button on the navigation Bar of the first navigationController's view. I tried like this:
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Foo" style:UIBarButtonItemStyleBordered target:self action:#selector(foo:)];
self.navigationItem.backBarButtonItem=backButton;
if instead of backBarButtonItem i write leftBarButtonItem the button is showed. My problem is that i need an arrow button as the normal back button. Is this possible?
Usually this works out of the box, but sometimes with modal views / action sheets you may need this. Just before you instantiate your viewcontroller and push it onto navigationcontroller stack, try
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle: #"Back" style: UIBarButtonItemStyleBordered target: nil action: nil];
[[self navigationItem] setBackBarButtonItem: newBackButton];
[newBackButton release];
DetailViewController *detailVC = [[DetailViewController alloc]init];
[self.navigationController pushViewController:detailVC animated:YES];
[detailVC release];
I don't think you can do that on the first NavigationController view, because you need to set the backBarButtonItem property in the parent controller, before the child controller is pushed. Also, according the to the Apple docs, the target & action of the backBarButtonItem must be nil.
This question about creating a left-arrow button on a UIToolbar may give you some ideas of how you could work around this using a custom image (for the leftBarButtonItem).
or you could also do the following - I prefer this method. I got this from a different post.
Use following psd that I derived from http://www.teehanlax.com/blog/?p=447
http://www.chrisandtennille.com/pictures/backbutton.psd
Then I just create a custom UIView that I use in the customView property of the toolbar item.
Works well for me.
Hope that helps a little
Of course you can do this. You just need to change the leftBarButtonItem's title to back
then you will get a nice left arrow button with the title back. Then you just change the selector to actually perform a method when the button is clicked. So #selector(foo:)
Here some code on how to achieve the above:
self.navigationItem.leftBarButtonItem.style = UIBarButtonItemStyleDone;
self.navigationItem.leftBarButtonItem.title = #"Back";
self.navigationItem.leftBarButtonItem.target = self;
self.navigationItem.leftBarButtonItem.action = #selector(endTextEnteringButtonAction:);
Let me know if that helps.
Apple Document says:
When this navigation item is immediately below the top item in the stack, the navigation controller derives the back button for the navigation bar from this navigation item.
So If your navigation item is the top of the Stack (as we are talking here) you can't add the back button to the navigation controller, simply because no place he can navigate back to it because it's the top item in the stack.
Updated Answer :
After I searched I found work a round to make a back button in your root view controller in Navigation controller in these link
It's very simple :)
[self.navigationItem setHidesBackButton:YES animated:YES];
UIBarButtonItem* backButton = [[UIBarButtonItem alloc] initWithTitle:#"Start" style:UIBarButtonItemStyleBordered target:self action:#selector(initializeStuff)];
self.navigationItem.leftBarButtonItem = backButton;

adding button to the navigation bar

i have a problem while adding button to the navigation bar.. My application consist of two view controllers added to the viewControllers array of a tabBarController. Inturn this tabBarController is added to the viewControllers array of a navigationController. In one of the views i have a textfield for entering dates . On the tap of this textfield the datepicker will pop up. simultaneously i want to display a done button on the navigation bar. how can i do this... i tried using
self.tabBarController.navigationController.navigationItem.rightBarButtonItem = self.doneButton;
But this is not working...
Pls help me out..
Try this code,
UIBarButtonItem *addButton = [[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Done", #"")
style:UIBarButtonItemStyleBordered
target:self
action:#selector(DoneButton)] autorelease];
self.navigationItem.rightBarButtonItem = addButton;
Best of luck.
Try with this
UIBarButtonItem* _doneButton;
self.navigationItem.rightBarButtonItem = _doneButton;
use this one:
UIButton *myBtn = [[UIButton alloc]init];
[self.navigationItem.titleView addSubview:myBtn];