UITextField for Phone Number

2020-01-24 10:54发布

I was wondering how I can format the textField that I'm using for a phone number (ie like the "Add New Contact" page on the iPhone. When I enter in a new mobile phone, ex. 1236890987 it formats it as (123) 689-0987.) I already have the keyboard set as the number pad.

24条回答
迷人小祖宗
2楼-- · 2020-01-24 11:15

Updated answer from Vikzilla for 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
    }
}
查看更多
仙女界的扛把子
3楼-- · 2020-01-24 11:15

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
    }
查看更多
狗以群分
4楼-- · 2020-01-24 11:16

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
}
查看更多
叛逆
5楼-- · 2020-01-24 11:18

Unfortunately, you have to do it yourself. The contact app uses undocumented APIs. For some reason attaching input formatters to text fields is not exposed on the iPhone the way it is on the Mac. Feel free to file a feature enhancement bug report.

查看更多
Deceive 欺骗
6楼-- · 2020-01-24 11:19

I've been struggling with this for a couple of hours, here's what I have:

- (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;
}

I hope someone can contribute.

查看更多
该账号已被封号
7楼-- · 2020-01-24 11:19

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, 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
}
查看更多
登录 后发表回答