Can a ViewController presented modally use the NavigationController's toolbar - ios

I'm trying to present modally a UITableViewController from a view controller in my navigation controller hierarchy. The modal view should display a toolbar.
Can the navigation controller's managed toolbar be used in view controllers presented modally or should I implement my own toolbar for these?
If I present the controller modally with [self.navigationController presentModalViewController:filterVC animated:YES]; no toolbar is displayed.
If I pushed the controller with: [self.navigationController pushViewController:filterVC animated:YES]; the toolbar is displayed.
Here is the method I run from the init method of my UITableViewController.
-(void)configureToolBar {
[self.navigationController setToolbarHidden:NO animated:YES];
//ToolbarItem Done
UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(doneButtonPressed)];
//ToolbarItem Cancel
UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:#selector(cancelButtonPressed)];
//Flexible Space
UIBarButtonItem *flexibleItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
self.toolbarItems = [NSArray arrayWithObjects:flexibleItem, cancelItem, doneItem, flexibleItem, nil];
[doneItem release];
[cancelItem release];
[flexibleItem release];
}

No, you can't, because a modal view controller becomes a child to the view controller that displays it, and this view controller is a subview of the navigation controller (i.e. the modal view has no connection with the NavigationController's hierarchy). You can present a navigation controller as a modal view controller, though, so you can pass your custom navbar buttons to it.

You have to embed your VC inside a new UINavigationController and set the toolbar items again or you just add a UIToolbar to the bottom of your VC.

Related

How to set up right bar button in nav bar from a tabbed view controller?

