In my Project I have two UITextFields, one is used for Postal Code another one is used for Phone Number , so I used the Keyboard in NumberPad, Here I used the UIToolbar for both UITextFields for hide values, but my problem is TextField is does not identify the correct Tags in custom Methods for hide the textfields. How to resolve this issue
and my code is
- (void)viewDidLoad
{
[super viewDidLoad];
numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
numberToolbar.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(cancelNumberPad:)],
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(doneWithNumberPad:)],
nil];
}
- (IBAction)cancelNumberPad:(UITextField*)textField {
NSLog(#"The user is typing in text field %d",textField.tag);
if (textField.tag==50) {
[txtPostalCode resignFirstResponder];
txtPostalCode.text=#"";
}
else
{
[txtphoneno resignFirstResponder];
txtphoneno.text = #"";
}
}
- (IBAction)doneWithNumberPad:(UITextField*)textField {
NSLog(#"The user is typing in text field %d",textField.tag);
if (textField==txtPostalCode) {
[txtPostalCode resignFirstResponder];
}
else
{
[txtphoneno resignFirstResponder];
}
}
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
if (textField.tag==50) {
textField.inputAccessoryView = numberToolbar;
}
else if
(textField.tag==5) {
textField.inputAccessoryView = numberToolbar;
}
}
in my console report is
2014-05-03 14:06:23.614 why-Q[2000:60b] The user is typing in text field 0
how to get the correct tag in custom methods
//yourviewcontroller.h
#interface ViewController : UIViewController {
int tag;
}
//yourviewcontroller.m
- (void)viewDidLoad {
[super viewDidLoad];
tag = 0;
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField// return NO to disallow editing.
{
tag = textField.tag;
return YES;
}
- (IBAction)cancelNumberPad:(UITextField*)textField {
NSLog(#"The user is typing in text field %d",tag);
}
- (IBAction)doneWithNumberPad:(UITextField*)textField {
NSLog(#"The user is typing in text field %d",tag);
}
Related
On the right is picker view toolbar button 'Next' and want to call textFieldShouldReturn method on its action via #selector. But it gives me error Undeclared Selector.
This is button's code,
UIBarButtonItem *nextBtn = [[UIBarButtonItem alloc] initWithTitle:#"Next" style:UIBarButtonItemStylePlain target:self action:#selector("textFieldShouldReturn here")];
And this is my textFieldShouldReturn method,
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
self.addScrollView.contentSize = CGSizeMake(320, 1800);
[self.addScrollView setContentOffset:CGPointMake(0, 0 ) animated:NO];
if (textField == industryTxtField) {
[subIndustryTxtField becomeFirstResponder];
}
else if (textField == subIndustryTxtField) {
[address1TxtField becomeFirstResponder];
}
ScreenShot
Try like this ...
UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:#"Next" style:UIBarButtonItemStylePlain target:self action:#selector(moveToNextField)];
-(void)moveToNextField
{
if (industryTxtField.isFirstResponder)
{
[subIndustryTxtField becomeFirstResponder];
}
else if (subIndustryTxtField.isFirstResponder)
{
[address1TxtField becomeFirstResponder];
}
}
I have searched the entire internet and tried different ways to implement UITextFieldShouldReturn, but when I run it in the simulator it just doesn't work.
What I'm trying to do is move from the first textfield(emailTextField) to the second one( nameTextField ) when user clicks next button on the keyboard. The same for the second textfield's keyboard and dismiss the keyboard when user clicks done button on the last textfield( numberTextField ).
Here is my code, can anyone help me with this?
#import "ViewController.h"
#interface ViewController () <UITextFieldDelegate>
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.emailTextField.placeholder = #"Your Pitt Email(optional)";
self.nameTextField.placeholder = #"Lost ID Name";
self.numberTextField.placeholder = #"Lost ID Series Number(optional)";
[self.emailTextField.delegate self];
[self.nameTextField.delegate self];
[self.numberTextField.delegate self];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//release delegate
-(void)dealloc{
self.emailTextField.delegate = nil;
self.nameTextField.delegate = nil;
self.numberTextField.delegate = nil;
}
//dismiss keyboard when it's called
-(void)dismissKeyboard{
[self.emailTextField resignFirstResponder];
[self.nameTextField resignFirstResponder];
[self.numberTextField resignFirstResponder];
}
//when a textfield begins editing, this will happen
-(void)textFieldDidBeginEditing:(UITextField *)textField{
if(textField == self.emailTextField){
textField.placeholder = #"";
}else if(textField == self.nameTextField){
textField.placeholder = #"";
}else{
textField.placeholder = #"";
}
}
//when a textfield ends editing, this will happen
-(void)textFieldDidEndEditing:(UITextField *)textField{
if(textField == self.emailTextField){
textField.placeholder = #"Your Pitt Email(optional)";
[self textFieldShouldReturn:self.emailTextField];
}else if(textField == self.nameTextField){
textField.placeholder = #"Lost ID Name";
[self textFieldShouldReturn:self.nameTextField];
}else{
textField.placeholder = #"Lost ID Series Number(Optional)";
[self textFieldShouldReturn:self.numberTextField];
}
}
//return button set up
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
//when confirm is pressed
- (IBAction)confirmButton:(id)sender {
[self dismissKeyboard];
}
#end`
Change
[self.emailTextField.delegate self];
to
self.emailTextField.delegate = self;
Also remove those delegates from dealloc. You can put them from viewDidDisappear
Try this code snippet. Here i am taking only two
UITextFields.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField==_txtEmail)
{
[_txtEmail resignFirstResponder];
[_txtPassword becomeFirstResponder];
}
else if (textField==_txtPassword)
{
[_txtPassword resignFirstResponder];
}
return YES;
}
This function is enough to return keyboard from text fields.
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
Your these 3 lines are not working.
[self.emailTextField.delegate self];
[self.nameTextField.delegate self];
[self.numberTextField.delegate self];
If you are using storyboard, connect delegates of the text fields with the view.
You can use this code.It is working for me..
-(void)tool{
UIToolbar *toolbar = [[UIToolbar alloc] init];
[toolbar setBarStyle:UIBarStyleBlackTranslucent];
[toolbar sizeToFit];
UIBarButtonItem *flexButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneButton =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(resignKeyboard)];
[doneButton setTintColor:[UIColor whiteColor]];
UIBarButtonItem *Next = [[UIBarButtonItem alloc]initWithTitle:#"Next" style:UIBarButtonItemStylePlain target:self action:#selector(Nextbutton)];
[Next setTintColor:[UIColor whiteColor]];
NSArray *itemsArray = [NSArray arrayWithObjects:Next,flexButton,doneButton,nil];
[toolbar setItems:itemsArray];
[FirstNameTextField setInputAccessoryView:toolbar];
[LastNameTextfield setInputAccessoryView:toolbar];
[EmailAddressTextField setInputAccessoryView:toolbar];
[PasswordTextfield setInputAccessoryView:toolbar];
[ConfirmPasswordTextfield setInputAccessoryView:toolbar];}
-(void)Nextbutton{
if ([FirstNameTextField isFirstResponder])
{
[LastNameTextfield becomeFirstResponder];
}
else if ([LastNameTextfield isFirstResponder])
{
[EmailAddressTextField becomeFirstResponder];
}
else if ([EmailAddressTextField isFirstResponder])
{
[PasswordTextfield becomeFirstResponder];
}
else if ([PasswordTextfield isFirstResponder])
{
[ConfirmPasswordTextfield becomeFirstResponder];
}
else if ([ConfirmPasswordTextfield isFirstResponder])
{
[ConfirmPasswordTextfield resignFirstResponder];
}}
-(void)resignKeyboard{
[FirstNameTextField resignFirstResponder];
[EmailAddressTextField resignFirstResponder];
[LastNameTextfield resignFirstResponder];
[PasswordTextfield resignFirstResponder];
[ConfirmPasswordTextfield resignFirstResponder];}
First of all you need to set the delegate right. Then You need to give your next textfield the becomeNextResponder call which should be ideally done in the shouldReturn delegate method.
In your viewDidLoad method, paste this.
self.emailTextField.tag = 2000;
self.nameTextField.tag = 3000;
self.numberTextField.tag = 4000;
Now edit your textFieldShouldReturn method like this:
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
if(textfield.tag<4000)
{
UITextField *nextTextField = (UITextField *)[self.view viewWithTag:textField.tag+1000];
[nextTextField becomeFirstResponder];
}
return YES;
}
you can always use a library to accomplish what you need to do !!
use this library : tpAvoidKeyboard
Read how to use it and there you go all the next buttons and clicks outside text fields to dismiss the keyboard and the the done button on the last textfield to dismiss the keyboard, all those features are already implemented
i have this set up in my app
im trying to change between the textfield with the uibarbutton but it aint working
i have this code
-(void)setToolBar {
UIToolbar* Toolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
Toolbar.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:#"backwardIcon"] style:UIBarButtonItemStylePlain target:self action:#selector(prevTextField)],
[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:#"forwardIcon"] style:UIBarButtonItemStylePlain target:self action:#selector(nextTextField)], nil];
[Toolbar sizeToFit];
self.txtNombre.inputAccessoryView = Toolbar;
self.txtAM.inputAccessoryView = Toolbar;
self.txtAP.inputAccessoryView = Toolbar;
self.txtEmail.inputAccessoryView = Toolbar;
self.txtPass.inputAccessoryView = Toolbar;
}
-(void)nextTextField {
if(self.txtNombre){
[self.txtNombre resignFirstResponder];
[self.txtAP becomeFirstResponder];
}else if(self.txtAP){
[self.txtAP resignFirstResponder];
[self.txtAM becomeFirstResponder];
}else if(self.txtAM){
[self.txtAM resignFirstResponder];
[self.txtTel becomeFirstResponder];
}else if(self.txtTel){
[self.txtTel resignFirstResponder];
[self.txtEmail becomeFirstResponder];
}else if(self.txtEmail){
[self.txtEmail resignFirstResponder];
[self.txtPass becomeFirstResponder];
}else{
[self.txtPass resignFirstResponder];
}
}
-(void)prevTextField{
if(self.txtAP){
[self.txtNombre becomeFirstResponder];
[self.txtAP resignFirstResponder];
}else if(self.txtAM){
[self.txtAP becomeFirstResponder];
[self.txtAM resignFirstResponder];
}else if(self.txtTel){
[self.txtAM becomeFirstResponder];
[self.txtTel resignFirstResponder];
}else if(self.txtEmail){
[self.txtTel becomeFirstResponder];
[self.txtEmail resignFirstResponder];
}else if(self.txtPass){
[self.txtEmail becomeFirstResponder];
[self.txtPass resignFirstResponder];
}
}
any ideas on what am i doing wrong since it just changes between the first two text fields
Instead of checking:
if(self.txtNombre)
you should be checking
if([self.txtNombre isFirstResponder])
For all textfields of course.
That is checking that your UITextField is currently being edited.
Also I would suggest, to make an NSArray from those UITextFields to make those methods looking nicer. Right now if you want to add more textfield, you need to copy paste a lot and rename properties - also easy to make mistake with that.
I wanna show a picker when I click inside a UITextField. This is my code (which works):
[super viewDidLoad];
// Picker View dei Tipi
pickerTipo= [[UIPickerView alloc] init];
pickerTipo.showsSelectionIndicator = YES;
UIToolbar* keyboardDoneButtonView = [[UIToolbar alloc] init];
[keyboardDoneButtonView sizeToFit];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc]
initWithTitle:
#"Fine" style:UIBarButtonItemStyleBordered
target:self
action:#selector(pickerDoneClicked:)];
[keyboardDoneButtonView setItems:[NSArray arrayWithObjects:doneButton, nil]];
self.textTipo.inputAccessoryView = keyboardDoneButtonView;
[self.textTipo resignFirstResponder];
self.textTipo.inputView = pickerTipo;
self.textTipo.delegate = self;
The picker and the accessory view show correctly. The problem is that the UITextField is still editable, that is I can still typing inside the UITextField. I would that when the picker is shown, no editing is enabled inside the UITextField.
[SOLVED}
Following the accepted answer, the right code is :
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == self.textTipo || textField == self.textStato)
return NO;
else
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if([textField.restorationIdentifier isEqualToString:#"textFieldIdentifier"])
{
return NO;
}
}
Hope it helps.
Instead of textfied you can use button with a background uiimage view of text field.
try this code:
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField;
{
if(textField==self.textTipo)
{
return NO;
}
else
{
return YES;
}
}
make your textfield a readonly property
I'm using the following code to move to the next field using the UITextField delegate and also I'm adding a toolbar to the keyboard with the previous, next and ok buttons. The code is working fine.
Like you see the keyboard return button logic is pretty generic, using the UITextField tags, and that's good because I'm gonna use the piece of code all around. Now I will need to write the previous and next buttons logic, and I'm lost. Any ideas?
UPDATE (complete code, with some modifications, thanks to #8vius that spent some time with me in the chat to make it work):
//
// SigninViewController.m
//
#import "SigninViewController.h"
#implementation SigninViewController
#synthesize firstResponder = _firstResponder;
#synthesize toolbar;
#synthesize email;
#synthesize password;
- (void)move:(UIBarButtonItem*)sender {
NSInteger tag = self.firstResponder.tag;
if ([sender.title isEqualToString:#"Anterior"]) {
tag -= 1;
} else if ([sender.title isEqualToString:#"Próximo"]) {
tag += 1;
}
UITextField *nextTextField = (UITextField*)[self.view viewWithTag:tag];
if (nextTextField && tag > 0) {
[nextTextField becomeFirstResponder];
} else {
[self.firstResponder resignFirstResponder];
self.firstResponder = nil;
}
}
- (void)ok:(id)sender {
[self.view endEditing:YES];
self.firstResponder = nil;
}
- (void)textFieldDidBeginEditing:(UITextField*)textField {
self.firstResponder = textField;
}
- (BOOL)textFieldShouldReturn:(UITextField*)textField {
NSInteger tag = textField.tag + 1;
UITextField *nextTextField = (UITextField*)[self.view viewWithTag:tag];
if (nextTextField) {
[nextTextField becomeFirstResponder];
} else {
[textField resignFirstResponder];
self.firstResponder = nil;
}
return NO;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.email.delegate = self;
self.password.delegate = self;
if (self.toolbar == nil)
{
self.toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
UIBarButtonItem* previous = [[UIBarButtonItem alloc] initWithTitle:#"Anterior" style:UIBarButtonItemStyleBordered target:self action:#selector(move:)];
UIBarButtonItem* next = [[UIBarButtonItem alloc] initWithTitle:#"Próximo" style:UIBarButtonItemStyleBordered target:self action:#selector(move:)];
UIBarButtonItem* space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:(UIBarButtonSystemItemFlexibleSpace) target:nil action:nil];
UIBarButtonItem* ok = [[UIBarButtonItem alloc] initWithTitle:#"Ok" style:UIBarButtonItemStyleBordered target:self action:#selector(ok:)];
[self.toolbar setItems:[[NSArray alloc] initWithObjects:previous, next, space, ok, nil]];
[self.toolbar setTranslucent:YES];
[self.toolbar setTintColor:[UIColor blackColor]];
}
for (UIView* view in self.view.subviews) {
if ([view isKindOfClass:[UITextField class]]) {
[(UITextField*)view setInputAccessoryView:toolbar];
}
}
}
- (void)viewDidUnload {
self.email = nil;
self.password = nil;
[super viewDidUnload];
}
#end
It's quite simple, when you load your view you set the tag property on your text fields depending on the order you want them in, then you have to just traverse the tag element on the fields:
- (void)toggleTextfield:(UIBarButtonItem *)sender {
NSInteger nextTag = self.firstResponder.tag;
if ([sender.title isEqualToString:#"Previous"] && nextTag > 1) {
nextTag -= 1
} else if ([sender.title isEqualToString:#"Next"]) {
nextTag += 1;
}
UITextField *nextTextField = (UITextField *)[self.view viewWithTag:nextTag];
if (nextTextField) {
[nextTextField becomeFirstResponder];
}
}
And keep track of who is the first responder:
-(void)textFieldDidBeginEditing:(UITextField *)textField {
self.firstResponder = textField;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
self.firstResponder = nil;
return YES;
}
And when you load your view, you bind the buttons to the toggle action:
UIBarButtonItem *previousButton = [[UIBarButtonItem alloc] initWithTitle:#"Previous"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(toggleTextfield:)];
UIBarButtonItem *nextButton = [[UIBarButtonItem alloc] initWithTitle:#"Next"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(toggleTextfield:)];
In my case, for instance, I set up my text fields inside a table view, so in my cellForRowAtIndexPath method I set the tag property to be the row of the indexPath.
EDIT: You have to set the firstResponder property for it to work.
In your .h file:
#property UIView *firstResponder
In your .m file:
#synthesize firstResponder = _firstResponder;