How to show/hide search bar with same toolbar button - ios

I have a toolbar button
UIBarButtonItem *systemItem2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:#selector(pressButton2:)];
systemItem2.style = UIBarButtonItemStyleBordered;
and a press action
- (void) pressButton2:(id)sender{
mapSearch.hidden = NO;
}
in viewWillAppear
- (void)viewWillAppear:(BOOL)animated
{
mapSearch.hidden = YES;
}
How can I show and hide searchbar with same button (second press)?

I understand you would like to toggle the mapSearch.hidden. Here is a solution
mapSearch.hidden = !mapSearch.hidden;
or
mapSearch.hidden = (mapSearch.hidden) ? NO : YES;

Related

Change items in navigation bar on device rotation

I have custom UIBarButton items added to UINavigationBar as rightbarbuttonitems. I add two more items in UIBarButton when device goes to landscape mode. I am getting rotation call and I am correctly removing items from UIBarbuttons array based on device orientation, but my navigationbar item set never gets updates.
If i start with portrait mode, it shows what it suppose to. When I rotate to landscape new items are not added to navigation bar and vice versa extra item won't go when device go to portrait.
I am not sure how I can change navigationbaritems on device rotation. Per me I am doing all things correct.
-(void)setUpOnRotation:(BOOL)toPortrait{
_searchMessage = [[UILabel alloc] initWithFrame:CGRectMake(3.0, 0, 110, 20)];
_searchMessage.numberOfLines = 2;
_searchMessage.textColor = [UIColor blackColor];
_searchMessage.font = [UIFont systemFontOfSize:8.0];
_searchMessage.text = #"";
_searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 15, 130, 25)];
_searchBar.delegate = self;
_searchBar.showsCancelButton = NO;
UIBarButtonItem* doneButton = [BarButtons doneButtonWithTarget:self action:#selector(cancel)];
UIBarButtonItem *searchActivityItem = [[UIBarButtonItem alloc] initWithCustomView:_searchMessage];
UIBarButtonItem *searchItem = [[UIBarButtonItem alloc] initWithCustomView:_searchBar];
UIBarButtonItem *in = [BarButtons nativeButtonNamed:#"In"
title:#"In"
target:self
action:#selector(In)];
UIBarButtonItem *out = [BarButtons nativeButtonNamed:#"Out"
title:#"Out"
target:self
action:#selector(Out)];
NSMutableArray *itemsSet;
itemsSet = [NSMutableArray arrayWithObjects:in,
out,
searchItem,
searchActivityItem,
doneButton, nil];
if (toPortrait) {
if ([itemsSet containsObject:searchItem] || [itemsSet containsObject:searchActivityItem]) {
[itemsSet removeObject:searchActivityItem];
[itemsSet removeObject:searchItem];
}
}
[_searchBar release];
[searchItem release];
[_searchActivity release];
[_searchMessage release];
[searchActivityView release];
self.navigationItem.rightBarButtonItems = itemsSet;
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self setUpOnRotation:UIInterfaceOrientationIsPortrait(toInterfaceOrientation)];
} -(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];
[self setUpOnRotation:UIInterfaceOrientationIsPortrait(self.interfaceOrientation)];}
Note: setUpOnRotaion method is called from willAnimateRotationToInterfaceOrientation and viewWillAppear with UIInterfaceOrientationIsPortrait(self.intefaceOrientation) and it does give me correct result. I have debugged.
In willAnimateRotationToInterfaceOrientation change cehck for orientation
if([uidevice orientaiton]statusbarorientation]){
self.naviogationite.rightbarbuttonitems = #[btn1,btn2,btn3];
}
else{
self.naviogationite.rightbarbuttonitems = #[abtn1,abtn2,abnt3];
}
u can do like this
can u do like this
NSMutableArray *itemsSet;
if(!toPortrait){
itemsSet = [NSMutableArray arrayWithObjects:in,
out,
searchItem,
searchActivityItem,
doneButton, nil];
}
if (toPortrait) {
itemsSet = [NSMutableArray arrayWithObjects:in,
out,
doneButton, nil];
}

Configure "Done" button for multiple picker views

