How do I draw "save" & "cancel" buttons on the navigation bar when the user taps "edit"? Also, how do I hide the delete "knobs" and instead make each row editable, like Apple's Contacts app?
An UIViewController has a -setEditing:animated: method that you can overwrite. In this method you could call -setRightBarButtonItem or -setLeftBarButtonItem.
As for your second question, take a look at the UITableViewDataSource. There's a method called -tableView:moveRowAtIndexPath:toIndexPath.
EDIT: If you want to enter text in a UITableViewCell, you have to place a UITextField inside it in your -tableView:cellForRowAtIndexPath:. Look here.
To create a Cancel button on the left side, implement the setEditing:animated: method and put the following inside.
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelEdit:)] autorelease];
And to add a Save button:
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:#selector(SaveEdit:)] autorelease];
Make sure you implement cancelEdit: and saveEdit:.
To both answers, I should add the following:
To remove added button, set the right/leftBarButtonItem to nil
Related
How to set an IBAction for the edit button in the NavigationBar created using the following code
self.navigationItem.leftBarButtonItem = [self editButtonItem];
Since you are assigning the left bar button programmatically, you must create the button yourself. When you instantiating the button, you can also set the callback action something like this:
UIBarButtonItem *editButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemEdit
target:self
action:#selector(editButtonPressed:)];
self.navigationItem.leftBarButtonItem = editButton;
When the edit button is pressed, the following method will be called
- (void)editButtonPressed:(id)sender
{
// do something
}
Since you are already working in code, rather than Interface Builder, it's probably easier to assign a selector programmatically as well:
[self.navigationItem.leftBarButtonItem setAction:#selector(doSomething:)];
I want to make a done button appear UINavigationBar when any row in my UITableView is selected and I want this button to perform an action performSegueWithIdentifier.
Any ideas on how to implement it?
Add the following to your tableView:didSelectRowAtIndexPath: method:
//add done button to navigation bar
UIBarButtonItem *doneBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(userPressedDone)];
self.navigationItem.rightBarButtonItem = doneBarButtonItem;
Then have a method like this somewhere in your view controller:
-(void)userPressedDone {
//perform segue
[self performSegueWithIdentifier:#"mySegue" sender:nil];
}
I would imagine that in your -didSelectRowAtIndexPath: method you would add a UIBarButtonItem to the right or left bar button item of the navigationItem of your view controller.
I have UItable with items. I have navigation bar etc. On one item in table "Category" I pust another UITable like this:
CategoryTableViewController *b = [[CategoryTableViewController alloc]init];
[self.navigationController pushViewController:b animated:YES];
[b release];
Now I want to add "ADD" button in navigation bar and I add UINavigationBarItem in *.xib connect it to outlets and add it like this in viewDidLoad:
self.navigationItem.rightBarButtonItem = self.addButton;
And this does not work (addButton is null), but when I put the same code for adding button in my first UITable it works fine and "ADD" button is added.
What could be the problem here?
In the ViewController that should show the button in the navigation bar type in the viewDidLoad() method:
self.addToolbarButton = [[[UIBarButtonItem alloc]
initWithTitle:#"Add", nil)
style:UIBarButtonSystemItemAdd
target:self
action:#selector (add)] autorelease];
self.navigationItem.leftBarButtonItem = addToolbarButton;
That will add a "add" styled button to the left in the navigation bar which calls the selector method:
-(void) add {...}
in the same class when it is tapped. In this method in the same class you can specify your add logic. If this method should be placed in a different class, set the target to that.
That is the programatical way to solve this. The method "-(void) add" is what your Outlet has been in the .xib approach.
For your .xib approach you should verify that the Outlet property for the navigationBarButton is set to retain.
self.addButton is NULL, thus make sure its not NULL. Create a button from code.
UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneMeasuring:)];
is [super viewDidLoad]; the first call in your viewDidLoad method?
If not try to put it at the very beginning of viewDidLoad.
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;
I want to have the default shape of the back button, but that makes my program enter a loop at some point.
The code is this for modifying the text of the back button, written before the initialization of the view.
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle: #"Back" style: UIBarButtonItemStyleBordered target: nil action: nil];
[[self navigationItem] setBackBarButtonItem: newBackButton];
[newBackButton release];
can I also change the target to another view? I really need that default shape and I don't know how else to get it. Thanks!
The UINavigationController does not work that way, you'll need to make a custom UIBarButton with an image.
If you want to customize the right-button in the navigation controller you usually set the backBarButtonItem on the parent view controller, i.e. the one you are going back to.
parentViewController.navigationItem.backBarButtonItem =
[[[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:nil action:nil] autorelease];
There is a solution to modify the target of the back button on this blog. The key idea is to subclass UINavigationController and override the popViewControllerAnimated: method. First paste in your custom code and then call [super popViewControllerAnimated:animated] at the end.
I have verified that this still works fine in SDK 4.3.