Ok, so i'm trying to set up the rightbarbutton for my UINavigationBar and it doesn't want to show up.I am pushing my UIViewController using self.navigationController push method and when i do the following :
for (UIViewController *vc in self.navigationController.viewControllers) {
NSLog(#"VC : %#",NSStringFromClass(vc.class));
}
from the view controller i just pushed, the result is 2 tabbarcontrollers because the previous view controller from which i pushed is a tab out of 2 within a tabbarcontroller... is this related to the fact that my navigation bar right button isn't showing up?
simply doing :
UIBarButtonItem *btn = [[UIBarButtonItem alloc] initWithTitle:#"Logout" style:UIBarButtonItemStylePlain target:self action:#selector(performLogout:)];
self.navigationItem.rightBarButtonItem = btn;
doesn't do the trick

Presenting a UINavigationController from a UIViewController doesn't have default cancel button

I am trying to present a UINavigationController modally from a UIViewController. From previous experience, I'm pretty sure that when I do this there should be a cancel button by default in the navigation bar, however with the following code the navigation bar is completely blank. Any ideas?
UIViewController *rootVC = [[UIViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:rootVC];
[self presentViewController:navController animated:YES completion:nil];
You will not get any bar button items by default. You need to either add the button before presenting, or, more correctly, add the button from inside the root view controller. Normally, you want to have delegation set up, where the presented view controller notifies the presenting view controller that it should dismiss it. Self-dismissing from inside the root view controller is usually not recommended.
– presentViewController:animated:completion: only going to present your view controller as a modal view controller, even you set up that as a navigation controller. the easiest solution in your case is in the navController set the left bar button as the cancel button, and call dismiss when click that button,
UIBarButtonItem *cancelButton= [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(dismissViewController)];
navController.navigationItem.leftBarButtonItem = cancelButton;
- (void)dismissViewController
{
[self dismissViewControllerAnimated:YES completion:nil];
}
Hope that would help.

Back button pressed, losing my custom UIToolBar when i pop the view controller off the stack

I hope everyone is having a great day so far.
I'm running into a problem with my app that I need some help figuring out. I have a view controller (lets call "A") with a custom toolbar which works nicely.
When I push a view controller (lets call it "locationsController") from view controller "A" ...
[self.navigationController pushViewController:self.locationsController animated:YES];
...and I press the back button on the locationsController which closes like this...
[self.navigationController popViewControllerAnimated:YES];
I lose my custom toolbar in view controller "A" when locationController is popped. How do I fix it so I can intercept and call my buildtoolbar method?
Also, the locationsController can be pushed/popped from one other view controller so I'll need to determine which view controller is popping locationsController and either fire the buildtoolbar method or do nothing since the other view controller doesn't have a toolbar.
view controller "A" is a XIB while locationsController is defined in the storyboard.
the XIB does not Have a toolbar in the view/layout thingy.
toolbar code called from viewDidLoad [self buildToolbar]...
-(void) buildToolbar{
blah blah blah
self.navigationController.toolbarHidden = NO;
UIBarButtonItem *flexableItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *refresh = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:#selector(refresh:)];
UIBarButtonItem *comments = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"Comments-selected.png"] style:UIBarButtonItemStyleDone target:self action:#selector(cameraButtonTapped:)];
UIBarButtonItem *pin = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"Pin-straight_60wide.png"] style:UIBarButtonItemStyleDone target:self action:#selector(pinBarButtonItemPressed:)];
NSArray *items = [NSArray arrayWithObjects:customBarButtonItem_right, flexableItem, comments, flexableItem, pin, flexableItem, refresh, nil];
// [self.navigationController.toolbar setItems:items animated:YES];
self.toolbarItems = items;
}
Thanks in advance!
I moved my call to toolbarSetup from viewDidLoad to viewWillAppear. Apparently the 2nd VC's viewDidLoad doesn't fire when the top most VC is popped off the stack.
viewWillAppear fires followed by viewDidAppear, etc....

Custom back button selector not triggered

I have two UIViewcontrollers, let's call them vcA and vcB in an UINavigationController.
I want vcB to have a custom backbutton that triggers some code, the goal is do some custom animation
In vcA I put this code:
UIViewController *vcB = [UIViewController alloc] init]
UIBarButtonItem *customBackButton = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(handleBack)];
self.navigationItem.backBarButtonItem = custombackBackButton;
[self.navigationController pushViewController: vcB animated: YES];
Then I added this code both in vcA and vcB:
-(void) handleBack
{
NSlog(#"Going back to vcA");
}
The handleback method is never called. Any hint?
Thanks
Nicola
Dont get me wrong but i think you need to be clear about push pop of UINavigationController.
A navigation controller manages views by pushing/popping them on/off the controller's view stack. When you push an item, the current view slides off screen to the left, and the new view slides over from the right. Ofcourse these animations can be changed according to your wish.
I think This is what you need completely.
Put this in vcA where you want to push vcB from vcA.
UIViewController *vcB = [UIViewController alloc] init];
[self.navigationController pushViewController: vcB animated: NO];
[UIView transitionWithView:self.navigationController.view
duration:0.8
options:UIViewAnimationOptionTransitionFlipFromRight
animations:nil
completion:nil];
In vcB, you can make a barbuttonitem
UIBarButtonItem *addButton = [[[UIBarButtonItem alloc] initWithTitle:#"BackToVcA"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(addAction:)] autorelease];
self.navigationItem.rightBarButtonItem = addButton;
In addActionMethod: you can put the below code for navigating back with your required animation
- (void)addAction:(id)sender
{
UIViewController *vcA = [UIViewController alloc] init];
[[self retain] autorelease];
[self.navigationController pushViewController: vcA animated: NO];
[UIView transitionWithView:self.navigationController.view duration:0.8 options:UIViewAnimationOptionTransitionFlipFromLeft animations:nil completion:nil];
[self.navigationController popViewControllerAnimated:NO];
}
Use trick given by William Jockusch Setting action for Back Button
And also As per the Updating the Navigation Bar
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 top-level view controller does not have a custom left bar button item, but the navigation item of the previous view controller has a valid item in its backBarButtonItem property, the navigation bar displays that item.
So if you want to have custom selector You need to write this inside vcB NOT IN vbA
vcB.m
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *customBackButton = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(handleBack)];
self.navigationItem.backBarButtonItem = customBackButton;
}
-(void) handleBack
{
NSlog(#"Going back to vcA");
}
NOTE:
UINavigationController Class Reference
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. When this property is nil,
the navigation item uses the value in its title property to create an
appropriate back button. If you want to specify a custom image or
title for the back button, you can assign a custom bar button item
(with your custom title or image) to this property instead. When
configuring your bar button item, do not assign a custom view to it;
the navigation item ignores custom views in the back bar button
anyway.
Here is is mentioned that If you want to specify a custom image or title for the back button, you can assign a custom bar button item (with your custom title or image) but it ignores custom view. So your selector is not invoking.
Your doing mistake. First Push to vcB and in vcB viewDidLoad method put this code.
UIBarButtonItem *customBackButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(handleBack)];
self.navigationItem.backBarButtonItem = custombackBackButton;
and also put this in vcB:
-(void) handleBack{
NSlog(#"Going back to vcA");
}
you can not modify the backBarButtonItems action , it is do the default (back) action , you should do your custom thing in the leftBarButtonItems
in your vcBs class add this :
- (void)viewWillAppear:(BOOL)animated
{
UIBarButtonItem *customBackButton = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(handleBack)];
self.navigationItem.leftBarButtonItem = customBackButton;
}
- (void)handleBack
{
NSLog(#"back");
}

Adding a UIBarButtonItem programmatically to UINavigationBar

I dropped in a UINavigationBar in UIInterfaceBuilder. I present this view modally and just want a UIBackBarButton to return to my last view. I have an outlet and property to this UINavigationBar declared. I thought in my viewDidLoad method, I could create a UIBackButton like this:
UIBarButtonItem *backButton =
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonItemStyleBordered
target:self
action:#selector(goBack)];
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
But I do not see my UIBackBarButtonItem on the UINavigationBar. I think I am doing something wrong here since I don't think my UINavigationBar knows I'm trying to add this UIBackBarButtonItem to it in this way. Would I have to do create an NSArray, put the button in it, and setItems for the NavigationBar instead?
I'm confused on how the navigationItem property works vs the setItems of the UINavigationBar as well. Any help would be appreciated. Thanks!
You are trying to set the Back Button Item in a modal view which doesn't add a backBarButtonItem. This what causes the Button (or any sort of back button for that matter) not to show. The backBarButtonItem is mainly for use with Pushed View Controllers which have a Back Button added from the parent (next item below) when you push a new view controller (top item). The Apple UINavigationItem Documentation says:
When this item is the back item of the navigation bar—when it is the next item below the top item—it may be represented as a back button on the navigation bar. Use this property to specify the back button. The target and action of the back bar button item you set should be nil. The default value is a bar button item displaying the navigation item’s title.
To get the Back Button on the left side like you wish, Try changing
self.navigationItem.backBarButtonItem = backButton;
to
self.navigationItem.leftBarButtonItem = backButton;
making a call such as this from a view controller
{
NextViewController* vcRootView = [[NextViewController alloc] initWithNibName:#"NextView" bundle:[NSBundle mainBundle]];
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:vcRootView];
[vcRootView release];
[self.navigationController presentModalViewController:navController animated:YES];
[navController release];
}
will present NextViewController as a Modal view on the calling view and NextViewController will have a navigationController for it.
In The NextViewController implementation file all you need is this
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem* backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:self
action:#selector(barButtonBackPressed:)];
self.navigationItem.leftBarButtonItem = backButton;
[backButton release];
}
-(void)barButtonBackPressed:(id)sender{
[self dismissModalViewControllerAnimated:YES];
}
to have the back button to dismiss the modalview. Hope it helps.
Use below code snippet :
//Add button to NavigationController
UIBarButtonItem *backButton =
[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#“back”, #"")
style:UIBarButtonItemStylePlain
target:self
action:#selector(goBack)];
self.navigationItem.leftBarButtonItem = backButton;
//Perform action on back Button
- (void) goBack { // Go back task over-here
}
Different style types available are :
UIBarButtonItemStylePlain, UIBarButtonItemStyleBordered, UIBarButtonItemStyleDone
You may use this setters without creation new UIBarButtonItem:
[self.navigationItem.leftBarButtonItem setAction:#selector(doBackButton:)];
[self.navigationItem.leftBarButtonItem setTarget:self];

Resources