Resigning First Responder for multiple UITextFields - iphone

There is an application in which I am generating multiple UITextFields dynamically. I want to resign first responder whenever the UITextFields are not selected (touch outside the UITextField). How can I know that of which UITextField I have to resign first responder? Please specify any other way beyond the 'tag' concept because I have tried that. Please suggest the right direction. Thanks in advance.

Don't call resignFirstResponder; call endEditing:!
Call endEditing: on any view above the text fields in the view hierarchy. It will locate the first responder and ask it to resign. Use endEditing:YES to force it or endEditing:NO to let the text field's delegate decide if it should end editing (useful if you are validating input).

**[self.view endEditing:TRUE];** //Resign firstresponder for all textboxes on the view

You can implement delegate method
- (void)textFieldDidBeginEditing:(UITextField *)textField;
in that you can take currentTextField = textField;
in another delegate method
- (BOOL)textFieldShouldReturn:(UITextField *)textField;
you can do currentTextField = nil;
you can then resign currentTextField....

use this code and implement
-(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 NO; // We do not want UITextField to insert line-breaks.
}

You can try it like this:
- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event {
for (id textField in self.view.subviews) {
if ([textField isKindOfClass:[UITextField class]] && [textField isFirstResponder]) {
[textField resignFirstResponder];
}
}
}
I didn't try it but it seems a good solution

The most generic way and also the only one that worked for me in an UITableViewController was sending the action down the responder-chain and wait for the right object to receive the action:
[[UIApplication sharedApplication] sendAction:#selector(resignFirstResponder) to:nil from:nil forEvent:nil];
Tested in iOS8

You can set textFields as properties and synthesize them. You will need as many properties as you are using in your app.
You can have #synthesise myTextField0, myTextField1, myTextField2; for three textFields. Just assign each UITextField you are using to these properties, while declaring them.
And when you want to resign them, just use [self.myTextField0 resignFirstResponder] at textFieldDidEndEditing or which ever function you want to resign them. And you can use this for other textFields also. This is the way to handle multiple textFields
In general, you can skip all these steps, with textField.returnKeyType = UIReturnKeyDone;
if you have a DONE return key, you can just go to the method
- (BOOL) textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return 1;
}
or you can use tags to tag certain textFields and then resign particular ones.

By the way..i have done this in different manner.. Not looking quite a good programming Champ tech but enough to solve my work!!
for(UIView *v in self.view.subviews)
{
if(([v isMemberOfClass:[UITextField class]]==YES) && !(CGRectContainsPoint(v.frame,[[touches anyObject] locationInView:self.View)))
{
v.userInteractionEnabled=NO;
if([v isEditing])
{
[v resignFirstResponder];
}
}
}

you can check with isFirstResponder.
At any point of time only one UIResponder (UITextField in your case) can be firstResonder.

Using [self.view endEditing:YES]; to resignFirstResponder for the current active UITextField.

This worked for me in Xamarin.iOS / Monotouch.
Change the keyboard button to Next, pass the control to the next UITextField and hide the keyboard after the last UITextField.
private void SetShouldReturnDelegates(IEnumerable<UIView> subViewsToScout )
{
foreach (var item in subViewsToScout.Where(item => item.GetType() == typeof (UITextField)))
{
(item as UITextField).ReturnKeyType = UIReturnKeyType.Next;
(item as UITextField).ShouldReturn += (textField) =>
{
nint nextTag = textField.Tag + 1;
var nextResponder = textField.Superview.ViewWithTag(nextTag);
if (null != nextResponder)
nextResponder.BecomeFirstResponder();
else
textField.Superview.EndEditing(true);
//You could also use textField.ResignFirstResponder(); but the above line makes some users happier (e.g. benzado)
return false; // We do not want UITextField to insert line-breaks.
};
}
}
Inside the ViewDidLoad you'll have:
If your TextFields haven't a Tag set it now:
txtField1.Tag = 0;
txtField2.Tag = 1;
txtField3.Tag = 2;
//...
and just the call
SetShouldReturnDelegates(yourViewWithTxtFields.Subviews.ToList());
//If you are not sure of which view contains your fields you can also call it in a safer way:
SetShouldReturnDelegates(txtField1.Superview.Subviews.ToList());
//You can also reuse the same method with different containerViews in case your UITextField are under different views.

I had a problem in Resigning first responder for the selected UITextField from the multiple TextField.
I find out this is working for me after so many different solutions.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
for (id textField in self.view.subviews) {
if ([textField isKindOfClass:[UITextField class]] && [textField isFirstResponder] && [textField isEqual:_selectedLabel] ) {
[textField resignFirstResponder];
}
}
}