I have a scene in which I want to use picker views to get the input for multiple text boxes. I want each picker view to have a toolbar with a "Done" button that dismisses the picker view. So far I have:
//toolbar with "Done" button for picker views
UIToolbar *pickerToolBar= [[UIToolbar alloc] initWithFrame:CGRectMake(0,0,320,44)];
[pickerToolBar setBarStyle:UIBarStyleBlackOpaque];
UIBarButtonItem *barButtonDone = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(doneWithPicker:)];
pickerToolBar.items = [[NSArray alloc] initWithObjects:barButtonDone,nil];
barButtonDone.tintColor=[UIColor blackColor];
//set up picker views
_pickerOne = [[UIPickerView alloc] init];
_pickerOne.dataSource = self;
_pickerOne.delegate = self;
self.textFieldOne.inputView = self.pickerOne;
self.textFieldOne.inputAccessoryView = pickerToolBar;
What I need is some way for the doneWithPicker method to figure out which text field is currently being edited and call resignFirstResponder.
Use the text field delegate to identify which field is active. (Make sure to set yourself up as the delegate)
#implementation WhateverViewController
{
UITextField *activeTextField;
}
...
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
activeTextField = textField;
}
Then, in the method that is called when your done button is tapped:
[activeTextField resignFirstResponder];

How to add button to navigation bar

adding a button to navigation bar on first nib viewController and wanted to view this button to only on main screen not on any other screen
i have worked out on it
i made the button and added to subview of navigation bar
on every button action i have put this
- (IBAction)forth:(id)sender {
forthView *forthview = [[forthView alloc]init];
[self.navigationController pushViewController:forthview animated:YES];
btn.hidden = YES;
}
after this button hides but didnot show up when i got back to main screen
my code for viewdidload is here
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.title = #"My First View";
self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
btn = [[UIButton alloc] init];
btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(10, 10, 65, 30);
[btn setTitle:#"Show" forState:UIControlStateNormal];
[self.navigationController.navigationBar addSubview:btn];
btn.hidden = false;
}
Once you hide the button so you need to unhide it again. here is the simple code to unhide the button:
btn.hidden = No
viewDidLoadis only called the first time your view is loaded. Add an NSLog()statement if you want to test when it gets called. Every time your view appers on screen viewWillAppearis called.
So you need to show the button in viewWillAppear
It seems likely that what you really want to be doing is adding a UIBarButtonItem to your main view controller's navigationItem.leftBarButtonItem property. That way the button will have the correct appearance and show and hide as the view controller is displayed.
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Show"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(onShowButtonPressed:)];

How can I enable/disable a UITextField's inputAccessoryView buttons?

