UITextField pour le numéro de téléphone

Je me demandais comment je pouvais formater le textField que j’utilise pour obtenir un numéro de téléphone (par exemple, la page “Ajouter un nouveau contact” sur l’iPhone. Lorsque j’entre dans un nouveau téléphone mobile, par exemple, 1236890987 ) 689-0987.) J’ai déjà défini le clavier comme pavé numérique.

Voici ma solution .. fonctionne très bien! Formate le numéro de téléphone en temps réel. Remarque: Ceci est pour les numéros de téléphone à 10 chiffres. Et actuellement, il formate automatiquement comme (xxx) xxx-xxxx .. tweak à votre gré plaisir.

D’abord, vous devez collecter la chaîne complète du champ de texte du téléphone dans votre shouldChangeCharactersInRange et la transmettre à la fonction de validation / formatage.

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementSsortingng:(NSSsortingng *)ssortingng { NSSsortingng* totalSsortingng = [NSSsortingng ssortingngWithFormat:@"%@%@",textField.text,ssortingng]; // if it's the phone number textfield format it. if(textField.tag==102 ) { if (range.length == 1) { // Delete button was hit.. so tell the method to delete the last char. textField.text = [self formatPhoneNumber:totalSsortingng deleteLastChar:YES]; } else { textField.text = [self formatPhoneNumber:totalSsortingng deleteLastChar:NO ]; } return false; } return YES; } 

Et voici où le numéro de téléphone est formaté. Le regex pourrait probablement être nettoyé un peu. Mais j’ai testé ce code pendant un moment et semble passer toutes les cloches. Notez que nous utilisons également cette fonction pour supprimer un numéro du numéro de téléphone. Fonctionne un peu plus facilement ici car nous avons déjà retiré tous les autres chiffres.

  -(NSSsortingng*) formatPhoneNumber:(NSSsortingng*) simpleNumber deleteLastChar:(BOOL)deleteLastChar { if(simpleNumber.length==0) return @""; // use regex to remove non-digits(including spaces) so we are left with just the numbers NSError *error = NULL; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[\\s-\\(\\)]" options:NSRegularExpressionCaseInsensitive error:&error]; simpleNumber = [regex ssortingngByReplacingMatchesInSsortingng:simpleNumber options:0 range:NSMakeRange(0, [simpleNumber length]) withTemplate:@""]; // check if the number is to long if(simpleNumber.length>10) { // remove last extra chars. simpleNumber = [simpleNumber subssortingngToIndex:10]; } if(deleteLastChar) { // should we delete the last digit? simpleNumber = [simpleNumber subssortingngToIndex:[simpleNumber length] - 1]; } // 123 456 7890 // format the number.. if it's less then 7 digits.. then use this regex. if(simpleNumber.length<7) simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d{3})(\\d+)" withString:@"($1) $2" options:NSRegularExpressionSearch range:NSMakeRange(0, [simpleNumber length])]; else // else do this one.. simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\\d{3})(\\d{3})(\\d+)" withString:@"($1) $2-$3" options:NSRegularExpressionSearch range:NSMakeRange(0, [simpleNumber length])]; return simpleNumber; } 

Voici comment vous pouvez le faire en Swift:

 func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementSsortingng ssortingng: Ssortingng) -> Bool { if (textField == phoneTextField) { let newSsortingng = (textField.text! as NSSsortingng).ssortingngByReplacingCharactersInRange(range, withSsortingng: ssortingng) let components = newSsortingng.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet) let decimalSsortingng = components.joinWithSeparator("") as NSSsortingng let length = decimalSsortingng.length let hasLeadingOne = length > 0 && decimalSsortingng.characterAtIndex(0) == (1 as unichar) if length == 0 || (length > 10 && !hasLeadingOne) || length > 11 { let newLength = (textField.text! as NSSsortingng).length + (ssortingng as NSSsortingng).length - range.length as Int return (newLength > 10) ? false : true } var index = 0 as Int let formattedSsortingng = NSMutableSsortingng() if hasLeadingOne { formattedSsortingng.appendSsortingng("1 ") index += 1 } if (length - index) > 3 { let areaCode = decimalSsortingng.subssortingngWithRange(NSMakeRange(index, 3)) formattedSsortingng.appendFormat("(%@)", areaCode) index += 3 } if length - index > 3 { let prefix = decimalSsortingng.subssortingngWithRange(NSMakeRange(index, 3)) formattedSsortingng.appendFormat("%@-", prefix) index += 3 } let remainder = decimalSsortingng.subssortingngFromIndex(index) formattedSsortingng.appendSsortingng(remainder) textField.text = formattedSsortingng as Ssortingng return false } else { return true } } 

Réponse mise à jour de Vikzilla pour Swift 3:

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementSsortingng ssortingng: Ssortingng) -> Bool { if textField == phoneTextField { let newSsortingng = (textField.text! as NSSsortingng).replacingCharacters(in: range, with: ssortingng) let components = (newSsortingng as NSSsortingng).components(separatedBy: NSCharacterSet.decimalDigits.inverted) let decimalSsortingng = components.joined(separator: "") as NSSsortingng let length = decimalSsortingng.length let hasLeadingOne = length > 0 && decimalSsortingng.character(at: 0) == (1 as unichar) if length == 0 || (length > 10 && !hasLeadingOne) || length > 11 { let newLength = (textField.text! as NSSsortingng).length + (ssortingng as NSSsortingng).length - range.length as Int return (newLength > 10) ? false : true } var index = 0 as Int let formattedSsortingng = NSMutableSsortingng() if hasLeadingOne { formattedSsortingng.append("1 ") index += 1 } if (length - index) > 3 { let areaCode = decimalSsortingng.subssortingng(with: NSMakeRange(index, 3)) formattedSsortingng.appendFormat("(%@)", areaCode) index += 3 } if length - index > 3 { let prefix = decimalSsortingng.subssortingng(with: NSMakeRange(index, 3)) formattedSsortingng.appendFormat("%@-", prefix) index += 3 } let remainder = decimalSsortingng.subssortingng(from: index) formattedSsortingng.append(remainder) textField.text = formattedSsortingng as Ssortingng return false } else { return true } } 

