在Swift中对textField进行遮罩处理

9

我应该如何在Swift中为文本字段设置掩码?例如,当用户输入电话号码时,它应该显示为电话格式。就像Objective-C中的这个代码:

self.textField.mask = @"(##)####-####";
3个回答

10

Swift 4&&5 非常简单的电话号码掩码

您必须将此代码用作文本字段委托。

 func formattedNumber(number: String) -> String {
                 let cleanPhoneNumber = number.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
                 let mask = "## ### ###"
                 var result = ""
                 var index = cleanPhoneNumber.startIndex
                 for ch in mask! where index < cleanPhoneNumber.endIndex {
                     if ch == "#" {
                         result.append(cleanPhoneNumber[index])
                         index = cleanPhoneNumber.index(after: index)
                     } else {
                         result.append(ch)
                     }
                 }
                 return result
             }
             func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string:  String) -> Bool {
                 guard let text = textField.text else { return false }
                 let newString = (text as NSString).replacingCharacters(in: range, with: string)
                 textField.text = formattedNumber(number: newString)
                 return false
             }

1
请注意 - 您必须将此代码用作文本字段委托。 - Chuck Krutsinger

8

Swift 4非常简单,支持掩码最大文本字段长度和处理退格键

 //MARK: - text field masking
internal func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    //MARK:- If Delete button click
    let  char = string.cString(using: String.Encoding.utf8)!
    let isBackSpace = strcmp(char, "\\b")

    if (isBackSpace == -92) && (textField.text?.count)! > 0 {
        print("Backspace was pressed")
        textField.text!.removeLast()
        return false
    }

    if textField == txtworkphone
    {
        if (textField.text?.count)! == 3
        {
            textField.text = "(\(textField.text!)) "  //There we are ading () and space two things
        }
        else if (textField.text?.count)! == 9
        {
            textField.text = "\(textField.text!)-" //there we are ading - in textfield
        }
        else if (textField.text?.count)! > 13
        {
            return false
        }
    }
}

这个好像不起作用,可能是我写错了,在ViewDidLoad函数结束后写的。你能详细解释一下吗? - RiTeSh
朋友,这是委托方法。在didLoad方法中使用您的textfield委托,如textfield.delegates = self,它将被调用。还应该提到UITextFieldDelegate。 - Shakeel Ahmed
如果有人只是复制粘贴这个答案,请注意...在textField.text!.removeLast()这一行之前,加上一个if text.count > 0的验证,否则如果用户在空文本框上点击退格键,它将会崩溃。 - rickrvo

2
这样,您就可以在Swift中创建电话掩码。首先,为String类型创建一个巧妙的扩展。下标获取索引处的字符,函数从int获取String.Index类型。
extension String {  
subscript (i: Int) -> String {

    if countElements(self) > i {

        return String(Array(self)[i])
    }

    return ""
}

func indexAt(theInt:Int)->String.Index {

    return advance(self.startIndex, theInt)
    }
}

这是在您的电话号码输入字段中调用的函数:

func returnMaskedPhoneField(thePhoneText:String)->String{

    var returnString = thePhoneText

    //Trims non-numerical characters
    returnString = returnString.stringByTrimmingCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
    //Removes all spaces
    returnString = returnString.stringByReplacingOccurrencesOfString(" ", withString: "")

    //Checks if we need to format a mobile number
    if thePhoneText[1] == "4"{

        if countElements(returnString) > 7 {

            returnString = returnString.stringByReplacingCharactersInRange(Range<String.Index>(start: returnString.indexAt(7), end: returnString.indexAt(7)), withString: " ")


        }

        if countElements(returnString) > 4 {

            returnString = returnString.stringByReplacingCharactersInRange(Range<String.Index>(start: returnString.indexAt(4), end: returnString.indexAt(4)), withString: " ")
        }

    }else {

        if countElements(returnString) > 6 {

            returnString = returnString.stringByReplacingCharactersInRange(Range<String.Index>(start: returnString.indexAt(6), end: returnString.indexAt(6)), withString: " ")


        }

        if countElements(returnString) > 2 {

            returnString = returnString.stringByReplacingCharactersInRange(Range<String.Index>(start: returnString.indexAt(2), end: returnString.indexAt(2)), withString: " ")
        }

    }

    return returnString
}

接下来是实现函数的地方,将以下代码放在你的viewDidLoad方法中:

aTextField.delegate = self  
aTextField.addTarget(self, action: "validateTextFields:", forControlEvents: UIControlEvents.EditingChanged)

还有一个在你的类中的某个位置,它是你的textfield代理:

func validateTextFields(sender:AnyObject){

    if let textField = sender as? UITextField {

        if textField == aTextField {

            if let currentCurserPosition = aTextField?.selectedTextRange {

                var isEndOfString = false

                let currentCurserPositionInteger = textField.offsetFromPosition(textField.beginningOfDocument, toPosition: currentCurserPosition.start)

                if currentCurserPositionInteger == count(textField.text){

                    isEndOfString = true
                }

                aTextField?.text = returnMaskedPhoneField(textField.text)

                if isEndOfString == false {
                    aTextField?.selectedTextRange = currentCurserPosition
                }

            }else {

                aTextField?.text = returnMaskedPhoneField(textField.text)
            }
        }
    }
}

它将像这样工作:

enter image description here

致谢:

http://pjeremymalouf.com/creating-a-text-mask-in-swift/

如果您想使用自定义的textField,则可以使用AKMaskField

在那里,您可以找到像这样的电话textField

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接