Merge branch 'feature/refineRegistrationAndVerification'

pull/1/head
Matthew Chen 8 years ago
commit 4f02e893e7

@ -139,6 +139,7 @@ NSString *const kCompletedRegistrationSegue = @"CompletedRegistration";
@"Text field placeholder for SMS verification code during registration");
_challengeTextField.font = [UIFont ows_lightFontWithSize:21.f];
_challengeTextField.textAlignment = NSTextAlignmentCenter;
_challengeTextField.keyboardType = UIKeyboardTypePhonePad;
_challengeTextField.delegate = self;
[self.view addSubview:_challengeTextField];
[_challengeTextField autoPinWidthToSuperviewWithMargin:kHMargin];
@ -392,18 +393,6 @@ NSString *const kCompletedRegistrationSegue = @"CompletedRegistration";
[self.view endEditing:NO];
}
- (NSString *)stringByFilteringString:(NSString *)input
withCharacterSet:(NSCharacterSet *)characterSet {
NSMutableString *result = [NSMutableString new];
for (NSUInteger i=0; i < input.length; i++) {
unichar c = [input characterAtIndex:i];
if ([characterSet characterIsMember:c]) {
[result appendFormat:@"%c", c];
}
}
return [result copy];
}
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)insertionText {
@ -423,18 +412,14 @@ NSString *const kCompletedRegistrationSegue = @"CompletedRegistration";
// * Take partial input if possible.
NSString *oldText = textField.text;
NSCharacterSet *validCharacterSet = [NSCharacterSet decimalDigitCharacterSet];
// Construct the new contents of the text field by:
// 1. Determining the "left" substring: the contents of the old text _before_ the deletion range.
// Filtering will remove non-decimal digit characters like hyphen "-".
NSString *left = [self stringByFilteringString:[oldText substringToIndex:range.location]
withCharacterSet:validCharacterSet];
NSString *left = [oldText substringToIndex:range.location].digitsOnly;
// 2. Determining the "right" substring: the contents of the old text _after_ the deletion range.
NSString *right = [self stringByFilteringString:[oldText substringFromIndex:range.location + range.length]
withCharacterSet:validCharacterSet];
NSString *right = [oldText substringFromIndex:range.location + range.length].digitsOnly;
// 3. Determining the "center" substring: the contents of the new insertion text.
NSString *center = [self stringByFilteringString:insertionText
withCharacterSet:validCharacterSet];
NSString *center = insertionText.digitsOnly;
// 3a. Trim the tail of the "center" substring to ensure that we don't end up
// with more than 6 decimal digits.
while (center.length > 0 &&
@ -474,9 +459,17 @@ NSString *const kCompletedRegistrationSegue = @"CompletedRegistration";
}
- (void)setVerificationCodeAndTryToVerify:(NSString *)verificationCode {
NSCharacterSet *validCharacterSet = [NSCharacterSet decimalDigitCharacterSet];
self.challengeTextField.text = [self stringByFilteringString:verificationCode
withCharacterSet:validCharacterSet];
NSString *rawNewText = verificationCode.digitsOnly;
NSString *formattedNewText = (rawNewText.length <= 3
? rawNewText
: [[[rawNewText substringToIndex:3]
stringByAppendingString:@"-"]
stringByAppendingString:[rawNewText substringFromIndex:3]]);
self.challengeTextField.text = formattedNewText;
// Move the cursor after the newly inserted text.
UITextPosition *newPosition = [self.challengeTextField endOfDocument];
self.challengeTextField.selectedTextRange = [self.challengeTextField textRangeFromPosition:newPosition
toPosition:newPosition];
[self verifyChallengeAction:nil];
}

@ -26,6 +26,7 @@ static NSString *const kCodeSentSegue = @"codeSent";
// Do any additional setup after loading the view.
_phoneNumberTextField.delegate = self;
_phoneNumberTextField.keyboardType = UIKeyboardTypeNumberPad;
[self populateDefaultCountryNameAndCode];
[[Environment getCurrent] setSignUpFlowNavigationController:self.navigationController];
@ -148,35 +149,41 @@ static NSString *const kCodeSentSegue = @"codeSent";
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
NSString *textBeforeChange = textField.text;
// backspacing should skip over formatting characters
UITextPosition *posIfBackspace = [textField positionFromPosition:textField.beginningOfDocument
offset:(NSInteger)(range.location + range.length)];
UITextRange *rangeIfBackspace = [textField textRangeFromPosition:posIfBackspace toPosition:posIfBackspace];
bool isBackspace =
string.length == 0 && range.length == 1 && [rangeIfBackspace isEqual:textField.selectedTextRange];
if (isBackspace) {
NSString *digits = textBeforeChange.digitsOnly;
NSUInteger correspondingDeletePosition = [PhoneNumberUtil translateCursorPosition:range.location + range.length
from:textBeforeChange
to:digits
stickingRightward:true];
if (correspondingDeletePosition > 0) {
textBeforeChange = digits;
range = NSMakeRange(correspondingDeletePosition - 1, 1);
}
}
// make the proposed change
NSString *textAfterChange = [textBeforeChange withCharactersInRange:range replacedBy:string];
NSUInteger cursorPositionAfterChange = range.location + string.length;
replacementString:(NSString *)insertionText {
// Phone numbers takes many forms.
//
// * We only want to let the user enter decimal digits.
// * The user shouldn't have to enter hyphen, parentheses or whitespace;
// the phone number should be formatted automatically.
// * The user should be able to copy and paste freely.
// * Invalid input should be simply ignored.
//
// We accomplish this by being permissive and trying to "take as much of the user
// input as possible".
//
// * Always accept deletes.
// * Ignore invalid input.
// * Take partial input if possible.
NSString *oldText = textField.text;
// Construct the new contents of the text field by:
// 1. Determining the "left" substring: the contents of the old text _before_ the deletion range.
// Filtering will remove non-decimal digit characters like hyphen "-".
NSString *left = [oldText substringToIndex:range.location].digitsOnly;
// 2. Determining the "right" substring: the contents of the old text _after_ the deletion range.
NSString *right = [oldText substringFromIndex:range.location + range.length].digitsOnly;
// 3. Determining the "center" substring: the contents of the new insertion text.
NSString *center = insertionText.digitsOnly;
// 4. Construct the "raw" new text by concatenating left, center and right.
NSString *textAfterChange = [[left stringByAppendingString:center]
stringByAppendingString:right];
// 5. Construct the "formatted" new text by inserting a hyphen if necessary.
// reformat the phone number, trying to keep the cursor beside the inserted or deleted digit
bool isJustDeletion = string.length == 0;
bool isJustDeletion = insertionText.length == 0;
NSUInteger cursorPositionAfterChange = left.length + center.length;
NSString *textAfterReformat =
[PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:textAfterChange.digitsOnly
[PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:textAfterChange
withSpecifiedCountryCodeString:_countryCodeButton.titleLabel.text];
NSUInteger cursorPositionAfterReformat = [PhoneNumberUtil translateCursorPosition:cursorPositionAfterChange
from:textAfterChange
@ -184,12 +191,18 @@ static NSString *const kCodeSentSegue = @"codeSent";
stickingRightward:isJustDeletion];
textField.text = textAfterReformat;
UITextPosition *pos =
[textField positionFromPosition:textField.beginningOfDocument offset:(NSInteger)cursorPositionAfterReformat];
[textField positionFromPosition:textField.beginningOfDocument offset:(NSInteger)cursorPositionAfterReformat];
[textField setSelectedTextRange:[textField textRangeFromPosition:pos toPosition:pos]];
return NO; // inform our caller that we took care of performing the change
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[self sendCodeAction:nil];
[textField resignFirstResponder];
return NO;
}
#pragma mark - Unwind segue
- (IBAction)unwindToChangeNumber:(UIStoryboardSegue *)sender {

Loading…
Cancel
Save