You can use endEditing instead of resignFirstResponder
Try This
[self.view EndEditing:YES]

Related

UITextfield keyboard resign

in my uitableview in each cell I'm having uitextfield when user edits the textfield and after pressing any other button on the screen the Keyboard is not resigning. I did the following in textfield delegates
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
textfieldInCell = textField;
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
textfieldInCell=nil;// this is the ivar i am using for each textfield in cell.
return YES;
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
textfieldInCell=textField;
// do the process...
textfieldInCell=nil
}
I am also calling the shouldReturn delegate function once the user tapping on any other button but the keyboard is not resigning. Where am I going wrong?
Confirm that you bind the delegate of each textfield that you create with the view controller and add one line of code in textfield did end editing :-
-(void)textFieldDidEndEditing:(UITextField *)textField
{
// add the following line
[textField resignFirstResponder];
textfieldInCell=textField;
// do the process...
textfieldInCell=nil
}
have you bind delegate of textfield with your controller? or did you check textFieldShouldReturn calling or not?
i think, binding is missing wit view controller in your case.
thanks
add a line in your tableview where you are adding textfield.
<YOUR_TEXTFIELD>.delegate = YES;
Enjoy Programming
first check that you give the delegate or not and give the delegate to UITextField after that when you call the method of button at that time resign this textfield like bellow...
-(IBAction)yourButton_Clicked(id)sender{
[yourTextField resignFirstResponder];
////your code write here
}
you must try to assign tag value to textfield then in should return method you used that tag to hide the keyboard like this (if you assign the tag -1 then)
-(void)textFieldDidEndEditing:(UITextField *)textField{
if(textField.tag==-1){
[textField resignFirstResponder];
}
}

UITextField strange behaviour on resignFirstResponder

Already the second day and cannot figure out the problem,
I've UITabelView with Custom UICellViews, each custom UICellView consists of UILabel and UITextField.
Custom UICellView object allocs UITextField and UILabel in its init method and are released in dealloc.
The number of custom UICellViews in UITableView is 6.
The user scenario is following
When user clicks from from 1 to 5 UITextFields virtual keyboard opens and user types some text
When user clicks on the 6th UITextField if virtual keyboard is active, it should be hidden, and if it is hidden it shall not be displayed.
As implement UITextFieldDelegate protocol in my UIViewController class and set the delegate of each UITextField to self.
My delegate methods are following
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if (textField.tag != 6) {
return YES;
} else {
[textField resignFirstResponder];
return NO;
}
}
-(BOOL) textFieldShouldEndEditing:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
-(void) textFieldDidBeginEditing:(UITextField *)textField {
/* Some code */
}
-(void) textFieldDidEndEditing:(UITextField *)textField
{
[textField resignFirstResponder];
}
All the functions are properly !
So now, the virtual keyboard is never get hidden, why this happens ?
PS. Similar code has worked on iPhone but this issue exists on iPad.
You need to know which textfield was last used! so you can do [lastUsedTextField resignFirstResponder]
There is a dirty, but working trick.. you can make your textfield the new active UITextField and call resignFirstResponder in the next cycle immediately:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if (textField.tag != 6) {
return YES;
} else {
// this will schedule keyboard dismissal for the current text field
dispatch_async(dispatch_get_main_queue(), ^{
[textField resignFirstResponder];
});
return YES; // -> make this one active
}
}
did you seted action for textField?
[YourTextField addTarget:self action:#selector(textFieldDoneEditing:) forControlEvents:UIControlEventEditingDidEndOnExit];
PS set any selector for any ControlEvent

keyboard is not getting dismissed on UITextField

This may sound a newbie question, however I'm new to iOS dev.
Platform : iPad
I have a UITableView with UITextField, let say they are two.
When pressing on the first one virtual keyboard should appear, but when user tapps on the second UITextField the virtual keyboard should be hidden and data picker view should be displayed.
So here it is, how I did it.
-(void) textFieldDidBeginEditing:(UITextField *)textField {
if (textField.tag == PICKER_VIEW_TAG) {
[textField resignFirstResponder];
} else {
...
}
}
-(void) textFieldDidEndEditing:(UITextField *)textField
{
if (textField.tag != PICKER_VIEW_TAG) {
...
}
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if (textField.tag == PICKER_VIEW_TAG) {
[self countriesPickerView];
}
return YES;
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField.tag == PICKER_VIEW_TAG) {
[textField resignFirstResponder];
} else {
...
}
return YES;
}
So now the question, when I click for the first time on the first UITextField it displays keyboard, but when I switch to second one it does not hide it. Why ? and how to solve this ?
UPDATE : The corresponding textField is not getting selected but i.e. the resign takes place, right ? but the keyboard is not hidden ... why this happens ?
The issue is with your textFieldShouldReturn. If you want it to complete the action, allow it to return while resigning the first responder.
[textField resignFirstResponder];
return YES;
Set the inputView property on UITextField to display views other than keyboard to receive input. In this case, you would set the text field's inputView to be an instance of UIDatePicker. The picker will be displayed with the same keyboard animation automatically and you get to delete a bunch of code. Win/win.

