I have a subclass of a UITableViewController, and I want to add a UINavBar to it. It is a very similar setup to the native contacts app, where you tap "add contact", and it presents a grouped tableview with a navbar at the top with a "cancel," and "done" option. The key is that I need it to present using a vertical transition (effectively with presentModalViewController:animated:yes), but I have tried using Interface Builder and adding it programmatically, and in both cases, the buttons do not respond, and the bar scrolls with the tableview, rather than staying at the top.
Thanks in advance,
HBhargava
It sounds like you're making the navigation bar a subview of the table view, that explains why the navigation bar scrolls with the table view.
Try this in the action method:
MyTableViewController *table = [MyTableViewController alloc] initWithStyle:UITableViewStyledGrouped];
UINavigationController *nav = [UINavigationController alloc] initWithRootViewController:table];
[self presentModalViewController:nav animated:YES];
Then in your table view controller's viewDidLoad:
UIBarButtonItem *doneButton = [UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(done:)];
self.navigationItem.rightBarButtonItem = doneButton;
Related
After reading a bunch of similar questions on SO I've found out that in order to use a custom back button view I should be setting the nav controller's nav bar's nav item's left button item to a custom view, but no matter what I do I'm getting stuck with the default. I've tried setting this both inside the view controller I want to navigate back from, as well as the one I'm navigating back to, to no avail. Any ideas what I might be doing wrong?
- (void)loadView{
[super loadView];
UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc]initWithCustomView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"back-btn"]]];
self.navigationController.navigationItem.leftBarButtonItem = backButtonItem;
self.navigationController.navigationItem.leftBarButtonItem.tintColor = [UIColor whiteColor];
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
The key thing you’re doing wrong is using the bar button item on the navigation controller instead of on your view controller. To quote Apple’s View Controller Catalog for iOS:
In a navigation interface, each content view controller in the navigation stack provides a navigation item as the value of its navigationItem property.
Emphasis mine; the content view controller is your custom view controller. Try this:
self.navigationItem.leftBarButtonItem = backButtonItem;
You need to do this in all your view controllers that should have the custom button, so I recommend creating your own base view controller class that subclasses UIViewController and implements custom back buttons, and use this base view controller as the parent of your other view controllers.
You’re hiding the navigation bar, which probably isn’t a good idea if you want it to show a custom back button.
By replacing the standard back button, you lose its tap behaviour. Use a UIButton in the bar button item’s custom view instead of a UIImageView.
Also, it would be more conventional to put this setup code in viewDidLoad rather than loadView.
So I would do something like this:
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton setBackgroundImage:[UIImage imageNamed:#"back-btn"] forState:UIControlStateNormal];
[backButton sizeToFit];
[backButton addTarget:self action:#selector(popNavigationController:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
self.navigationItem.leftBarButtonItem = backButtonItem;
}
- (void)popNavigationController:(id)sender
{
[[self navigationController] popViewControllerAnimated:YES];
}
Note that if you use a custom back button, the swipe-from-the-edge-of-the-screen-to-go-back gesture will not work. See this Stack Overflow question for a couple of potential solutions, but it’s fiddly.
Im adding a right bar button to my navigation bar. It appears and it works fine.
The problem is that it´s not animated. I mean, when I move to other views by clicking in some row, it just suddenly pops out and you can see the new view moving behind it until the sliding animation is finished.
UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithTitle:#"Close"style:UIBarButtonItemStylePlain target:self action:#selector(closePopOver)];
[self.navigationItem setRightBarButtonItem: closeButton animated:YES];
[closeButton release];
And I add it in the initWithNibName: method. I´ve tried to move it to the viewDidLoad and it didn't work.
Any ideas?
There are specific methods you can use to animate the right bar button items:
[self.navigationItem setRightBarButtonItem: self.addToOrderButton animated:YES];
I have ViewController in which is WebView (loading web site inside) and I want on start loading to show UIActivityIndicator left in navigation controller and when loading is done remove it.
I have ViewController with embed navigation controller and I've tryed to put over IB UIIndicator but with no success, it's put in content part so pls tell me how programmatically put indicator in navigation bar left side.
Thank's for help
You won't be able to put an activity indicator in the nav bar using only storyboards, unfortunately.
Create an instance variable for the activity indicator:
#implementation
{
UIActivityIndicatorView *activityIndicator;
}
...
In your viewDidLoad method, instantiate it and add it to the navigation bar:
activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
The property hidesWhenStopped is YES by default, so it will hide when it's not animating automatically. All you have to do is call startAnimating and stopAnimating when you want it to be visible or hidden, respectively.
Try this:
UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
self.navigationController.navigationItem.leftBarButtonItem = button;
I'm following the CoreDataRecipes app for modaly showing the add screen when I want to add a new item. However I cannot get the bar to display at the top so I can press 'Done' or 'Cancel'.
In the xib calling the modal controller I have the + button linked to modally sliding up the controller via IB.
I have the below in my modal controller
self.navigationItem.title = #"Add";
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(cancel)];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStyleDone target:self action:#selector(save)];
self.navigationController.navigationBarHidden = NO;
In my viewDidLoad
The modal controller displays fine except there is no bar so I cannot leave that screen.
You need to add it before the popover is actually presented.
Where you create the modal popover, you need to create it inside a UINavigationController first.
So, do the following.
PopoverView *foo = [[PopoverView alloc] initWithNibName:#"PopoverView" bundle:nil];
// Here you pass through properties if you need too.
// ...
UINavigationController *navC = [[UINavigationController alloc] initWithRootView:foo];
[foo release];
[self.navigationController presentModalViewController:navC animated:YES];
That will give the modal view the navigation bar which you're trying to edit.
Alternatively, you could maintain your storyboard segue. In Xcode, select the view controller you are trying to transition to and embed it in a navigation controller.
Now in the viewDidLoad of that view controller, add:
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(cancel)];
and lastly the callback:
- (void)cancel {
[self dismissModalViewControllerAnimated:YES];
}
Or if you just need the look of the bar, not exactly its functionality, you could drag the Navigation Bar (UINavigationBar) or Toolbar (UIToolbar) controll from the Media Library panel onto your view and go from there.
I had a similar predicament whereby I was loading a UITableViewController in a containerView. The containerView was inside a UIViewController which was being presented in a modal fashion.
I, like you, needed the navigation bar to have a title and a Done/Cancel button.
After overflowing the stack, I finally did this -
Dragged a UIView as the first item in the Table View in the IB. This automatically took a height of 44 pts and snapped to the top. It also shifted my first section downwards.
I dragged a UIButton (Done button) inside this view. Created an IBOutlet to it and called
[self dismissViewControllerAnimated:YES completion:nil];
Disclaimer:
1) This fake nav-bar will scroll along with the tableview.
2) This might not be a solution for what Bot has asked, but it's an option for others who might be looking for something similar.
I am trying to recreate the iPhone's tabView, but with my own style, buttons, etc. I didn't want to have to totally redo my app, so I simply added a view to the bottom like this [window addSubview:theToolbar]; theToolbar.frame = CGRectMake(0, 425, 320, 44); in my appDelegate.
However, when trying to do this from a view inside a navigationController theToolbar is over it. Is there anyway to somehow present it to the front?
Here's my code to present the view:
AppSettingsController *appSettings = [[AppSettingsController alloc] initWithNibName:nil bundle:nil];
appSettings.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:appSettings animated:YES];
[appSettings release];
Thanks.
it's impossible show partial views of the viewcontroller. if your want to use the same toolbar, you should retain the toolbar to your appdelegate, and add the toolbar to each viewcontroller when it is in view.
or you should just use uiview's as viewcontrollers