Formatting a UITextField for credit card input like (xxxx xxxx xxxx xxxx)

前端 未结 28 2171
长情又很酷
长情又很酷 2020-11-28 01:19

I want to format a UITextField for entering a credit card number into such that it only allows digits to be entered and automatically inserts spaces so that the

28条回答
  •  生来不讨喜
    2020-11-28 01:52

    Here's a swift copy of the accepted answer in case somebody needs it. It is basically a wrapper class. I haven't spent too much time on optimising it, but it's ready for use.

    var creditCardFormatter : CreditCardFormatter
    {
        return CreditCardFormatter.sharedInstance
    }
    
    class CreditCardFormatter : NSObject
    {
        static let sharedInstance : CreditCardFormatter = CreditCardFormatter()
    
        func formatToCreditCardNumber(textField : UITextField, withPreviousTextContent previousTextContent : String?, andPreviousCursorPosition previousCursorSelection : UITextRange?)
        {
            if let selectedRangeStart = textField.selectedTextRange?.start, textFieldText = textField.text
            {
                var targetCursorPosition : UInt = UInt(textField.offsetFromPosition(textField.beginningOfDocument, toPosition: selectedRangeStart))
    
                let cardNumberWithoutSpaces : String = removeNonDigitsFromString(textFieldText, andPreserveCursorPosition: &targetCursorPosition)
    
                if cardNumberWithoutSpaces.characters.count > 19
                {
                    textField.text = previousTextContent
                    textField.selectedTextRange = previousCursorSelection
                    return
                }
    
                let cardNumberWithSpaces : String = insertSpacesIntoEvery4DigitsIntoString(cardNumberWithoutSpaces, andPreserveCursorPosition: &targetCursorPosition)
    
                textField.text = cardNumberWithSpaces
    
                if let finalCursorPosition = textField.positionFromPosition(textField.beginningOfDocument, offset: Int(targetCursorPosition))
                {
                    textField.selectedTextRange = textField.textRangeFromPosition(finalCursorPosition, toPosition: finalCursorPosition)
                }
            }
        }
    
        func removeNonDigitsFromString(string : String,inout andPreserveCursorPosition cursorPosition : UInt) -> String
        {
            var digitsOnlyString : String = ""
    
            for index in 0.stride(to: string.characters.count, by: 1)
            {
                let charToAdd : Character = Array(string.characters)[index]
    
                if isDigit(charToAdd)
                {
                    digitsOnlyString.append(charToAdd)
                }
                else
                {
                    if index < Int(cursorPosition)
                    {
                        cursorPosition -= 1
                    }
                }
            }
    
            return digitsOnlyString
        }
    
        private func isDigit(character : Character) -> Bool
        {
            return "\(character)".containsOnlyDigits()
        }
    
        func insertSpacesIntoEvery4DigitsIntoString(string : String, inout andPreserveCursorPosition cursorPosition : UInt) -> String
        {
            var stringWithAddedSpaces : String = ""
    
            for index in 0.stride(to: string.characters.count, by: 1)
            {
                if index != 0 && index % 4 == 0
                {
                    stringWithAddedSpaces += " "
    
                    if index < Int(cursorPosition)
                    {
                        cursorPosition += 1
                    }
                }
    
                let characterToAdd : Character = Array(string.characters)[index]
    
                stringWithAddedSpaces.append(characterToAdd)
            }
    
            return stringWithAddedSpaces
        }
    
    }
    
    extension String
    {
        func containsOnlyDigits() -> Bool
        {
            let notDigits : NSCharacterSet = NSCharacterSet.decimalDigitCharacterSet().invertedSet
    
            if (rangeOfCharacterFromSet(notDigits, options: NSStringCompareOptions.LiteralSearch, range: nil) == nil)
            {
                return true
            }
    
            return false
        }
    }
    

提交回复
热议问题