i have placed Dynamically created textfield in scrollview.I need to set contentOffset for the scrollview. In textfield shouldbegin Editing i have given the scrollview. It works fine if i traverse through Done button. But in betwwen if i tap any textfield that textfield goes up and and i cannot see the textfield. It shows the nextfield offset but cursor is in correct textfield. My code is
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if(enteredHealthyHeart)
{
for(int i=0;i<[healthyHeart_TxtFldAry count];i++)
{
if(textField == [healthyHeart_TxtFldAry objectAtIndex:i])
{
getHHTag=textField.tag;
NSLog(#"getHHTag %i",getHHTag);
UITextField *tempTxtFld=[healthyHeart_TxtFldAry objectAtIndex:getHHTag];
if(i<([healthyHeart_TxtFldAry count]-1))
{
int j =tempTxtFld.frame.origin.y;
healthyHeartScrollView.contentOffset=CGPointMake(0 , j);
NSLog(#"j>>>>>%i",j);
}
if(i==([healthyHeart_TxtFldAry count]-1))
{
healthyHeartScrollView.contentOffset=CGPointMake(0 ,tempTxtFld.frame.origin.y);
}
[tempTxtFld resignFirstResponder];
return YES;
}
}
}
}
Please help me to solve this issue.
Firstly add tag to each and every UITextField;
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
//Take reference of all UITextField u added let say u have 3;
UITextField *txt = (UItextField *)[self.view viewWithTag:99];
UITextField *txt1 = (UItextField *)[self.view viewWithTag:199];
UITextField *txt2 = (UItextField *)[self.view viewWithTag:299];
if(textField == txt)
{
[txt1 resignFirstResponder];
[txt2 resignFirstResponder];
//required scroll view offset here
}
if(textField == txt1)
{
[txt resignFirstResponder];
[txt2 resignFirstResponder];
//required scroll view offset here
}
if(textField == txt2)
{
[txt resignFirstResponder];
[txt1 resignFirstResponder];
//required scroll view offset here
}
return YES;
}
scrollview.contentOffset is the point at which the content view is offset from the orgin scroll view. In you code
healthyHeartScrollView.contentOffset=CGPointMake(0 ,tempTxtFld.frame.origin.y);
The tempTxtFld is out of hte content view of healthyHeartScrollView. This makes the tempTxtFld.frame.orgin.y be negative relative to the contentview of healthyHeartScrollView.
So you can't see it.
ps. I really do not know what you want to do.-_-
Related
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...!
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.
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;
}
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...
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];
}