uikeyboard return

I have one view name:myplay.h and myplay.m
my view contain one textfield name txtplay..
It contain one button name btnplay.
In button event i want to check that if uikeyboard is open then close it.
I know below code
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return TRUE;
}
and in button click event
-(IBAction)btnplayclick:(id)sender
{
[self.txtplay resignFirstResponder];
....
....
}
I want a global code to resign.
Try this:
[self.view endEditing:YES];
From the doc:
endEditing:
Causes the view (or one of its embedded text fields) to resign the first responder status.
(BOOL)endEditing:(BOOL)force
This method looks at the current view and its subview hierarchy for the text field that is currently the first responder. If it finds one, it asks that text field to resign as first responder. If the force parameter is set to YES, the text field is never even asked; it is forced to resign.
Available in iOS 2.0 and later.
The best way i think to be generic and reuse your code anywhere is to create a category for the UIView :
#implementation UIView (FindFirstResponder)
- (UIView *)findFirstResonder
{
if (self.isFirstResponder) {
return self;
}
for (UIView *subView in self.subviews) {
UIView *firstResponder = [subView findFirstResonder];
if (firstResponder != nil) {
return firstResponder;
}
}
return nil;
}
#end
And then to call the method like that :
-(IBAction)btnplayclick:(id)sender
{
UIView *firstResponder = [self.view findFirstResonder];
[firstResponder resignFirstResponder];
}
It does the tricks perfectly for me.
or just write
[self.view findAndResignFirstResponder];
Calling resignFirstResponder on a UITextField that ISN'T first responder is a harmless no-op.
So go:
for (UIView *candidate in self.subview) {
if ([candidate isKindOfClass:[UITextView class]]) {
[(UITextView *)candidate resignFirstResponder];
}
}

iPhone: Possible to dismiss keyboard with UITextField clear button?

I'm wondering if there is a way to have the UITextField clear button 'always visible'
textfield.clearButtonMode = UITextFieldViewModeAlways;
doesn't seem to work
.. and if it is possible to dismiss the keyboard using the button?
Thanks in advance.
Like mentioned before it seems apple is setting the textfield focus after you clear the field.
The solution is quite simple. Just clear the field yourself, resignFirstResponder and return NO
-(BOOL)textFieldShouldClear:(UITextField *)textField
{
textField.text = #"";
[textField resignFirstResponder];
return NO;
}
In your delegate, the function
- (BOOL)textFieldShouldClear:(UITextField *)textField
is called when the users wants to clear the textfield. If you return YES and call
[textField resignFirstResponder];
the keyboard should go away. I don't know about the clearButtonMode, other than that you may want to set it early, preferably before adding the view to its superview.
edit To make sure you really resign the responder, try doing it just a little later:
[textField performSelector:#selector(resignFirstResponder) withObject:nil afterDelay:0.1];
The delay didn't work well for me. Instead I added an instance variable to the delegate:
BOOL cancelEdit;
Then in the delegate implementation:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if (cancelEdit) {
cancelEdit = NO;
return NO;
} else {
return YES;
}
}
- (BOOL)textFieldShouldClear:(UITextField *)textField
{
cancelEdit = YES;
return YES;
}
UITextFieldDelegate textFieldShouldClear
- (BOOL)textFieldShouldClear:(UITextField *)textField {
[textField] resignFirstResponder];
return YES;
http://developer.apple.com/iphone/library/documentation/uikit/reference/UITextFieldDelegate_Protocol/UITextFieldDelegate/UITextFieldDelegate.html#//apple_ref/occ/intfm/UITextFieldDelegate/textFieldShouldClear:
I discovered this odd behavior was caused by a competing gesture recognizer that resigned the first responder before the keyboard before textFieldShouldClear: was called. It seemed to be corrupting the first responder.
If you've set it up this way, ensure that cancelsTouchesInView on your gesture recognizer is set to YES. This way you shouldn't need to do anything special in the textFieldShouldClear: or textFieldShouldBeginEditing: delegate methods.