J’ai lutté avec ça pendant quelques heures, voici ce que j’ai:

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementSsortingng:(NSSsortingng *)ssortingng { NSUInteger currentLength = textField.text.length; NSCharacterSet *numbers = [NSCharacterSet decimalDigitCharacterSet]; if (range.length == 1) { return YES; } if ([numbers characterIsMember:[ssortingng characterAtIndex:0]]) { if ( currentLength == 3 ) { if (range.length != 1) { NSSsortingng *firstThreeDigits = [textField.text subssortingngWithRange:NSMakeRange(0, 3)]; NSSsortingng *updatedText; if ([ssortingng isEqualToSsortingng:@"-"]) { updatedText = [NSSsortingng ssortingngWithFormat:@"%@",firstThreeDigits]; } else { updatedText = [NSSsortingng ssortingngWithFormat:@"%@-",firstThreeDigits]; } [textField setText:updatedText]; } } else if ( currentLength > 3 && currentLength < 8 ) { if ( range.length != 1 ) { NSString *firstThree = [textField.text substringWithRange:NSMakeRange(0, 3)]; NSString *dash = [textField.text substringWithRange:NSMakeRange(3, 1)]; NSUInteger newLenght = range.location - 4; NSString *nextDigits = [textField.text substringWithRange:NSMakeRange(4, newLenght)]; NSString *updatedText = [NSString stringWithFormat:@"%@%@%@",firstThree,dash,nextDigits]; [textField setText:updatedText]; } } else if ( currentLength == 8 ) { if ( range.length != 1 ) { NSString *areaCode = [textField.text substringWithRange:NSMakeRange(0, 3)]; NSString *firstThree = [textField.text substringWithRange:NSMakeRange(4, 3)]; NSString *nextDigit = [textField.text substringWithRange:NSMakeRange(7, 1)]; [textField setText:[NSString stringWithFormat:@"(%@) %@-%@",areaCode,firstThree,nextDigit]]; } } } else { return NO; } return YES; } 

J'espère que quelqu'un peut consortingbuer.

La fonction ci-dessous applique le format (999)333-5555 sur le textField:

Swift 3:

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementSsortingng ssortingng: Ssortingng) -> Bool { if (textField == self.phone){ let newSsortingng = (textField.text! as NSSsortingng).replacingCharacters(in: range, with: ssortingng) let components = newSsortingng.components(separatedBy: NSCharacterSet.decimalDigits.inverted) let decimalSsortingng = components.joined(separator: "") as NSSsortingng let length = decimalSsortingng.length let hasLeadingOne = length > 0 && decimalSsortingng.character(at: 0) == (1 as unichar) if length == 0 || (length > 10 && !hasLeadingOne) || length > 11 { let newLength = (textField.text! as NSSsortingng).length + (ssortingng as NSSsortingng).length - range.length as Int return (newLength > 10) ? false : true } var index = 0 as Int let formattedSsortingng = NSMutableSsortingng() if hasLeadingOne { formattedSsortingng.append("1 ") index += 1 } if (length - index) > 3 { let areaCode = decimalSsortingng.subssortingng(with: NSMakeRange(index, 3)) formattedSsortingng.appendFormat("(%@)", areaCode) index += 3 } if length - index > 3 { let prefix = decimalSsortingng.subssortingng(with: NSMakeRange(index, 3)) formattedSsortingng.appendFormat("%@-", prefix) index += 3 } let remainder = decimalSsortingng.subssortingng(from: index) formattedSsortingng.append(remainder) textField.text = formattedSsortingng as Ssortingng return false } else { return true } } 

Voici ma prise de vue. Ce qui est proche de ce que fait Apple dans l’application Téléphone et Contacts (du moins lorsque votre région est définie sur US, je ne suis pas sûr que le comportement change par région).

J’étais particulièrement intéressé par le formatage allant jusqu’à 1 (123) 123-1234 et prenant en charge des nombres plus longs sans formatage. Il y a aussi un bug en vérifiant simplement range.length == 1 (pour delete / backspace) dans les autres solutions qui empêche un utilisateur de sélectionner la chaîne entière ou une partie de celle-ci et en appuyant sur la touche delete / backspace.

