Go back to previous UITextfield , IOS - ios

My app has a registration view, I compare strings in password textfield and confirm password textfield , if they dont match I want user go back to password textfield
This question done it with using tags
UITextField jump to previous
Is there a way to accomplish this without using tags?
//call next textfield on each next button
- (BOOL) textFieldShouldReturn:(UITextField *) textField {
BOOL didResign = [textField resignFirstResponder];
if (!didResign) return NO;
if ([textField isKindOfClass:[SOTextField class]])
dispatch_async(dispatch_get_current_queue(),
^ { [[(SOTextField *)textField nextField] becomeFirstResponder]; });
return YES;
}
-(void)textFieldDidEndEditing:(UITextField *)textField{
if (textField==self.confirmPassword) {
if ([self.password.text isEqualToString:self.confirmPassword.text]) {
NSLog(#"password fields are equal");
}
else{
NSLog(#"password fields are not equal prompt user to enter correct values");
//[self.password becomeFirstResponder]; doesnt work
}
}
}

Without using tags, you could create an NSArray of textfield outlets the describes the desired ordering.
Declare and init like this ...
#property(nonatomic,strong) NSArray *textFields;
- (NSArray *)textFields {
if (!_textFields) {
// just made these outlets up, put your real outlets in here...
_textFields = [NSArray arrayWithObjects:self.username, self.password, nil];
}
return _textFields;
}
You'll need to fetch the text field that currently has focus, if there is one...
- (UITextField *)firstResponderTextField {
for (UITextField *textField in self.textFields) {
if ([textField isFirstResponder]) return textField;
}
return nil;
}
Then advance focus like this...
- (void)nextFocus {
UITextField *focusField = [self firstResponderTextField];
// what should we do if none of the fields have focus? nothing
if (!focusField) return;
NSInteger index = [self.textFields indexOfObject:textField];
// advance the index in a ring
index = (index == self.textFields.count-1)? 0 : index+1;
UITextField *newFocusField = [self.textFields objectAtIndex:index];
[newFocusField becomeFirstResponder];
}
And move focus backward like this...
- (void)previousFocus {
UITextField *focusField = [self firstResponderTextField];
// what should we do if none of the fields have focus? nothing
if (!focusField) return;
NSInteger index = [self.textFields indexOfObject:textField];
// backup the index in a ring
index = (index == 0)? self.textFields.count-1 : index-1;
UITextField *newFocusField = [self.textFields objectAtIndex:index];
[newFocusField becomeFirstResponder];
}

Related

Navigation using return button in apple keyboard

I have more than one text field in my view controller how can i navigate from one to another using the return button in the IOS keyboard.
Use UITextFieldDelegate delegate and the textFieldShouldReturn: method. Inside you can get the tag of the textfield passed in argument and direct to another one based on this information.
To have the delegate working you have to set delegate property of sender (textfield) to be the receiver (e.g. your view controller)
myTextField.delegate = self;
or do it in the storyboard (here is some storyboard hints). Your view controller then needs to specify this delegate as follows (in the "h" file):
#interface MyViewController:UIViewController<UITextFieldDelegate>
#end
and then in the "m" file
-(BOOL)textFieldShouldReturn:(UITextField*)textfield{
if([textfield tag] == 1)
{
//pass focus to next textfield
[self.nextTextField becomeFirstResponder];
} else {
//remove focus from current textfield
[textfield resignFirstResponder];//
}
return YES;//YES if textfield should implement its default behaviour
}
-(BOOL) textFieldShouldReturn: (UITextField *) textField
{
[textField resignFirstResponder];
if(textField == _your1stTextField)
[_your2ndTextField becomeFirstResponder];
return YES;
}
try this...
set delegates to all of your text fields and then..
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == textField1)
{
[textField2 becomeFirstResponder];
}
else if (textField == textField2)
{
[textField3 becomeFirstResponder];
}
else if textField == textField3)
{
[textField4 becomeFirstResponder];
}
.
.
.
[textField resignFirstResponder];
return YES;
}
I think this solution is more dynamic as it works for any number of textFields as long as your superview doesn't have a view with a tag == lastTextField.tag + 1
In viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
self.textField1.delegate = self;
self.textField2.delegate = self;
...
self.lastTextField.delegate = self;
self.textField1.tag = 1;
self.textField2.tag = 2;
...
self.lastTextField.tag = n;
}
Then implement the textFieldDelegate:
-(BOOL) textFieldShouldReturn:(UITextField *)textField
{
NSInteger nextTag = textField.tag + 1;
UIResponder* nextResponder = [textField.superview viewWithTag:nextTag];
if (nextResponder)
[nextResponder becomeFirstResponder];
else
[textField resignFirstResponder];
return NO;
}
You need to declare at .h
.m set
yourTextfieldRef1.delegate=self;
yourTextfieldRef2.delegate=self;
yourTextfieldRef3.delegate=self;
yourTextfieldRef4.delegate=self;
yourTextfieldRef5.delegate=self;
.
.
.
set
yourTextFieldRef1.tag=1;
yourTextFieldRef2.tag=2;
yourTextFieldRef3.tag=3;
yourTextFieldRef4.tag=4;
yourTextFieldRef5.tag=5;
.
.
.
-(BOOL)textFieldShouldReturn:(UITextField*)textField;
{
NSInteger nextTag = textField.tag + 1;
// Try to find next responder
UIResponder* nextResponder = [textField.superview viewWithTag:nextTag];
if (nextResponder) {
// Found next responder, so set it.
[nextResponder becomeFirstResponder];
} else {
// Not found, so remove keyboard.
[textField resignFirstResponder];
}
return YES;
}
Hope it helps you...!

