How to not resign first responder for UITextField in iOS

Issue #353

When using STPPaymentCardTextField from stripe-ios, the default behavior is when we touch outside to dismiss keyboard, it checks and focus on number text field is it is invalid

STPPaymentCardTextField.m

- (STPFormTextField *)currentFirstResponderField {
    for (STPFormTextField *textField in [self allFields]) {
        if ([textField isFirstResponder]) {
            return textField;
        }
    }
    return nil;
}

- (BOOL)canResignFirstResponder {
    return [self.currentFirstResponderField canResignFirstResponder];
}

- (BOOL)resignFirstResponder {
    [super resignFirstResponder];
    BOOL success = [self.currentFirstResponderField resignFirstResponder];
    [self layoutViewsToFocusField:nil
                         animated:YES
                       completion:nil];
    [self updateImageForFieldType:STPCardFieldTypeNumber];
    return success;
}

Then it calls [self.numberField becomeFirstResponder]; is validation on number fails

typedef void (^STPLayoutAnimationCompletionBlock)(BOOL completed);
- (void)layoutViewsToFocusField:(NSNumber *)focusedField
                       animated:(BOOL)animated
                     completion:(STPLayoutAnimationCompletionBlock)completion {

    NSNumber *fieldtoFocus = focusedField;

    if (fieldtoFocus == nil
        && ![self.focusedTextFieldForLayout isEqualToNumber:@(STPCardFieldTypeNumber)]
        && ([self.viewModel validationStateForField:STPCardFieldTypeNumber] != STPCardValidationStateValid)) {
        fieldtoFocus = @(STPCardFieldTypeNumber);
        [self.numberField becomeFirstResponder];
    }
}

isUserInteractionEnabled

Be aware to use isUserInteractionEnabled on STPPaymentCardTextField as that can resign first responder when set to true and become first responder when set to false

Written by

I’m open source contributor, writer, speaker and product maker.

Start the conversation