I've created a UIToolBar as an inputAccessoryView with a next and previous buttons that will cycle through the textFields in my view controller.
I've created a category on UITextField based on the third SO answer on this page which adds a property to the textField that points to the next/previous textField.
I can get it to cycle through the textFields both forward and backward, but only once, and then my buttons are permanently disabled. Also, when the last textField is in focus, I still need to tap the next button one extra time (4 taps for 3 textFields) to have it disable the next button — same with the previous button, I have to tap back once when I'm in the first textField.
// ViewController.h
#interface DetailViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate, UIPopoverControllerDelegate> {
__weak IBOutlet UITextField *valueField;
__weak IBOutlet UITextField *nameField;
__weak IBOutlet UITextField *serialNumberField;
}
#property (nonatomic, strong) UITextField *currentTextField;
- (IBAction)nextTextField:(id)sender;
- (IBAction)prevTextField:(id)sender;
// ViewController.m
- (void)viewDidLoad {
//...
nameField.delegate = self;
nameField.nextTextField = serialNumberField;
nameField.prevTextField = nil;
serialNumberField.delegate = self;
serialNumberField.nextTextField = valueField;
serialNumberField.prevTextField = nameField;
valueField.delegate = self;
valueField.prevTextField = serialNumberField;
valueField.nextTextField = nil;
//...
}
- (void)viewWillAppear:(BOOL)animated {
//UIToolBar for inputAccessoryView
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
UIBarButtonItem *nextField = [[UIBarButtonItem alloc] initWithTitle:#"\U00003009"
style:UIBarButtonItemStylePlain
target:self
action:#selector(nextTextField:)];
UIBarButtonItem *prevField = [[UIBarButtonItem alloc] initWithTitle:#"\U00003008"
style:UIBarButtonItemStylePlain
target:self
action:#selector(prevTextField:)];
UIBarButtonItem *space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *done = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(backgroundTapped:)];
NSArray *toolBarButtons = #[prevField, nextField, space, done];
toolBar.items = toolBarButtons;
nameField.inputAccessoryView = toolBar;
valueField.inputAccessoryView = toolBar;
serialNumberField.inputAccessoryView = toolBar;
}
- (IBAction)nextTextField:(id)sender {
UITextField *next = self.currentTextField.nextTextField;
if (!next) {
[sender setEnabled:NO];
} else {
[sender setEnabled:YES];
[next becomeFirstResponder];
}
}
- (IBAction)prevTextField:(id)sender {
UITextField *prev = self.currentTextField.prevTextField;
if (!prev) {
[sender setEnabled:NO];
} else {
[sender setEnabled:YES];
[prev becomeFirstResponder];
}
}
I think part of the problem is that you are handling the enabling/disabling of the bar buttons in a method that is only called once one of the bar buttons has been tapped. It would be better to set the barbuttonitems as properties of your view controller (so you can enable/disable them when you want to), and then handle the enabling/disabling of the bar button items within the UITextField's 'textFieldShouldBeginEditing' delegate method.
So, something like this:
- (void)viewWillAppear:(BOOL)animated {
//UIToolBar for inputAccessoryView
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
self.moveToNextFieldButton = [[UIBarButtonItem alloc] initWithTitle:#"\U00003009"
style:UIBarButtonItemStylePlain
target:self
action:#selector(nextTextField:)];
self.moveToPrevFieldButton = [[UIBarButtonItem alloc] initWithTitle:#"\U00003008"
style:UIBarButtonItemStylePlain
target:self
action:#selector(prevTextField:)];
UIBarButtonItem *space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *done = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(backgroundTapped:)];
NSArray *toolBarButtons = #[self.moveToPrevFieldButton, self.moveToNextFieldButton, space, done];
toolBar.items = toolBarButtons;
nameField.inputAccessoryView = toolBar;
valueField.inputAccessoryView = toolBar;
serialNumberField.inputAccessoryView = toolBar;
}
-(BOOL)textFieldShouldBeginEditing:(UITextField*)textField{
UITextField *next = textField.nextTextField;
UITextField *prev = textField.prevTextField;
self.moveToNextFieldButton.enabled = next != nil;
self.moveToPrevFieldButton.enabled = prev != nil;
return YES;
}
- (IBAction)nextTextField:(id)sender {
UITextField *next = self.currentTextField.nextTextField;
if (next) {
[next becomeFirstResponder];
}
}
- (IBAction)prevTextField:(id)sender {
UITextField *prev = self.currentTextField.prevTextField;
if (prev) {
[prev becomeFirstResponder];
}
}

UIBarButtonItem changing title not working

How can I change the title of a UIBarButtonItem? I have the following code which is called when an edit button is pressed on my UINavigationBar.
-(void)editButtonSelected:(id)sender {
NSLog(#"edit button selected!");
if(editing) {
NSLog(#"notediting");
[super setEditing:NO animated:NO];
[tableView setEditing:NO animated:NO];
[tableView reloadData];
[rightButtonItem setTitle:#"Edit"];
[rightButtonItem setStyle:UIBarButtonItemStylePlain];
editing = false;
}
else {
NSLog(#"editing");
[super setEditing:YES animated:YES];
[tableView setEditing:YES animated:YES];
[tableView reloadData];
[rightButtonItem setTitle:#"Done"];
[rightButtonItem setStyle:UIBarButtonItemStyleDone];
editing = true;
}
}
The edit button is changing color (so the line which sets the style is working), however the line which sets the title of the button is not working.
I've done the following to dynamically change the title of a UIBarButtonItem. In this situation I am not using a UIViewTableController and cannot use the standard editButton. I have a view with a tableView as well as other subviews and wanted to emulate the behavior of the limited UIViewTableController.
- (void)InitializeNavigationItem
{
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:2];
UIBarButtonItem* barButton;
barButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(addNewItem:)];
barButton.style = UIBarButtonItemStyleBordered;
[array addObject:barButton];
// --------------------------------------------------------------------------------------
barButton = [[UIBarButtonItem alloc] initWithTitle:#"Edit" style:UIBarButtonItemStyleBordered
target:self
action:#selector(editMode:)];
barButton.style = UIBarButtonItemStyleBordered;
barButton.possibleTitles = [NSSet setWithObjects:#"Edit", #"Done", nil];
[array addObject:barButton];
self.navigationItem.rightBarButtonItems = array;
}
- (IBAction)editMode:(UIBarButtonItem *)sender
{
if (self.orderTable.editing)
{
sender.title = #"Edit";
[self.orderTable setEditing:NO animated:YES];
}
else
{
sender.title = #"Done";
[self.orderTable setEditing:YES animated:YES];
}
}
Note that I didn't use the the UIBarButtonSystemItemEdit barButton, you cannot manually change the name of that button, which makes sense.
You also might want to take advantage of the possibleTitles property so that the button doesn't resize when you change the title.
If you are using a Storyboard/XIB to create/set these buttons, ensure that the Bar Button Item Identifier is set to Custom for the button which you'd want to control the title for.
I had this problem and resolved it by setting the UIBarButtonItem style to the custom type when it's initialised. Then the titles would set when changing their title values.
You may also want to set the possibleTitle value in the viewDidLoad method to ensure the button is sized correctly for all the possible titles it can have.
In my case what prevented the title being displayed was that in the xib I'd selected the Bar button item 'identifier' property as 'Cancel'.
I tried setting the title property even before assigning the button to the navigation bar, but the title was not being updated.
I made it like this:
And it started working just as I wanted.
If you look at the documentation of the title property, it is explicitly mentioned that you should set it before assigning it to the navigation bar. Instead of doing what you're doing right now, you can use two bar button items – one for done and one for edit, and set them alternatively.
Actually if all you want if switching between "Edit" and "Done", just use
self.navigationItem.rightBarButtonItem = self.editButtonItem;
It will handle this transition for you
Just switch out the buttons each time the user presses them.
- (void)setNavigationButtonAsEdit
{
UIBarButtonItem* editButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Edit", #"")
style:UIBarButtonItemStylePlain
target:self
action:#selector(editButtonPressed:)];
self.navigationItem.rightBarButtonItems = [NSArray arrayWithObject:editButton];
}
- (void)setNavigationButtonAsDone
{
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Done", #"")
style:UIBarButtonItemStylePlain
target:self
action:#selector(editButtonPressed:)];
self.navigationItem.rightBarButtonItems = [NSArray arrayWithObject:doneButton];
}
And then create an IBAction to handle the button press:
- (IBAction)editButtonPressed:(id)sender
{
NSString* buttonText = [sender title];
if ([buttonText isEqualToString:NSLocalizedString(#"Edit",#"")])
{
[self setNavigationButtonAsDone];
}
else
{
[self setNavigationButtonAsEdit];
}
}
Swift 3.0, 3.2, or 4.0
If your custom ViewController containing a tableView object follows the UITableViewController Delegate and Datasource protocols, you can append a system editBarButtonItem to your navigationItem.leftBarButtonItem(s) or navigationItem.rightBarButtonItem(s) with the following code:
func setupTableView() {
tableView.delegate = self
tableView.dataSource = self
navigationItem.rightBarButtonItem = editButtonItem
editButtonItem.action = #selector(CustomViewController.editTableView(_:))
}
#objc func editTableView(_ sender: UIBarButtonItem) {
tableView.isEditing = !tableView.isEditing
if tableView.isEditing {
sender.title = "Done"
} else {
sender.title = "Edit"
}
}
Try:
UIButton *rightButton;
rightButton = (UIButton*)self.navigationItem.rightBarButtonItem.customView;
[rightButton setTitle:#"Done" forState:UIControlStateNormal];
Because rightBarButtonItem.customView == “the button your added”.

Resources