How do I clear my UITextField's text when I tap on it again?

I have a UITextField called numberToAdd and it asks the user to enter a number to be added to 10 and a UIButton that calculates it. Then there's a UILabel that displays the sum.
Say I enter a number 5 into the UITextField and press calculate, the UILabel will show 15.
How do I write a code that will clear the UITextField when I tap on it again instead of having to delete the number 5 manually?
Firstly you should have a flag which indicate number is calculated or not, after user tapping calculate button, you should turn on that flag, then when user taps the TextField again, you can use UITextFieldDelegate detect the action and clear the textfield as below answer:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if (isCalculated) {
textField.text = #"";
isCalculated = NO;
}
}
I can think in three solutions for your problem:
Option 1
Clear the TextField everytime you touch it
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if (textField == self.numberToAdd) {
self.numberToAdd1.text = #"";
}
}
Option 2
Clear the TextField when you touch it, only if you already calculated the number.
#property (nonatomic) BOOL calculateDone;
- (void)viewDidLoad
{
[super viewDidLoad];
self.calculateDone = false;
}
- (IBAction)calculate:(id)sender {
//sum label number and textField number
int sum = [self.label.text intValue] + [self.numberToAdd.text intValue];
//set label
self.label.text = [NSString stringWithFormat:#"%d", sum];
// sum done true
self.calculateDone = true;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if (textField == self.numberToAdd)
{
if (self.calculateDone)
{
self.numberToAdd.text = #"";
self.calculateDone = false;
}
}
}
Option 3
Clear the TextField when you click calculate button
- (IBAction)calculate:(id)sender {
//sum label number and textField number
int sum = [self.label.text intValue] + [self.numberToAdd.text intValue];
//set label
self.label.text = [NSString stringWithFormat:#"%d", sum];
//reset textField
self.numberToAdd.text = #"";
}
You can also check the text entered in the TextField, because you only wants numbers in the TextField, right?.
#property (strong, nonatomic) NSString *urlRegEx;
#property (strong, nonatomic) NSPredicate *urlRegExTest;
//This Regex accepts negative and positive numbers
self.urlRegEx = #"((-)?[0-9]*)";
self.urlRegExTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", self.urlRegEx];
- (IBAction)calculate:(id)sender {
// if text is a valid Number
if ([self.urlRegExTest evaluateWithObject:self.numberToAdd.text]) {
int sum = [self.label.text intValue] + [self.numberToAdd.text intValue];
self.label.text = [NSString stringWithFormat:#"%d", sum];
}
}
You can download an example code here.
You can use UITapGestureRecognizer to get clear text on TextField.First you should use BOOL flag for know if it calculated or not let say BOOL flag is isCal.
UITapGestureRecognizer *clearTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(clearTextField:)];
[self.textView addGestureRecognizer:clearTapRecognizer];
and in clearTextField method write belove code.
- (void)clearTextField:(UITapGestureRecognizer *)gestureRecognizer
{
if(isCal)
{
UITextView *_textView = (UITextView*) gestureRecognizer.view;
_textView.text=#"";
isCal=NO;
}
}

Unable to hide the keyboard in iOS

I am trying to hide the keyboard in an iOS app. I've spent several hours looking for it, and I've tried pretty much everything, so I'm quite desperate.
My code follows as next:
RNViewController.h
#interface RNViewController : UIViewController <UITextFieldDelegate> {
UITextField *textField;
...
}
RNController.m
- (void)viewDidLoad {
textField.delegate = self;
textField.returnKeyType = UIReturnKeyDone;
}
- (BOOL)textFieldShouldReturn:(id)sender {
NSLog(#"Entering in textFieldShouldReturn ");
[textField resignFirstResponder];
return YES;
}
- (BOOL)textViewShouldReturn:(id)sender {
NSLog(#"Entering in textViewShouldReturn ");
[textField resignFirstResponder];
return YES;
}
- (IBAction)textFieldDoneEditing:(id)sender {
NSLog(#"Entering in textFieldDoneEditing ");
[sender resignFirstResponder];
}
- (IBAction)textViewDoneEditing:(id)sender {
NSLog(#"Entering in textViewDoneEditing ");
[sender resignFirstResponder];
}
- (BOOL)disablesAutomaticKeyboardDismissal {
return NO;
}
EDIT: The textField is created dinamically like this:
- (void) showPreguntaTexto: (Pregunta *) pregunta {
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(CGRectGetWidth(baseView.bounds)*0.1, offset + CGRectGetWidth(baseView.bounds)*0.05, CGRectGetWidth(baseView.bounds) - CGRectGetWidth(baseView.bounds) * 0.2 , CGRectGetWidth(baseView.bounds)*0.5)];
textField.delegate = self;
[vistaAnterior addSubview:textField];
}
My views are the baseView (with elements that do not change) and vistaAnterior, that has the content (and the textField) and changes.
Trying this, it shows that entered to textFieldShouldReturn, but the keyboard does not dissapear.
Why is this happening?? Please help!!
Resign the sender of the textfield instead of your instance. UITextField *textField is not an IBOutlet (storyboard) or created in code so textField is nil (unless you created it somewhere else and didn't show the code).
- (BOOL)textViewShouldReturn:(id)sender {
NSLog(#"Entering in textViewShouldReturn ");
[sender resignFirstResponder];
return YES;
}
have you set text fields delegate in your RNViewController from stroyboard. This might be a reason for keyboard not hiding.

How to change event of return key? [duplicate]

This question already has answers here:
How to navigate through textfields (Next / Done Buttons)
(35 answers)
Closed 9 years ago.
i have 4 text fields , i want to parform following actions by clicking on return key -
1- when i enter entry in one field and press return key , curser should be jumped on next
TextField .
Thanks .
Implement UITextField delegate and set tag value to all your textField in series. like 1,2,3..as so on. then, make sure scrollView and textField tag values should not conflict.
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
int nextTextFieldTag = textField.tag+1;
UITextField *textFieldd = (UITextField*)[self.view viewWithTag:nextTextFieldTag];
if (textFieldd!=nil) {
if ([textField isKindOfClass:[UITextField class]]) {
[textFieldd becomeFirstResponder];
return NO;
}
}
return YES;
}
Try this
Take the 4 textfields as textfield1,textfield2,textfile3,textfield4 .
In the textfield delegate method
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if([textField isEqual:textfield1])
{
[textfield2 becomeFirstResponder];
return NO;
}
else if([textField isEqual:textfield2])
{
[textfield3 becomeFirstResponder];
return NO;
}
// Do for other textfields
return YES;
}
You just need to know what the next TextField should be and have UITextFieldDelegateProtocol especially the - (BOOL)textFieldShouldReturn:(UITextField *)textField implemented.
In - (BOOL)textFieldShouldReturn:(UITextField *)textField simply figure out the next TextField and do [nextTextField becomeFirstResponder];
So the - (BOOL)textFieldShouldReturn:(UITextField *)textField Method could look like this:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if ([textField isEqual:firstTextField]) {
[secondTextField becomeFirstResponder];
}
//When last textfield dismiss the keyboard
else if ([textField lastTextField]) {
[textField resignFirstResponder];
}
return NO;
}

Setting TextField Focus on text removal

i have four textfields. User is allowed to enter only one digit in each text field.Once the user Enters single digit its focus should be on the next textfield. i have done this part and its working fine. Now, What i want is when i remove the text from the text field then its focus should move to previous textfield. i mean if i am deleting the text(digit) from the fourth text field then its focus should move to third text field. In short on removal of text the focus should be on previous textfield.
Now, what my problem is when i remove the text from the textfield then its focus moves to previous textfield but it clears the text of that textfield(the textfield on which i have set the focus).What i want is the text should not be removed on focus.
in .h file
IBOutlet UITextField *txtPinDigit1;
IBOutlet UITextField *txtPinDigit2;
IBOutlet UITextField *txtPinDigit3;
IBOutlet UITextField *txtPinDigit4;
UITextField *currentTextField;
in .m file
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(textField.tag==0)
{
currentTextField=txtPinDigit1;
}
else if(textField.tag==1)
{
currentTextField=txtPinDigit2;
}
else if(textField.tag==2)
{
currentTextField=txtPinDigit3;
if(isDelete)
{
textField.text=digit3;
}
}
else if(textField.tag==3)
{
currentTextField=txtPinDigit4;
}
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(([textField.text length]==1)&&(![string isEqualToString:#""]))
{
if(currentTextField==txtPinDigit1)
{
[txtPinDigit2 becomeFirstResponder];
}
else if(currentTextField==txtPinDigit2)
{
[txtPinDigit3 becomeFirstResponder];
}
else if(currentTextField==txtPinDigit3)
{
[txtPinDigit4 becomeFirstResponder];
}
else if(currentTextField==txtPinDigit4)
{
textField.text = [textField.text substringToIndex:MAXLENGTH-1];
//[txtPinDigit4 resignFirstResponder];
//[txtPinDigit1 becomeFirstResponder];
}
}
else if([string isEqualToString:#""])
{
isDelete=YES;
NSLog(#"replacementString:%#",string);
// textField.text=string;
if(currentTextField==txtPinDigit4)
{
textField.text=string;
digit3=nil;
[digit3 release];
digit3=[[NSString alloc] initWithFormat:#"%i",[txtPinDigit3.text intValue]];
[txtPinDigit3 becomeFirstResponder];
}
else if(currentTextField==txtPinDigit3)
{
textField.text=string;
[txtPinDigit2 becomeFirstResponder];
}
else if(currentTextField==txtPinDigit2)
{
textField.text=string;
[txtPinDigit1 becomeFirstResponder];
}
else if(currentTextField==txtPinDigit1)
{
textField.text=string;
// [txtPinDigit1 resignFirstResponder];
//[txtPinDigit1 becomeFirstResponder];
}
}
return YES;
}
in the above code MAXLENGTH=1 defined.
any help will be appreciated.
thanks in advance.
Try This code, Change shouldChangeCharactersInRange: Delegate Method
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if ([newString length] < 1)
{
if (textField.tag==2)
{
[txtPinDigit1 performSelector:#selector(becomeFirstResponder) withObject:nil afterDelay:0.0];
// txt2.text=#"";
}
else if (textField.tag==3)
{
[txtPinDigit2 performSelector:#selector(becomeFirstResponder) withObject:nil afterDelay:0.0];
}
else if (textField.tag==4)
{
[txtPinDigit3 performSelector:#selector(becomeFirstResponder) withObject:nil afterDelay:0.0];
}
return YES;
} else
{
// Otherwise we cut the length of newString to 1 (if needed) and set it to the textField.
textField.text = [newString length] > 1 ? [newString substringToIndex:1] : newString;
if (textField.tag==1)
{
[textField resignFirstResponder];
[txtPinDigit2 becomeFirstResponder];
}
else if (textField.tag==2)
{
[textField resignFirstResponder];
[txtPinDigit3 becomeFirstResponder];
}
else if (textField.tag==3)
{
[textField resignFirstResponder];
[txtPinDigit4 becomeFirstResponder];
}
return NO;
}
}
Check to check length via this way and put a break point at beginning of shouldChangeCharactersInRange
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int length = textField.text.length - range.length + string.length;
return YES;
}
I hope it will help you.
Before calling up to become first responder on filling up the 1st digit,bind the entered text inputs & the responder into dictionary...
On each previous/next condition,retrieve the information from the dictionary...The below example code is for the general previous/next custom actions(not auto though)..You just need to change the logic a bit based on the condition you prefer...
- (NSArray *) responders
{
if (_responders)
return _responders;
NSArray *textInputs = EditableTextInputsInView([[UIApplication sharedApplication] keyWindow]);
return [textInputs sortedArrayUsingComparator:^NSComparisonResult(UIView *textInput1, UIView *textInput2) {
UIView *commonAncestorView = textInput1.superview;
while (commonAncestorView && ![textInput2 isDescendantOfView:commonAncestorView])
commonAncestorView = commonAncestorView.superview;
CGRect frame1 = [textInput1 convertRect:textInput1.bounds toView:commonAncestorView];
CGRect frame2 = [textInput2 convertRect:textInput2.bounds toView:commonAncestorView];
return [#(CGRectGetMinY(frame1)) compare:#(CGRectGetMinY(frame2))];
}];
}
The below function should get called before doing previous/next auto tab.
- (Void) selectAdjacentResponder: (UISegmentedControl *) sender
{
NSArray *firstResponders = [self.responders filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(UIResponder *responder, NSDictionary *bindings) {
return [responder isFirstResponder];
}]];
NSLog(#"%#",firstResponders);
UIResponder *firstResponder = [firstResponders lastObject];
NSInteger offset = sender.selectedSegmentIndex == 0 ? -1 : +1;
NSInteger firstResponderIndex = [self.responders indexOfObject:firstResponder];
NSInteger adjacentResponderIndex = firstResponderIndex != NSNotFound ? firstResponderIndex + offset : NSNotFound;
UIResponder *adjacentResponder = nil;
if (adjacentResponderIndex >= 0 && adjacentResponderIndex < (NSInteger)[self.responders count])
adjacentResponder = [self.responders objectAtIndex:adjacentResponderIndex];
[adjacentResponder becomeFirstResponder];
}
Bit lengthier,but this is all i know a BIT :)..Happy coding...

Resources