3

Card number first 12 digits should be secure entry and remaining 4 digits as normal for example i am entering card number - 4111 1111 1111 1111. While entering this text in textfield first 12 digits should be secure entry and last 4 digits should be as normal entry i.e., 1111.(finally card number will looks like XXXXXXXXXXXX1111).

Can any one explain me how to do it.

Earth
  • 43
  • 5

2 Answers2

5

One option is to implement the UITextField delegate method textField:shouldChangeCharactersInRange:replacementString:. In this method you would want to always return NO. But first you would update the text field's text such that the first 12 digits show an X. You would keep track of the actual text in another ivar.

Edit: This should work:

- (NSString *)maskNumber:(NSString *)num {
    static NSString *twelveX = @"XXXXXXXXXXXX";

    if (num.length < twelveX.length) {
        return [twelveX substringToIndex:num.length];
    } else {
        return [twelveX stringByAppendingString:[num substringFromIndex:twelveX.length]];
    }
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    // Determine where the cursor should be
    UITextRange *selRange = textField.selectedTextRange;
    NSInteger cursorPos = [textField offsetFromPosition:textField.beginningOfDocument toPosition:selRange.start] + string.length;

    _cardNum = [_cardNum stringByReplacingCharactersInRange:range withString:string];

    textField.text = [self maskNumber:_cardNum];

    // Reset the cursor position
    UITextPosition *startPos = [textField positionFromPosition:textField.beginningOfDocument offset:cursorPos];
    selRange = [textField textRangeFromPosition:startPos toPosition:startPos];
    textField.selectedTextRange = selRange;

    return NO;
}

where _cardNum is an ivar of type NSString. This tracks the actual card number.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
4

I would recommend that you keep two fields, the first, a 12-character limited password field that secures the text.

Limit the length of the field with the following delegate method:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    NSUInteger newLength = [textField.text length] + [string length] - range.length;
    return (newLength > 12) ? NO : YES;
}

Set the field to enforce secure text entry:

twelveDigitTextField.secureTextEntry = YES;

The second field, you limit to four characters with the same approach used for the 12-character field. You don't need to protect this field with the secureTextEntry property.

If you want to make this interface "nice", track the length of the first field with the same delegate method and set the second field as the next responder — in other words, the cursor will jump to the four-character field once the twelve-character field fills up:

/* called within delegate method for 12-character field, once filled up */
[fourDigitTextField becomeFirstResponder]; 

One reason why you might want to do it this way is to get the same OS-level protections for sensitive data (like a 12-digit card number) as for a password, entered into a password-style UITextField.

While you can do tricks with replacing text as typewritten, it could be easier to overlook allowing sensitive numbers from this unprotected field to be copied and pasted to another application — whereas with a password field, those limitations are usually in place by default.

Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345