Il y a quelques comportements étranges qui se produisent lorsque vous commencez à sélectionner une plage au milieu et à modifier, où le curseur se termine toujours à la fin de la chaîne en raison de la définition de la valeur des champs de texte. Je ne sais pas comment repositionner le curseur dans un UITextField , je présume qu’Apple utilise actuellement UITextView dans les applications Contacts et Téléphone car ils maintiennent la position du curseur tout en effectuant ce formatage en ligne, ils semblent gérer toutes les petites nuances! J’aurais aimé qu’ils nous donnent juste ceci de la boîte.

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementSsortingng:(NSSsortingng *)ssortingng { NSMutableSsortingng *newSsortingng = [NSMutableSsortingng ssortingngWithSsortingng:textField.text]; [newSsortingng replaceCharactersInRange:range withSsortingng:ssortingng]; NSSsortingng *phoneNumberSsortingng = [self formattedPhoneNumber:newSsortingng]; if (range.length >= 1) { // backspace/delete if (phoneNumberSsortingng.length > 1) { // the way we format the number it is possible that when the user presses backspace they are not deleting the last number // in the ssortingng, so we need to check if the last character is a number, if it isn't we need to delete everything after the // last number in the ssortingng unichar lastChar = [phoneNumberSsortingng characterAtIndex:phoneNumberSsortingng.length-1]; NSCharacterSet *numberCharacterSet = [NSCharacterSet characterSetWithCharactersInSsortingng:@"1234567890#*"]; if (![numberCharacterSet characterIsMember:lastChar]) { NSRange numberRange = [phoneNumberSsortingng rangeOfCharacterFromSet:numberCharacterSet options:NSBackwardsSearch]; phoneNumberSsortingng = [phoneNumberSsortingng subssortingngToIndex:numberRange.location+1]; } } } textField.text = phoneNumberSsortingng; return NO; } - (NSSsortingng *)formattedPhoneNumber:(NSSsortingng *)ssortingng { NSSsortingng *formattedPhoneNumber = @""; NSCharacterSet *numberCharacterSet = [NSCharacterSet characterSetWithCharactersInSsortingng:@"1234567890#*+"]; NSRange pauseRange = [ssortingng rangeOfSsortingng:@","]; NSRange waitRange = [ssortingng rangeOfSsortingng:@";"]; NSSsortingng *numberSsortingngToFormat = nil; NSSsortingng *numberSsortingngToAppend = @""; if (pauseRange.location != NSNotFound || waitRange.location != NSNotFound) { NSSsortingng *choppedSsortingng = [ssortingng subssortingngToIndex:MIN(pauseRange.location, waitRange.location)]; numberSsortingngToFormat = [[choppedSsortingng componentsSeparatedByCharactersInSet:[numberCharacterSet invertedSet]] componentsJoinedBySsortingng:@""]; numberSsortingngToAppend = [ssortingng subssortingngFromIndex:MIN(pauseRange.location, waitRange.location)]; } else { numberSsortingngToFormat = [[ssortingng componentsSeparatedByCharactersInSet:[numberCharacterSet invertedSet]] componentsJoinedBySsortingng:@""]; } if ([numberSsortingngToFormat hasPrefix:@"0"] || [numberSsortingngToFormat hasPrefix:@"11"]) { // numbers starting with 0 and 11 should not be formatted formattedPhoneNumber = numberSsortingngToFormat; } else if ([numberSsortingngToFormat hasPrefix:@"1"]) { if (numberSsortingngToFormat.length <= 1) { // 1 formattedPhoneNumber = numberStringToFormat; } else if (numberStringToFormat.length <= 4) { // 1 (234) NSString *areaCode = [numberStringToFormat substringFromIndex:1]; if (areaCode.length < 3) { formattedPhoneNumber = [NSString stringWithFormat:@"1 (%@", [numberStringToFormat substringFromIndex:1]]; // 1 (XXX) } else { formattedPhoneNumber = [NSString stringWithFormat:@"1 (%@) ", [numberStringToFormat substringFromIndex:1]]; // 1 (XXX) } } else if (numberStringToFormat.length <= 7) { // 1 (234) 123 formattedPhoneNumber = [NSString stringWithFormat:@"1 (%@) %@", [numberStringToFormat substringWithRange:NSMakeRange(1, 3)], //1 (XXX) 123 [numberStringToFormat substringFromIndex:4]]; // 1 (234) XXX } else if (numberStringToFormat.length <= 11) { // 1 (123) 123-1234 formattedPhoneNumber = [NSString stringWithFormat:@"1 (%@) %@-%@", [numberStringToFormat substringWithRange:NSMakeRange(1, 3)], //1 (XXX) 123 [numberStringToFormat substringWithRange:NSMakeRange(4, 3)], //1 (234) XXX-1234 [numberStringToFormat substringFromIndex:7]]; // 1 (234) 123-XXXX } else { // 1123456789012.... formattedPhoneNumber = numberStringToFormat; } } else { if (numberStringToFormat.length <= 3) { // 123 formattedPhoneNumber = numberStringToFormat; } else if (numberStringToFormat.length <= 7) { // 123-1234 formattedPhoneNumber = [NSString stringWithFormat:@"%@-%@", [numberStringToFormat substringToIndex:3], // XXX-1234 [numberStringToFormat substringFromIndex:3]]; // 123-XXXX } else if (numberStringToFormat.length <= 10) { // (123) 123-1234 formattedPhoneNumber = [NSString stringWithFormat:@"(%@) %@-%@", [numberStringToFormat substringToIndex:3], // (XXX) 123-1234 [numberStringToFormat substringWithRange:NSMakeRange(3, 3)], // (123) XXX-1234 [numberStringToFormat substringFromIndex:6]]; // (123) 123-XXXX } else { // 123456789012.... formattedPhoneNumber = numberStringToFormat; } } if (numberStringToAppend.length > 0) { formattedPhoneNumber = [NSSsortingng ssortingngWithFormat:@"%@%@", formattedPhoneNumber, numberSsortingngToAppend]; } return formattedPhoneNumber; } 

Cette solution fonctionne parfaitement pour les numéros d’Amérique du Nord sans le préfixe de numérotation international (+1) et sans extension. Le numéro sera formaté comme “(212) 555-1234”. Il préréglera le “)” et le “-“, mais supprimera également correctement.

Voici le -textField:shouldChangeCharactersInRange:replacementSsortingng que votre délégué de champ de texte doit implémenter:

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementSsortingng:(NSSsortingng *)ssortingng { if (textField == self.myPhoneTextField) { NSSsortingng *newText = [textField.text ssortingngByReplacingCharactersInRange:range withSsortingng:ssortingng]; BOOL deleting = [newText length] < [textField.text length]; NSString *stripppedNumber = [newText stringByReplacingOccurrencesOfString:@"[^0-9]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [newText length])]; NSUInteger digits = [stripppedNumber length]; if (digits > 10) ssortingpppedNumber = [ssortingpppedNumber subssortingngToIndex:10]; UITextRange *selectedRange = [textField selectedTextRange]; NSInteger oldLength = [textField.text length]; if (digits == 0) textField.text = @""; else if (digits < 3 || (digits == 3 && deleting)) textField.text = [NSString stringWithFormat:@"(%@", stripppedNumber]; else if (digits < 6 || (digits == 6 && deleting)) textField.text = [NSString stringWithFormat:@"(%@) %@", [stripppedNumber substringToIndex:3], [stripppedNumber substringFromIndex:3]]; else textField.text = [NSString stringWithFormat:@"(%@) %@-%@", [stripppedNumber substringToIndex:3], [stripppedNumber substringWithRange:NSMakeRange(3, 3)], [stripppedNumber substringFromIndex:6]]; UITextPosition *newPosition = [textField positionFromPosition:selectedRange.start offset:[textField.text length] - oldLength]; UITextRange *newRange = [textField textRangeFromPosition:newPosition toPosition:newPosition]; [textField setSelectedTextRange:newRange]; return NO; } return YES; } 

Réponse mise à jour pour Swift 2.0 de Vikzilla:

 func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementSsortingng ssortingng: Ssortingng) -> Bool { sendButton.enabled = true let newSsortingng = (textField.text! as NSSsortingng).ssortingngByReplacingCharactersInRange(range, withSsortingng: ssortingng) let components = newSsortingng.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet) let decimalSsortingng : Ssortingng = components.joinWithSeparator("") let length = decimalSsortingng.characters.count let decimalStr = decimalSsortingng as NSSsortingng let hasLeadingOne = length > 0 && decimalStr.characterAtIndex(0) == (1 as unichar) if length == 0 || (length > 10 && !hasLeadingOne) || length > 11 { let newLength = (textField.text! as NSSsortingng).length + (ssortingng as NSSsortingng).length - range.length as Int return (newLength > 10) ? false : true } var index = 0 as Int let formattedSsortingng = NSMutableSsortingng() if hasLeadingOne { formattedSsortingng.appendSsortingng("1 ") index += 1 } if (length - index) > 3 { let areaCode = decimalStr.subssortingngWithRange(NSMakeRange(index, 3)) formattedSsortingng.appendFormat("(%@)", areaCode) index += 3 } if length - index > 3 { let prefix = decimalStr.subssortingngWithRange(NSMakeRange(index, 3)) formattedSsortingng.appendFormat("%@-", prefix) index += 3 } let remainder = decimalStr.subssortingngFromIndex(index) formattedSsortingng.appendSsortingng(remainder) textField.text = formattedSsortingng as Ssortingng return false } 

Travailler excelente pour moi, j’espère que ça marche pour vous aussi 🙂

Vous pouvez append un numéro de téléphone comme 000-000-0000 (10 chiffres). Veuillez vous référer à ce code.

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementSsortingng:(NSSsortingng *)ssortingng { if (textField==Phone_TXT) { if (range.location == 12) { return NO; } // Backspace if ([ssortingng length] == 0) return YES; if ((range.location == 3) || (range.location == 7)) { NSSsortingng *str = [NSSsortingng ssortingngWithFormat:@"%@-",textField.text]; textField.text = str; } return YES; } } 

Ma solution pour + X (XXX) format XXX-XXXX. (RAPIDE)

 func textFieldDidBeginEditing(textField: UITextField) { if (textField == self.mobileField) { textField.text = "+" } } func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementSsortingng ssortingng: Ssortingng) -> Bool { if (textField == self.mobileField) { let newSsortingng = (textField.text! as NSSsortingng).ssortingngByReplacingCharactersInRange(range, withSsortingng: ssortingng) if (newSsortingng.characters.count < textField.text?.characters.count && newString.characters.count >= 1) { return true // return true for backspace to work } else if (newSsortingng.characters.count < 1) { return false; // deleting "+" makes no sence } if (newString.characters.count > 17 ) { return false; } let components = newSsortingng.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet) let decimalSsortingng = components.joinWithSeparator("") as NSSsortingng let length = decimalSsortingng.length var index = 0 let formattedSsortingng = NSMutableSsortingng() formattedSsortingng.appendSsortingng("+") if (length >= 1) { let countryCode = decimalSsortingng.subssortingngWithRange(NSMakeRange(0, 1)) formattedSsortingng.appendSsortingng(countryCode) index += 1 } if (length > 1) { var rangeLength = 3 if (length < 4) { rangeLength = length - 1 } let operatorCode = decimalString.substringWithRange(NSMakeRange(1, rangeLength)) formattedString.appendFormat(" (%@) ", operatorCode) index += operatorCode.characters.count } if (length > 4) { var rangeLength = 3 if (length < 7) { rangeLength = length - 4 } let prefix = decimalString.substringWithRange(NSMakeRange(4, rangeLength)) formattedString.appendFormat("%@-", prefix) index += prefix.characters.count } if (index < length) { let remainder = decimalString.substringFromIndex(index) formattedString.appendString(remainder) } textField.text = formattedString as String if (newString.characters.count == 17) { textField.resignFirstResponder() } return false } return true } 

Swift 4 (et sans NSSsortingng)

pour le format + X (XXX) XXX-XXXX ou + X (XXX) XXX-XX-XX Mis à jour et légèrement

 class ViewController: UIViewController, UITextFieldDelegate { var myPhoneNumber = Ssortingng() @IBOutlet weak var phoneTextField: UITextField! override func viewDidLoad() { super.viewDidLoad() phoneTextField.delegate = self phoneTextField.keyboardType = .phonePad } func textFieldDidBeginEditing(_ textField: UITextField) { if (textField == self.phoneTextField) && textField.text == ""{ textField.text = "+7(" //your country code default } } func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementSsortingng ssortingng: Ssortingng) -> Bool { if textField == phoneTextField { let res = phoneMask(phoneTextField: phoneTextField, textField: textField, range, ssortingng) myPhoneNumber = res.phoneNumber != "" ? "+\(res.phoneNumber)" : "" print("Phone - \(myPhoneNumber) MaskPhone=\(res.maskPhoneNumber)") if (res.phoneNumber.count == 11) || (res.phoneNumber.count == 0) { //phone number entered or completely cleared print("EDIT END: Phone = \(myPhoneNumber) MaskPhone = \(res.maskPhoneNumber)") } return res.result } return true } } extension UITextFieldDelegate { func phoneMask(phoneTextField: UITextField, textField: UITextField, _ range: NSRange, _ ssortingng: Ssortingng) -> (result: Bool, phoneNumber: Ssortingng, maskPhoneNumber: Ssortingng) { let oldSsortingng = textField.text! let newSsortingng = oldSsortingng.replacingCharacters(in: Range(range, in: oldSsortingng)!, with: ssortingng) //in numSsortingng only Numeric characters let components = newSsortingng.components(separatedBy: CharacterSet.decimalDigits.inverted) let numSsortingng = components.joined(separator: "") let length = numSsortingng.count let maxCharInPhone = 11 if newSsortingng.count < oldString.count { //backspace to work if newString.count <= 2 { //if now "+7(" and push backspace phoneTextField.text = "" return (false, "", "") } else { return (true, numString, newString) //will not in the process backspace } } if length > maxCharInPhone { // input is complete, do not add characters return (false, numSsortingng, newSsortingng) } var indexStart, indexEnd: Ssortingng.Index var maskSsortingng = "", template = "" var endOffset = 0 if newSsortingng == "+" { // allow add "+" if first Char maskSsortingng += "+" } //format +X(XXX)XXX-XXXX if length > 0 { maskSsortingng += "+" indexStart = numSsortingng.index(numSsortingng.startIndex, offsetBy: 0) indexEnd = numSsortingng.index(numSsortingng.startIndex, offsetBy: 1) maskSsortingng += Ssortingng(numSsortingng[indexStart.. 1 { endOffset = 4 template = ")" if length < 4 { endOffset = length template = "" } indexStart = numString.index(numString.startIndex, offsetBy: 1) indexEnd = numString.index(numString.startIndex, offsetBy: endOffset) maskString += String(numString[indexStart.. 4 { endOffset = 7 template = "-" if length < 7 { endOffset = length template = "" } indexStart = numString.index(numString.startIndex, offsetBy: 4) indexEnd = numString.index(numString.startIndex, offsetBy: endOffset) maskString += String(numString[indexStart.. if need uncoment // nIndex = 9 // // if length > 7 { // endOffset = 9 // template = "-" // if length < 9 { // endOffset = length // template = "" // } // indexStart = numString.index(numString.startIndex, offsetBy: 7) // indexEnd = numString.index(numString.startIndex, offsetBy: endOffset) // maskString += String(numString[indexStart.. nIndex { indexStart = numSsortingng.index(numSsortingng.startIndex, offsetBy: nIndex) indexEnd = numSsortingng.index(numSsortingng.startIndex, offsetBy: length) maskSsortingng += Ssortingng(numSsortingng[indexStart.. 

Vous pouvez appeler cette méthode chaque fois que vous devez mettre à jour votre textField:

 extension Ssortingng { func applyPatternOnNumbers(pattern: Ssortingng, replacmentCharacter: Character) -> Ssortingng { var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression) for index in 0 ..< pattern.count { guard index < pureNumber.count else { return pureNumber } let stringIndex = String.Index(encodedOffset: index) let patternCharacter = pattern[stringIndex] guard patternCharacter != replacmentCharacter else { continue } pureNumber.insert(patternCharacter, at: stringIndex) } return pureNumber } } 

Exemple:

  guard let text = textField.text else { return } textField.text = text.applyPatternOnNumbers(pattern: "+# (###) ###-####", replacmentCharacter: "#") 

Malheureusement, vous devez le faire vous-même. L’application de contact utilise des API non documentées. Pour une raison quelconque, la connexion de formateurs d’entrée à des champs de texte n’est pas visible sur l’iPhone comme sur Mac. N’hésitez pas à déposer un rapport de bogue sur l’amélioration des fonctionnalités.

J’espère que ce que je vais dire sera utile pour la programmation de nouvelles personnes sur iOS, comme je le suis. J’ai fait ce que zingle-dingle suggère (merci beaucoup!). Pour aider les nouveaux, le code ainsi que ce que je vais lister pourraient vous aider. 1. vous devez append UITextFieldDelegate dans le fichier d’en-tête. 2. UITextField doit lier le délégué à la vue, dans mon cas, UIViewController, qui est le fichier d’en-tête. 3. le champ UITextField doit être instaturé, cela signifie votre texte.delegate = self, sur le fichier “.m”.

Voici mon code Swift 2, légèrement localisé du sharepoint vue britannique.

Il formatera:

+11234567890 au +1 (123) 456 7890

+33123456789 au 01 23 45 67 89

+441234123456 au +44 1234 123456 (ceci a été localisé à 01234 123456) car je n’ai pas besoin de voir le code du pays pour les numéros britanniques.

Appelez comme suit:

 initInternationalPhoneFormats() //this just needs to be done once var formattedNo = formatInternationalPhoneNo("+11234567890") 

Si vous avez d’autres codes de pays et formats ou des améliorations au code s’il vous plaît faites le moi savoir.

Prendre plaisir.

 import Cocoa extension Ssortingng { //extension from http://stackoverflow.com/questions/24092884/get-nth-character-of-a-ssortingng-in-swift-programming-language subscript (i: Int) -> Character { return self[self.startIndex.advancedBy(i)] } } var phoneNoFormat = [Ssortingng : Ssortingng]() var localCountryCode: Ssortingng? = "+44" func initInternationalPhoneFormats() { if phoneNoFormat.count == 0 { phoneNoFormat["0"] = "+44 #### ######" //local no (UK) phoneNoFormat["02"] = "+44 ## #### #####" //local no (UK) London phoneNoFormat["+1"] = "+# (###) ###-####" //US and Canada phoneNoFormat["+234"] = "+## # ### ####" //Nigeria phoneNoFormat["+2348"] = "+## ### ### ####" //Nigeria Mobile phoneNoFormat["+31"] = "+## ### ## ## ##" //Netherlands phoneNoFormat["+316"] = "+## # ## ## ## ##" //Netherlands Mobile phoneNoFormat["+33"] = "+## # ## ## ## ##" //France phoneNoFormat["+39"] = "+## ## ########" //Italy phoneNoFormat["+392"] = "+## #### #####" //Italy phoneNoFormat["+393"] = "+## ### #######" //Italy phoneNoFormat["+44"] = "+## #### ######" //United Kingdom phoneNoFormat["+442"] = "+## ## #### #####" //United Kingdom London phoneNoFormat["+51"] = "+## # ### ####" //Peru phoneNoFormat["+519"] = "+## ### ### ###" //Peru Mobile phoneNoFormat["+54"] = "+## ### ### ####" //Argentina phoneNoFormat["+541"] = "+## ## #### ####" //Argentina phoneNoFormat["+549"] = "+## # ### ### ####" //Argentina phoneNoFormat["+55"] = "+## (##) ####-####" //Brazil phoneNoFormat["+551"] = "+## (##) ####-###" //Brazil Mobile? phoneNoFormat["+60"] = "+## # #### ####" //Malaysia phoneNoFormat["+6012"] = "+## ## ### ####" //Malaysia Mobile phoneNoFormat["+607"] = "+## # ### ####" //Malaysia? phoneNoFormat["+61"] = "+## # #### ####" //Australia phoneNoFormat["+614"] = "+## ### ### ###" //Australia Mobile phoneNoFormat["+62"] = "+## ## #######" //Indonesia phoneNoFormat["+628"] = "+## ### ######" //Indonesia Mobile phoneNoFormat["+65"] = "+## #### ####" //Singapore phoneNoFormat["+90"] = "+## (###) ### ## ##" //Turkey } } func getDiallingCode(phoneNo: Ssortingng) -> Ssortingng { var countryCode = phoneNo while countryCode.characters.count > 0 && phoneNoFormat[countryCode] == nil { countryCode = Ssortingng(countryCode.characters.dropLast()) } if countryCode == "0" { return localCountryCode! } return countryCode } func formatInternationalPhoneNo(fullPhoneNo: Ssortingng, localisePhoneNo: Bool = true) -> Ssortingng { if fullPhoneNo == "" { return "" } initInternationalPhoneFormats() let diallingCode = getDiallingCode(fullPhoneNo) let localPhoneNo = fullPhoneNo.ssortingngByReplacingOccurrencesOfSsortingng(diallingCode, withSsortingng: "", options: NSSsortingngCompareOptions.LiteralSearch, range: nil) var filteredPhoneNo = (localPhoneNo.characters.filter{["0","1","2","3","4","5","6","7","8","9"].contains($0)}) if filteredPhoneNo[0] == "0" { filteredPhoneNo.removeFirst() } let phoneNo:Ssortingng = diallingCode + Ssortingng(filteredPhoneNo) if let format = phoneNoFormat[diallingCode] { let formatLength = format.characters.count var formattedPhoneNo = [Character]() var formatPos = 0 for char in phoneNo.characters { while formatPos < formatLength && format[formatPos] != "#" && format[formatPos] != "+" { formattedPhoneNo.append(format[formatPos]) formatPos++ } if formatPos < formatLength { formattedPhoneNo.append(char) formatPos++ } else { break } } if localisePhoneNo, let localCode = localCountryCode { return String(formattedPhoneNo).stringByReplacingOccurrencesOfString(localCode + " ", withString: "0", options: NSStringCompareOptions.LiteralSearch, range: nil) //US users need to remove the extra 0 } return String(formattedPhoneNo) } return String(filteredPhoneNo) } 

https://github.com/chebur/CHRTextFieldFormatter fonctionne pour moi comme un charme.

Copier / coller depuis la page d’utilisation:

 - (void)viewDidLoad { [super viewDidLoad]; self.phoneNumberFormatter = [[CHRTextFieldFormatter alloc] initWithTextField:self.phoneNumberTextField mask:[CHRPhoneNumberMask new]]; self.cardNumberFormatter = [[CHRTextFieldFormatter alloc] initWithTextField:self.cardNumberTextField mask:[CHRCardNumberMask new]]; } - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementSsortingng:(NSSsortingng *)ssortingng { if (textField == self.phoneNumberTextField) { return [self.phoneNumberFormatter textField:textField shouldChangeCharactersInRange:range replacementSsortingng:ssortingng]; } else if (textField == self.cardNumberTextField) { return [self.cardNumberFormatter textField:textField shouldChangeCharactersInRange:range replacementSsortingng:ssortingng]; } else { return YES; } } 

Aussi rapide:

 override func viewDidLoad() { super.viewDidLoad() self.phoneNumber.delegate = self self.phoneNumberFormatter = CHRTextFieldFormatter(textField: self.phoneNumber, mask:CHRPhoneNumberMask()) } func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementSsortingng ssortingng: Ssortingng) -> Bool { if textField == self.phoneNumber { return self.phoneNumberFormatter.textField(textField, shouldChangeCharactersInRange: range, replacementSsortingng: ssortingng) } return true } 

Réponse mise à jour de “Unité iOS” pour Swift 3 au format + X (XXX) XXX-XXXX:

 func textFieldDidBeginEditing(_ textField: UITextField) { if (textField == self.phoneTextField) { textField.text = "+" } } func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementSsortingng ssortingng: Ssortingng) -> Bool { if (textField == self.phoneTextField) { let newSsortingng = (textField.text! as NSSsortingng).replacingCharacters(in: range, with: ssortingng) if (newSsortingng.characters.count < (textField.text?.characters.count)! && newString.characters.count >= 1) { return true // return true for backspace to work } else if (newSsortingng.characters.count < 1) { return false; // deleting "+" makes no sence } if (newString.characters.count > 17 ) { return false; } let components = newSsortingng.components(separatedBy: CharacterSet.decimalDigits.inverted) let decimalSsortingng = components.joined(separator: "") as NSSsortingng let length = decimalSsortingng.length var index = 0 let formattedSsortingng = NSMutableSsortingng() formattedSsortingng.append("+") if (length >= 1) { let countryCode = decimalSsortingng.subssortingng(with: NSMakeRange(0, 1)) formattedSsortingng.append(countryCode) index += 1 } if (length > 1) { var rangeLength = 3 if (length < 4) { rangeLength = length - 1 } let operatorCode = decimalString.substring(with: NSMakeRange(1, rangeLength)) formattedString.appendFormat(" (%@) ", operatorCode) index += operatorCode.characters.count } if (length > 4) { var rangeLength = 3 if (length < 7) { rangeLength = length - 4 } let prefix = decimalString.substring(with: NSMakeRange(4, rangeLength)) formattedString.appendFormat("%@-", prefix) index += prefix.characters.count } if (index < length) { let remainder = decimalString.substring(from: index) formattedString.append(remainder) } textField.text = formattedString as String if (newString.characters.count == 17) { textField.resignFirstResponder() } return false } return true } 

u have to do to this manually . take a notification of textField and check length of field text and format it according to country. if any problem let me know. I have done this

I have a solution for this but it is having some drawback, see if you can modify and use it. By using this you can achieve both ressortingct phone number to 10 digit and format it as per US format.

 #define MAX_LENGTH 10 

Implement it in UITextField Delegate method

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementSsortingng:(NSSsortingng *)ssortingng { NSInteger insertDelta = ssortingng.length - range.length; if (PhoneNumber_txt.text.length + insertDelta > MAX_LENGTH) { return NO; // the new ssortingng would be longer than MAX_LENGTH } else { range.length = 3; range.location = 3; PhoneNumber_txt.text = [NSSsortingng ssortingngWithFormat:@"(%@)%@-%@", [PhoneNumber_txt.text subssortingngToIndex:3], [PhoneNumber_txt.text subssortingngWithRange:range], [PhoneNumber_txt.text subssortingngFromIndex:6]]; return YES; } } 
 - (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementSsortingng:(NSSsortingng *)ssortingng { NSCharacterSet* validationSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet]; NSArray* components = [ssortingng componentsSeparatedByCharactersInSet:validationSet]; if ([components count] > 1) { return NO; } NSSsortingng* newSsortingng = [textField.text ssortingngByReplacingCharactersInRange:range withSsortingng:ssortingng]; NSArray* validComponents = [newSsortingng componentsSeparatedByCharactersInSet:validationSet]; static const int localNumberMaxLength = 7; static const int areaCodeMaxLength = 3; static const int countryCodeMaxLength = 2; newSsortingng = [validComponents componentsJoinedBySsortingng:@""]; if ([newSsortingng length] > localNumberMaxLength + areaCodeMaxLength + countryCodeMaxLength) { return NO; } NSLog(@"new ssortingng: %@", newSsortingng); NSMutableSsortingng* resultSsortingng = [NSMutableSsortingng ssortingng]; NSInteger localNumberLength = MIN([newSsortingng length], localNumberMaxLength); if (localNumberLength > 0) { NSSsortingng* number = [newSsortingng subssortingngFromIndex:(int)[newSsortingng length] - localNumberLength]; [resultSsortingng appendSsortingng:number]; if ([resultSsortingng length] > 3) { [resultSsortingng insertSsortingng:@"-" atIndex:3]; } } if ([newSsortingng length] > localNumberMaxLength) { NSInteger areaCodeLength = MIN((int)[newSsortingng length] - localNumberMaxLength, areaCodeMaxLength); NSRange areaRange = NSMakeRange((int)[newSsortingng length] - localNumberMaxLength - areaCodeLength, areaCodeLength); NSSsortingng* area = [newSsortingng subssortingngWithRange:areaRange]; area = [NSSsortingng ssortingngWithFormat:@"(%@) ",area]; [resultSsortingng insertSsortingng:area atIndex:0]; } if ([newSsortingng length] > localNumberMaxLength + areaCodeMaxLength) { NSInteger countryCodeLength = MIN((int)[newSsortingng length] - localNumberMaxLength - areaCodeMaxLength, countryCodeMaxLength); NSRange countryCodeRange = NSMakeRange(0, countryCodeLength); NSSsortingng* countryCode = [newSsortingng subssortingngWithRange:countryCodeRange]; countryCode = [NSSsortingng ssortingngWithFormat:@"+%@ ",countryCode]; [resultSsortingng insertSsortingng:countryCode atIndex:0]; } textField.text = resultSsortingng; return NO; 

}

Here is my solution for 05xx xxx xxxx phone format. At the beginning I set

 phoneTextField.delegate = self phoneTextField.text = "05" // I don't let user to change it. 

It also covers copy/paste cases for cursor position.

Maybe it helps someone for different formats.

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementSsortingng ssortingng: Ssortingng) -> Bool { if range.location == 0 || range.location == 1 { return false } var phone = (textField.text! as NSSsortingng).replacingCharacters(in: range, with: ssortingng) if phone.length > 13 { return false } phone = phone.replacingOccurrences(of: " ", with: "") if phone.characters.count > 7 { phone.insert(" ", at: phone.index(phone.startIndex, offsetBy: 4)) phone.insert(" ", at: phone.index(phone.startIndex, offsetBy: 8)) } else if phone.characters.count > 4 { phone.insert(" ", at: phone.index(phone.startIndex, offsetBy: 4)) } let text = textField.text let ssortingngToStart = text?.subssortingng(to: (text?.index((text?.startIndex)!, offsetBy: range.location))!) let ssortingngToStartCount = ((ssortingngToStart?.components(separatedBy: " ").count)! > 1) ? (ssortingngToStart?.components(separatedBy: " ").count)!-1 : 0 var cursorIndex = range.location + ssortingng.length - ssortingngToStartCount if cursorIndex > 7 { cursorIndex += 2 } else if cursorIndex > 4 { cursorIndex += 1 } textField.text = phone textField.selectedTextRange = textField.textRange(from: textField.position(from: textField.beginningOfDocument, offset: cursorIndex)!, to: textField.position(from: textField.beginningOfDocument, offset: cursorIndex)!) return false } 

You can use this library https://github.com/luximetr/AnyFormatKit

Exemple

 let textInputController = TextInputController() let textInput = TextInputField() // or TextInputView or any TextInput textInputController.textInput = textInput // setting textInput let formatter = TextInputFormatter(textPattern: "### (###) ###-##-##", prefix: "+12") textInputController.formatter = formatter // setting formatter 

Just set your textField to this textInputController and it will format text with pattern, that you set.

Ou

 let phoneFormatter = TextFormatter(textPattern: "### (###) ###-##-##") phoneFormatter.formattedText(from: "+123456789012") // +12 (345) 678-90-12 

for format full ssortingng

objective c solution for +X (XXX) XXX-XXXX format

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementSsortingng:(NSSsortingng *)ssortingng { if (textField == objCell.txtPhone) { NSSsortingng *newSsortingng = [textField.text ssortingngByReplacingCharactersInRange:range withSsortingng:ssortingng]; if (newSsortingng.length < ([textField.text length]) && newString.length >= 1) { return true; } else if (newSsortingng.length < 1) { return false; } if (newString.length > 15 ) { return false; } NSArray *components =[newSsortingng componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]; NSSsortingng *decimalSsortingng = [components componentsJoinedBySsortingng:@""]; NSUInteger length = decimalSsortingng.length; NSUInteger index = 0; NSMutableSsortingng *formattedSsortingng=[[NSMutableSsortingng alloc] init]; [formattedSsortingng appendSsortingng:@"+"]; if (length >= 1) { NSSsortingng *countryCode = [decimalSsortingng subssortingngWithRange:NSMakeRange(0,1)]; [formattedSsortingng appendSsortingng:countryCode]; index += 1; } if (length > 1) { NSUInteger rangeLength = 3; if (length < 4) { rangeLength = length - 1; } NSString *operatorCode = [decimalString substringWithRange:NSMakeRange(1, rangeLength)]; [formattedString appendFormat:@"(%@)",operatorCode]; index += operatorCode.length; } if (length > 4) { NSUInteger rangeLength = 3; if (length < 7) { rangeLength = length - 4; } NSString *prefix = [decimalString substringWithRange:NSMakeRange(4, rangeLength)]; [formattedString appendFormat:@"%@-",prefix]; index += prefix.length; } if (index < length) { NSString *remainder = [decimalString substringFromIndex:index]; [formattedString appendString:remainder]; } textField.text = formattedString; if (newString.length == 15) { [textField resignFirstResponder]; } contactNumberAdded=decimalString; return false; } return YES; } 

I use this format X (XXX) XXX XX XX it is work in Turkey,

I use it with TableView with Swift 4

 func formatToPhoneNumber(withPhoneTextField: UITextField, tableTextField: UITextField, range: NSRange, ssortingng: Ssortingng) -> Bool { if (tableTextField == withPhoneTextField) { let newSsortingng = (tableTextField.text! as NSSsortingng).replacingCharacters(in: range, with: ssortingng) let components = newSsortingng.components(separatedBy: NSCharacterSet.decimalDigits.inverted) let decimalSsortingng = components.joined(separator: "") as NSSsortingng let length = decimalSsortingng.length let hasLeadingOne = length > 0 && decimalSsortingng.character(at: 0) == (1 as unichar) if length == 0 || (length > 11 && !hasLeadingOne) || length > 12 { let newLength = (tableTextField.text! as NSSsortingng).length + (ssortingng as NSSsortingng).length - range.length as Int return (newLength > 11) ? false : true } var index = 0 as Int let formattedSsortingng = NSMutableSsortingng() if hasLeadingOne { formattedSsortingng.append("1 ") index += 1 } if (length - index) > 1{ let zeroNumber = decimalSsortingng.subssortingng(with: NSMakeRange(index, 1)) formattedSsortingng.appendFormat("%@ ", zeroNumber) index += 1 } if (length - index) > 3 { let areaCode = decimalSsortingng.subssortingng(with: NSMakeRange(index, 3)) formattedSsortingng.appendFormat("(%@) ", areaCode) index += 3 } if length - index > 3 { let prefix = decimalSsortingng.subssortingng(with: NSMakeRange(index, 3)) formattedSsortingng.appendFormat("%@ ", prefix) index += 3 } if (length - index) > 3{ let prefix = decimalSsortingng.subssortingng(with: NSMakeRange(index, 2)) formattedSsortingng.appendFormat("%@ ", prefix) index += 2 } let remainder = decimalSsortingng.subssortingng(from: index) formattedSsortingng.append(remainder) tableTextField.text = formattedSsortingng as Ssortingng return false } else { return true } } 

and you can call this func in

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementSsortingng ssortingng: Ssortingng, indexPath: IndexPath) -> Bool { } 

in any indexPath that your text field in it

for example my textfield in indexPath number 1 so the code will be

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementSsortingng ssortingng: Ssortingng, indexPath: IndexPath) -> Bool { if indexPath.row == 1 { let phoneTextField = textField return formatToPhoneNumber(withPhoneTextField: phoneTextField, tableTextField: textField, range: range, ssortingng: ssortingng) } }