UITextField pour le numéro de téléphone
je me demandais comment je pouvais formater la zone de texte que j'utilise pour un numéro de téléphone (c.-à-d. comme la page" Ajouter un nouveau Contact " sur l'iPhone. Quand j'entre dans un nouveau téléphone mobile, ex. 1236890987 il formats comme (123) 689-0987.) J'ai déjà le clavier comme Bloc-notes.
24 réponses
voici ma solution.. fonctionne très bien! Formate le numéro de téléphone en temps réel. Note: Ceci est pour les numéros de téléphone à 10 chiffres. Et actuellement il le formate automatiquement comme (xxx) xxx-xxxx.. modifier à votre cœur joie.
tout d'abord dans votre shouldChangeCharactersInRange
vous voulez rassembler la chaîne entière pour le champ de texte du téléphone et la passer à la fonction de validation/formatage.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString* totalString = [NSString stringWithFormat:@"%@%@",textField.text,string];
// 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:totalString deleteLastChar:YES];
} else {
textField.text = [self formatPhoneNumber:totalString 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 pour un moment et semble passer toutes les cloches. Avis nous également utiliser cette fonction pour supprimer un numéro le numéro de téléphone. Ça marche un peu mieux ici parce qu'on a déjà enlevé tous les autres non-chiffres.
-(NSString*) formatPhoneNumber:(NSString*) 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 stringByReplacingMatchesInString: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 substringToIndex:10];
}
if(deleteLastChar) {
// should we delete the last digit?
simpleNumber = [simpleNumber substringToIndex:[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:@"() "
options:NSRegularExpressionSearch
range:NSMakeRange(0, [simpleNumber length])];
else // else do this one..
simpleNumber = [simpleNumber stringByReplacingOccurrencesOfString:@"(\d{3})(\d{3})(\d+)"
withString:@"() -"
options:NSRegularExpressionSearch
range:NSMakeRange(0, [simpleNumber length])];
return simpleNumber;
}
Voici comment vous pouvez le faire dans Swift:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
if (textField == phoneTextField)
{
let newString = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
let components = newString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let decimalString = components.joinWithSeparator("") as NSString
let length = decimalString.length
let hasLeadingOne = length > 0 && decimalString.characterAtIndex(0) == (1 as unichar)
if length == 0 || (length > 10 && !hasLeadingOne) || length > 11
{
let newLength = (textField.text! as NSString).length + (string as NSString).length - range.length as Int
return (newLength > 10) ? false : true
}
var index = 0 as Int
let formattedString = NSMutableString()
if hasLeadingOne
{
formattedString.appendString("1 ")
index += 1
}
if (length - index) > 3
{
let areaCode = decimalString.substringWithRange(NSMakeRange(index, 3))
formattedString.appendFormat("(%@)", areaCode)
index += 3
}
if length - index > 3
{
let prefix = decimalString.substringWithRange(NSMakeRange(index, 3))
formattedString.appendFormat("%@-", prefix)
index += 3
}
let remainder = decimalString.substringFromIndex(index)
formattedString.appendString(remainder)
textField.text = formattedString as String
return false
}
else
{
return true
}
}
mise à jour de la réponse de Vikzilla pour Swift 3:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField == phoneTextField {
let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
let components = (newString as NSString).components(separatedBy: NSCharacterSet.decimalDigits.inverted)
let decimalString = components.joined(separator: "") as NSString
let length = decimalString.length
let hasLeadingOne = length > 0 && decimalString.character(at: 0) == (1 as unichar)
if length == 0 || (length > 10 && !hasLeadingOne) || length > 11 {
let newLength = (textField.text! as NSString).length + (string as NSString).length - range.length as Int
return (newLength > 10) ? false : true
}
var index = 0 as Int
let formattedString = NSMutableString()
if hasLeadingOne {
formattedString.append("1 ")
index += 1
}
if (length - index) > 3 {
let areaCode = decimalString.substring(with: NSMakeRange(index, 3))
formattedString.appendFormat("(%@)", areaCode)
index += 3
}
if length - index > 3 {
let prefix = decimalString.substring(with: NSMakeRange(index, 3))
formattedString.appendFormat("%@-", prefix)
index += 3
}
let remainder = decimalString.substring(from: index)
formattedString.append(remainder)
textField.text = formattedString as String
return false
} else {
return true
}
}
je lutte avec cela depuis quelques heures, voici ce que j'ai:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSUInteger currentLength = textField.text.length;
NSCharacterSet *numbers = [NSCharacterSet decimalDigitCharacterSet];
if (range.length == 1) {
return YES;
}
if ([numbers characterIsMember:[string characterAtIndex:0]]) {
if ( currentLength == 3 )
{
if (range.length != 1)
{
NSString *firstThreeDigits = [textField.text substringWithRange:NSMakeRange(0, 3)];
NSString *updatedText;
if ([string isEqualToString:@"-"])
{
updatedText = [NSString stringWithFormat:@"%@",firstThreeDigits];
}
else
{
updatedText = [NSString stringWithFormat:@"%@-",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 contribuer.
(999)333-5555 format sur le champ de texte:
Swift 3:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if (textField == self.phone){
let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
let components = newString.components(separatedBy: NSCharacterSet.decimalDigits.inverted)
let decimalString = components.joined(separator: "") as NSString
let length = decimalString.length
let hasLeadingOne = length > 0 && decimalString.character(at: 0) == (1 as unichar)
if length == 0 || (length > 10 && !hasLeadingOne) || length > 11 {
let newLength = (textField.text! as NSString).length + (string as NSString).length - range.length as Int
return (newLength > 10) ? false : true
}
var index = 0 as Int
let formattedString = NSMutableString()
if hasLeadingOne {
formattedString.append("1 ")
index += 1
}
if (length - index) > 3 {
let areaCode = decimalString.substring(with: NSMakeRange(index, 3))
formattedString.appendFormat("(%@)", areaCode)
index += 3
}
if length - index > 3 {
let prefix = decimalString.substring(with: NSMakeRange(index, 3))
formattedString.appendFormat("%@-", prefix)
index += 3
}
let remainder = decimalString.substring(from: index)
formattedString.append(remainder)
textField.text = formattedString as String
return false
} else {
return true
}
}
voici ce que j'en pense. Ce qui est proche de ce que fait Apple dans L'application Phone and Contacts (au moins quand votre région est définie aux États-Unis, Je ne suis pas sûr si le comportement change par région).
j'étais particulièrement intéressé à formater jusqu'à 1 (123) 123-1234
et à supporter des numéros plus longs sans formatage. Il y a aussi un bug dans la simple vérification de range.length == 1
(pour supprimer/backspace) dans les autres solutions qui empêche un utilisateur de sélectionner la chaîne entière ou une partie de il et en appuyant sur la touche delete / backspace, cela corrige cette situation.
il y a des comportements étranges qui se produisent lorsque vous commencez à sélectionner une plage au milieu et à éditer, où le curseur finit toujours à la fin de la chaîne en raison de la définition de la valeur des champs de texte. Je ne suis pas sûr de savoir comment repositionner le curseur dans un UITextField
, je présume Qu'Apple utilise en fait un UITextView
dans les applications de Contacts et de téléphone car ils maintiennent la position du curseur tout en faisant cela en ligne formatage, ils semblent gérer toutes les petites nuances! J'aimerais qu'ils me donnent de cette sortie de la boîte.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSMutableString *newString = [NSMutableString stringWithString:textField.text];
[newString replaceCharactersInRange:range withString:string];
NSString *phoneNumberString = [self formattedPhoneNumber:newString];
if (range.length >= 1) { // backspace/delete
if (phoneNumberString.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 string, 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 string
unichar lastChar = [phoneNumberString characterAtIndex:phoneNumberString.length-1];
NSCharacterSet *numberCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"1234567890#*"];
if (![numberCharacterSet characterIsMember:lastChar]) {
NSRange numberRange = [phoneNumberString rangeOfCharacterFromSet:numberCharacterSet options:NSBackwardsSearch];
phoneNumberString = [phoneNumberString substringToIndex:numberRange.location+1];
}
}
}
textField.text = phoneNumberString;
return NO;
}
- (NSString *)formattedPhoneNumber:(NSString *)string {
NSString *formattedPhoneNumber = @"";
NSCharacterSet *numberCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"1234567890#*+"];
NSRange pauseRange = [string rangeOfString:@","];
NSRange waitRange = [string rangeOfString:@";"];
NSString *numberStringToFormat = nil;
NSString *numberStringToAppend = @"";
if (pauseRange.location != NSNotFound || waitRange.location != NSNotFound) {
NSString *choppedString = [string substringToIndex:MIN(pauseRange.location, waitRange.location)];
numberStringToFormat = [[choppedString componentsSeparatedByCharactersInSet:[numberCharacterSet invertedSet]] componentsJoinedByString:@""];
numberStringToAppend = [string substringFromIndex:MIN(pauseRange.location, waitRange.location)];
} else {
numberStringToFormat = [[string componentsSeparatedByCharactersInSet:[numberCharacterSet invertedSet]] componentsJoinedByString:@""];
}
if ([numberStringToFormat hasPrefix:@"0"] || [numberStringToFormat hasPrefix:@"11"]) {
// numbers starting with 0 and 11 should not be formatted
formattedPhoneNumber = numberStringToFormat;
} else if ([numberStringToFormat hasPrefix:@"1"]) {
if (numberStringToFormat.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 = [NSString stringWithFormat:@"%@%@", formattedPhoneNumber, numberStringToAppend];
}
return formattedPhoneNumber;
}
cette solution fonctionne très bien pour les numéros Nord-Américains sans le préfixe de numérotation international (+1) et sans extension. Le numéro sera formaté comme suit: "(212) 555-1234". Il pré-Tapera le") "et le" -", mais supprimera également correctement.
voici le -textField:shouldChangeCharactersInRange:replacementString
que votre délégué de champ de texte devrait mettre en œuvre:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField == self.myPhoneTextField) {
NSString *newText = [textField.text stringByReplacingCharactersInRange:range withString:string];
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)
stripppedNumber = [stripppedNumber substringToIndex: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;
}
mise à jour de la réponse pour Swift 2.0 de Vikzilla:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
sendButton.enabled = true
let newString = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
let components = newString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let decimalString : String = components.joinWithSeparator("")
let length = decimalString.characters.count
let decimalStr = decimalString as NSString
let hasLeadingOne = length > 0 && decimalStr.characterAtIndex(0) == (1 as unichar)
if length == 0 || (length > 10 && !hasLeadingOne) || length > 11
{
let newLength = (textField.text! as NSString).length + (string as NSString).length - range.length as Int
return (newLength > 10) ? false : true
}
var index = 0 as Int
let formattedString = NSMutableString()
if hasLeadingOne
{
formattedString.appendString("1 ")
index += 1
}
if (length - index) > 3
{
let areaCode = decimalStr.substringWithRange(NSMakeRange(index, 3))
formattedString.appendFormat("(%@)", areaCode)
index += 3
}
if length - index > 3
{
let prefix = decimalStr.substringWithRange(NSMakeRange(index, 3))
formattedString.appendFormat("%@-", prefix)
index += 3
}
let remainder = decimalStr.substringFromIndex(index)
formattedString.appendString(remainder)
textField.text = formattedString as String
return false
}
Travaillé excelente pour moi, espérons que cela fonctionne pour vous aussi :)
vous pouvez ajouter le numéro de téléphone comme as 000-000-0000 (10 chiffres). Veuillez consulter ce code.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField==Phone_TXT)
{
if (range.location == 12)
{
return NO;
}
// Backspace
if ([string length] == 0)
return YES;
if ((range.location == 3) || (range.location == 7))
{
NSString *str = [NSString stringWithFormat:@"%@-",textField.text];
textField.text = str;
}
return YES;
}
}
Swift 4 (et sans NSString)
pour format +X (XXX)XXX-XXXX ou +X (XXX)XXX-XX-XX mise à jour et légère
class ViewController: UIViewController, UITextFieldDelegate {
var myPhoneNumber = String()
@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, replacementString string: String) -> Bool {
if textField == phoneTextField {
let res = phoneMask(phoneTextField: phoneTextField, textField: textField, range, string)
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, _ string: String) -> (result: Bool, phoneNumber: String, maskPhoneNumber: String) {
let oldString = textField.text!
let newString = oldString.replacingCharacters(in: Range(range, in: oldString)!, with: string)
//in numString only Numeric characters
let components = newString.components(separatedBy: CharacterSet.decimalDigits.inverted)
let numString = components.joined(separator: "")
let length = numString.count
let maxCharInPhone = 11
if newString.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, numString, newString)
}
var indexStart, indexEnd: String.Index
var maskString = "", template = ""
var endOffset = 0
if newString == "+" { // allow add "+" if first Char
maskString += "+"
}
//format +X(XXX)XXX-XXXX
if length > 0 {
maskString += "+"
indexStart = numString.index(numString.startIndex, offsetBy: 0)
indexEnd = numString.index(numString.startIndex, offsetBy: 1)
maskString += String(numString[indexStart..<indexEnd]) + "("
}
if length > 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..<indexEnd]) + template
}
if length > 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..<indexEnd]) + template
}
var nIndex: Int; nIndex = 7
// //format +X(XXX)XXX-XX-XX -> 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..<indexEnd]) + template
// }
if length > nIndex {
indexStart = numString.index(numString.startIndex, offsetBy: nIndex)
indexEnd = numString.index(numString.startIndex, offsetBy: length)
maskString += String(numString[indexStart..<indexEnd])
}
phoneTextField.text = maskString
if length == maxCharInPhone {
//dimiss kayboard
phoneTextField.endEditing(true)
return (false, numString, newString)
}
return (false, numString, newString)
}
}
Voici mon code Swift 2 d'un point de vue britannique.
il formatera:
+11234567890 as +1 (123) 456 7890
+33123456789 as +33 1 23 45 67 89
+441234123456 as + 44 1234 123456 (ce qui a été localisé comme 01234 123456) parce que 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.
de Profiter de.
import Cocoa
extension String
{
//extension from /q/get-nth-character-of-a-string-in-swift-programming-language-74498/"+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: String) -> String
{
var countryCode = phoneNo
while countryCode.characters.count > 0 && phoneNoFormat[countryCode] == nil
{
countryCode = String(countryCode.characters.dropLast())
}
if countryCode == "0"
{
return localCountryCode!
}
return countryCode
}
func formatInternationalPhoneNo(fullPhoneNo: String, localisePhoneNo: Bool = true) -> String
{
if fullPhoneNo == ""
{
return ""
}
initInternationalPhoneFormats()
let diallingCode = getDiallingCode(fullPhoneNo)
let localPhoneNo = fullPhoneNo.stringByReplacingOccurrencesOfString(diallingCode, withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
var filteredPhoneNo = (localPhoneNo.characters.filter{["0","1","2","3","4","5","6","7","8","9"].contains("151910920")})
if filteredPhoneNo[0] == "0"
{
filteredPhoneNo.removeFirst()
}
let phoneNo:String = diallingCode + String(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)
}
My solution for +X (XXX) XXX-XXXX format. (SWIFT)
func textFieldDidBeginEditing(textField: UITextField) {
if (textField == self.mobileField) {
textField.text = "+"
}
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if (textField == self.mobileField) {
let newString = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
if (newString.characters.count < textField.text?.characters.count && newString.characters.count >= 1) {
return true // return true for backspace to work
} else if (newString.characters.count < 1) {
return false; // deleting "+" makes no sence
}
if (newString.characters.count > 17 ) {
return false;
}
let components = newString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let decimalString = components.joinWithSeparator("") as NSString
let length = decimalString.length
var index = 0
let formattedString = NSMutableString()
formattedString.appendString("+")
if (length >= 1) {
let countryCode = decimalString.substringWithRange(NSMakeRange(0, 1))
formattedString.appendString(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
}
vous pouvez appeler cette méthode chaque fois que vous avez besoin de mettre à jour votre textField:
extension String {
func applyPatternOnNumbers(pattern: String, replacmentCharacter: Character) -> String {
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 contact utilise des API non documentées. Pour une raison quelconque, attacher les formateursd'entrée aux champs de texte n'est pas exposé sur l'iPhone comme il est sur le Mac. N'hésitez pas à déposer un rapport de bogue d'amélioration de fonctionnalité.
J'espère, ce que je vais dire, sera utile pour les nouvelles personnes programmant sur iOS, comme je le suis. J'ai fait ce que zingle-dingle suggèrent (merci beaucoup!). Pour aider les nouveaux le code plus ce que je vais énumérer pourrait vous aider. 1. vous devez ajouter L'UITextFieldDelegate sur le fichier d'en-tête. 2. Le champ UITextField devrait lier le délégué avec la vue, dans mon cas le Controller UIViewController, qui est le fichier d'en-tête. 3. le champ Uitext devrait être mis en place, ça veut dire, votretextfile.delegate = self, sur l' ".m" fichier.
https://github.com/chebur/CHRTextFieldFormatter fonctionne pour moi comme un charme.
copier / coller à partir de 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 replacementString:(NSString *)string {
if (textField == self.phoneNumberTextField) {
return [self.phoneNumberFormatter textField:textField shouldChangeCharactersInRange:range replacementString:string];
} else if (textField == self.cardNumberTextField) {
return [self.cardNumberFormatter textField:textField shouldChangeCharactersInRange:range replacementString:string];
} else {
return YES;
}
}
aussi swift:
override func viewDidLoad() {
super.viewDidLoad()
self.phoneNumber.delegate = self
self.phoneNumberFormatter = CHRTextFieldFormatter(textField: self.phoneNumber, mask:CHRPhoneNumberMask())
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if textField == self.phoneNumber {
return self.phoneNumberFormatter.textField(textField, shouldChangeCharactersInRange: range, replacementString: string)
}
return true
}
voici ma solution pour le format de téléphone 05xx xxx xxxx. Au début j'ai mis
phoneTextField.delegate = self
phoneTextField.text = "05" // I don't let user to change it.
il couvre également les cas de copier/coller pour la position du curseur.
peut-être qu'il aide quelqu'un pour différents formats.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if range.location == 0 || range.location == 1 {
return false
}
var phone = (textField.text! as NSString).replacingCharacters(in: range, with: string)
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 stringToStart = text?.substring(to: (text?.index((text?.startIndex)!, offsetBy: range.location))!)
let stringToStartCount = ((stringToStart?.components(separatedBy: " ").count)! > 1) ? (stringToStart?.components(separatedBy: " ").count)!-1 : 0
var cursorIndex = range.location + string.length - stringToStartCount
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
}
Updated answer from "iOS Unit" for Swift 3 with format +X (XXX)XXX-XXXX:
func textFieldDidBeginEditing(_ textField: UITextField) {
if (textField == self.phoneTextField) {
textField.text = "+"
}
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if (textField == self.phoneTextField) {
let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
if (newString.characters.count < (textField.text?.characters.count)! && newString.characters.count >= 1) {
return true // return true for backspace to work
} else if (newString.characters.count < 1) {
return false; // deleting "+" makes no sence
}
if (newString.characters.count > 17 ) {
return false;
}
let components = newString.components(separatedBy: CharacterSet.decimalDigits.inverted)
let decimalString = components.joined(separator: "") as NSString
let length = decimalString.length
var index = 0
let formattedString = NSMutableString()
formattedString.append("+")
if (length >= 1) {
let countryCode = decimalString.substring(with: NSMakeRange(0, 1))
formattedString.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
}
vous pouvez utiliser cette bibliothèque 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
il suffit de définir votre champ text à ce controller TextInput et il formatera le texte avec le motif que vous avez défini.
ou
let phoneFormatter = TextFormatter(textPattern: "### (###) ###-##-##")
phoneFormatter.formattedText(from: "+123456789012") // +12 (345) 678-90-12
pour le format chaîne de caractères complète
vous devez le faire manuellement . prenez une notification de textField et vérifiez la longueur du texte du champ et formatez-le selon le pays. si un problème faites le moi savoir. Je l'ai fait
j'ai une solution pour cela mais elle a un inconvénient, voir si vous pouvez la modifier et l'utiliser. En utilisant ceci, vous pouvez à la fois restreindre le numéro de téléphone à 10 chiffres et le formater selon le format US.
#define MAX_LENGTH 10
implémenter it in UITextField Delegate method
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSInteger insertDelta = string.length - range.length;
if (PhoneNumber_txt.text.length + insertDelta > MAX_LENGTH)
{
return NO; // the new string would be longer than MAX_LENGTH
}
else {
range.length = 3;
range.location = 3;
PhoneNumber_txt.text = [NSString stringWithFormat:@"(%@)%@-%@", [PhoneNumber_txt.text substringToIndex:3], [PhoneNumber_txt.text substringWithRange:range], [PhoneNumber_txt.text substringFromIndex:6]];
return YES;
}
}
- (BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSCharacterSet* validationSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
NSArray* components = [string componentsSeparatedByCharactersInSet:validationSet];
if ([components count] > 1) {
return NO;
}
NSString* newString = [textField.text stringByReplacingCharactersInRange:range
withString:string];
NSArray* validComponents = [newString componentsSeparatedByCharactersInSet:validationSet];
static const int localNumberMaxLength = 7;
static const int areaCodeMaxLength = 3;
static const int countryCodeMaxLength = 2;
newString = [validComponents componentsJoinedByString:@""];
if ([newString length] > localNumberMaxLength + areaCodeMaxLength + countryCodeMaxLength) {
return NO;
}
NSLog(@"new string: %@", newString);
NSMutableString* resultString = [NSMutableString string];
NSInteger localNumberLength = MIN([newString length], localNumberMaxLength);
if (localNumberLength > 0) {
NSString* number = [newString substringFromIndex:(int)[newString length] - localNumberLength];
[resultString appendString:number];
if ([resultString length] > 3) {
[resultString insertString:@"-" atIndex:3];
}
}
if ([newString length] > localNumberMaxLength) {
NSInteger areaCodeLength = MIN((int)[newString length] - localNumberMaxLength, areaCodeMaxLength);
NSRange areaRange = NSMakeRange((int)[newString length] - localNumberMaxLength - areaCodeLength, areaCodeLength);
NSString* area = [newString substringWithRange:areaRange];
area = [NSString stringWithFormat:@"(%@) ",area];
[resultString insertString:area atIndex:0];
}
if ([newString length] > localNumberMaxLength + areaCodeMaxLength) {
NSInteger countryCodeLength = MIN((int)[newString length] - localNumberMaxLength - areaCodeMaxLength, countryCodeMaxLength);
NSRange countryCodeRange = NSMakeRange(0, countryCodeLength);
NSString* countryCode = [newString substringWithRange:countryCodeRange];
countryCode = [NSString stringWithFormat:@"+%@ ",countryCode];
[resultString insertString:countryCode atIndex:0];
}
textField.text = resultString;
return NO;
}
objective C solution for +X (XXX) XXX-XXXX format
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == objCell.txtPhone)
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if (newString.length < ([textField.text length]) && newString.length >= 1) {
return true;
} else if (newString.length < 1) {
return false;
}
if (newString.length > 15 ) {
return false;
}
NSArray *components =[newString componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]];
NSString *decimalString = [components componentsJoinedByString:@""];
NSUInteger length = decimalString.length;
NSUInteger index = 0;
NSMutableString *formattedString=[[NSMutableString alloc] init];
[formattedString appendString:@"+"];
if (length >= 1) {
NSString *countryCode = [decimalString substringWithRange:NSMakeRange(0,1)];
[formattedString appendString: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;
}
j'utilise ce format X (XXX) XXX XX XX c'est un travail en Turquie,
Je l'utilise avec TableView avec Swift 4
func formatToPhoneNumber(withPhoneTextField: UITextField, tableTextField: UITextField, range: NSRange, string: String) -> Bool {
if (tableTextField == withPhoneTextField) {
let newString = (tableTextField.text! as NSString).replacingCharacters(in: range, with: string)
let components = newString.components(separatedBy: NSCharacterSet.decimalDigits.inverted)
let decimalString = components.joined(separator: "") as NSString
let length = decimalString.length
let hasLeadingOne = length > 0 && decimalString.character(at: 0) == (1 as unichar)
if length == 0 || (length > 11 && !hasLeadingOne) || length > 12 {
let newLength = (tableTextField.text! as NSString).length + (string as NSString).length - range.length as Int
return (newLength > 11) ? false : true
}
var index = 0 as Int
let formattedString = NSMutableString()
if hasLeadingOne {
formattedString.append("1 ")
index += 1
}
if (length - index) > 1{
let zeroNumber = decimalString.substring(with: NSMakeRange(index, 1))
formattedString.appendFormat("%@ ", zeroNumber)
index += 1
}
if (length - index) > 3 {
let areaCode = decimalString.substring(with: NSMakeRange(index, 3))
formattedString.appendFormat("(%@) ", areaCode)
index += 3
}
if length - index > 3 {
let prefix = decimalString.substring(with: NSMakeRange(index, 3))
formattedString.appendFormat("%@ ", prefix)
index += 3
}
if (length - index) > 3{
let prefix = decimalString.substring(with: NSMakeRange(index, 2))
formattedString.appendFormat("%@ ", prefix)
index += 2
}
let remainder = decimalString.substring(from: index)
formattedString.append(remainder)
tableTextField.text = formattedString as String
return false
} else {
return true
}
}
et vous pouvez appeler cette func dans
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String, indexPath: IndexPath) -> Bool {
}
dans tout indexPath que votre champ de texte dans elle
par exemple mon champ Text dans indexPath numéro 1 donc le code sera
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String, indexPath: IndexPath) -> Bool {
if indexPath.row == 1 {
let phoneTextField = textField
return formatToPhoneNumber(withPhoneTextField: phoneTextField, tableTextField: textField, range: range, string: string)
}
}