I have navigationController and I want to change nav back button text on appdelegate. so I want to change every uiviewController's back button's text on appdelegate. Is it possible?
I wrote the following code but it's not working.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
navigationController=[[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = self.navigationController;
self.navigationController.navigationItem.backBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:#"custom back text"
style:UIBarButtonItemStyleBordered
target:nil
action:nil]; // didn't work
[self.window makeKeyAndVisible];
return YES;
}
You need to understand the difference between the navigation bar (there is one, owned, managed and controlled by the navigation controller) and the navigation items (there are many, one per view controller in the navigation controllers stack, owned and controlled by the view controllers). So you can't change it from where you are trying.
Instead, change it in each view controller or subclass the navigation controller (or act as its delegate) so you can change each view controller as its added to the stack.
Just adding to the answer that appeared while I was typing.
For example:
UIViewController *viewController = [[UIViewController alloc] init];
viewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"custom back text"
style:UIBarButtonItemStyleBordered
target:nil
action:nil];
[self.navigationController pushViewController:viewController];
But be careful. WIth this you're now responsible for handling the button action and this one here will do nothing.
Related
I have a custom button I want to add onto the navigation bar. So here's what I have so far in my RootViewController (which inherits UIViewController, the UINavigationController is added through the AppDelegate):
In viewDidLoad:
UIBarButtonItem *share = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"icon"] style:UIBarButtonItemStylePlain target:self action:#selector(share:)];
self.navigationController.navigationItem.rightBarButtonItem = share;
Here's how my UINavigationController is set up:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *rootViewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"navbar"] forBarMetrics:UIBarMetricsDefault];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;
}
Why is this not working?
EDIT:
It worked after I replaced self.navigationController.navigationItem.rightBarButtonItem with self.navigationItem.rightBarButtonItem. Why is that? My rootviewcontroller is of type UIViewController and I should access navigationItems through navigationController. What is navigationController in this case?
It worked after I replaced self.navigationController.navigationItem.rightBarButtonItem with self.navigationItem.rightBarButtonItem. Why is that?
Every instance of a UIViewController has a navigationItem. This includes UINavigationController, which is a subclass of UIViewController.
navigationItem is used by a UINavigationController to update its visual state when a new view controller appears. When you modify self.navigationController.navigationItem, you are modifying what would be displayed if you had nested UINavigationControllers. In practice, you will never modify the navigationItem of a UINavigationController because you will not have nested navigation controllers.
As you've discovered, you must modify the view controller's navigationItem in order for the changes to take affect in the navigation controller.
What is navigationController in this case?
navigationController is a reference to the UINavigationController that the view controller represented by self is currently contained within.
For example:
UIViewController* viewController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:viewController];
// This is TRUE: viewController.navigationController == navController
Based on Apple UINavigationController reference by Updating the Navigation Bar, it is stated that
If the new top-level view controller has a custom left bar button
item, that item is displayed. To specify a custom left bar button
item, set the leftBarButtonItem property of the view controller’s
navigation item.
If the new top-level view controller has a custom right bar button
item, that item is displayed. To specify a custom right bar button
item, set the rightBarButtonItem property of the view controller’s
navigation item.
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;
I have the following code taken straight from the NavBar sample code from Apple. I put this in the viewDidLoad method for a view in my app that is being presented modally, and it wont work.
UIBarButtonItem *addButton = [[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"AddTitle", #"")
style:UIBarButtonItemStyleBordered
target:self
action:#selector(addAction:)] autorelease];
self.navigationItem.rightBarButtonItem = addButton;
Any Suggestions?
Okay explained solution:
presentModalViewController:animated: presents a viewController modally, which does not have a UINavigationBar, so you can do some things:
Add a UINavigationBar in your viewController's nib and add the "Add" button there and everything you need to setup.
You can use pushViewController:animated: to show the viewController modally which will be on the navigation stack and have the UINavigationBar for you to add your button
If your first viewController is not a UINavigationController, using pushViewController:animated: won't solve it, so you can present a UINavigationController modally with your viewController as the rootViewController:
YourViewController *viewController =[[[YourViewController alloc] initWithNibName:#"YourViewController" bundle:nil] autorelease];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:viewController] autorelease];
[self.navigationController presentModalViewController:navController animated:YES];
Hope any of this helps
You need to use these lines of code on the page where you present the other view.
sceondController *obj=[[[sceondController alloc] initWithNibName:#"sceondController" bundle:nil] autorelease];
UINavigationController *navController=[[[UINavigationController alloc] initWithRootViewController:obj] autorelease];
[self.navigationController presentModalViewController:navController animated:NO];
and in second view use same code which you are using for making navigation button.
May be it resolves your problem.
I assume your view controller is actually a UINavigationController and everything else is in place. In which case I would change two things.
I wouldn't autorelease the UIBarButtonItem. That tends to be unreliable with view controllers so add the button to your list of things to dealloc at cleanup
I would use the setter function to set the button. Here is my code that works in my navigation controller
clearAllButton = [[UIBarButtonItem alloc] initWithTitle:#"Clear All" style:UIBarButtonItemStylePlain target:self action:#selector(rightButtonPressed:)];
[[self navigationItem] setRightBarButtonItem:clearAllButton];
Run your app in real device. In iOS6 it is not working on simulator.
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];
In my app, I'm presenting a modalviewcontroller as follows and I'm not able to change the navigationbar's title or any of its properties for that matter.
fullListTopCompanies *fullListTopCompaniesInstance = [[fullListTopCompanies alloc] initWithNibName:#"fullListTopCompanies" bundle:nil];
UINavigationController *cntrol = [[UINavigationController alloc] initWithRootViewController:fullListTopCompaniesInstance];
[fullListTopCompaniesInstance setTitle:#"TEST"];
UIBarButtonItem *submit = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(displayViewForPosts)];
fullListTopCompaniesInstance.navigationItem.rightBarButtonItem = submit;
[submit release];
[self presentModalViewController:cntrol animated:YES];
[cntrol release];
I tried instantiating application delegate and assigning its navigationcontroller to local navigationcontroller instance but no use.
Somehow that navigationcontroller is not accessible. It can't be accessed by using "self.navigationitem". Whenever I present modalviewcontroller with the navigationcontroller, this navigation comes below the actual navigationcontroller.
For Example, if you are trying to set title of navigation bar for the ViewController called "ABCViewController", then add
self.Title = #"";
in viewWillAppear Method of the ABCViewController and try to rebuild and Run.
Hope this helps. :)
Whenever I present modalviewcontroller with the navigationcontroller, this navigation comes below the actual navigationcontroller.
That problem is because calling presentModalViewController: on self, you should call it on self.navigationController that way the navigation controller won't be shown below the other one.
As to why you can't set the navigationController's properties, I don't know. It looks Ok to me. But I expect it is because you are setting the properties before viewDidLoad is called by the nib-loader. I think I remember having problems like this myself a long time ago.
You should set the title etc. in the UIViewController subclass's viewDidLoad method and I think you worries will be over.
I've created a simple view based app with xcode template, then i've added your code and it's working for me...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Add the view controller's view to the window and display.
TestViewController *fullListTopCompaniesInstance = [[TestViewController alloc] initWithNibName:#"TestViewController" bundle:nil];
UINavigationController *cntrol = [[UINavigationController alloc] initWithRootViewController:fullListTopCompaniesInstance];
[fullListTopCompaniesInstance setTitle:#"TEST"];
UIBarButtonItem *submit = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(displayViewForPosts)];
fullListTopCompaniesInstance.navigationItem.rightBarButtonItem = submit;
[window addSubview:viewController.view];
[window makeKeyAndVisible];
[viewController presentModalViewController:cntrol animated:YES];
[cntrol release];
[submit release];
return YES;
}