Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
380 views
in Technique[技术] by (71.8m points)

ios - Adding space between textfield character when typing in text filed

I have a textfield with maximum character range 16, After every 4 characters, I want to add minus character or space and then writing The rest of the characters like this sample 5022-2222-2222-2222. there is my code but that's don't work, how can do this?

if textField.text?.characters.count  == 5 {

               let  l = textField.text?.characters.count
            let attributedString = NSMutableAttributedString(string: cartNumberTextField.text!)
            attributedString.addAttribute(NSKernAttributeName, value: CGFloat(4.0), range: NSRange(location: l!, length: 4))
            cartNumberTextField.attributedText = attributedString

            }

            else if textField.text?.characters.count  == 9 {

                let  l = textField.text?.characters.count
                let attributedString = NSMutableAttributedString(string: cartNumberTextField.text!)
                attributedString.addAttribute(NSKernAttributeName, value: CGFloat(4.0), range: NSRange(location: l!, length: 4))
                cartNumberTextField.attributedText = attributedString

            }

            else if textField.text?.characters.count  == 13 {

                let  l = textField.text?.characters.count
                let attributedString = NSMutableAttributedString(string: cartNumberTextField.text!)
                attributedString.addAttribute(NSKernAttributeName, value: CGFloat(4.0), range: NSRange(location: l!, length: 4))
                cartNumberTextField.attributedText = attributedString

            }

I am adding this code in UITextField shouldChangeCharactersIn range method.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

We may start by implementing a Swift 3 version of the chunk(n:) method (for Collection's) of oisdk:s SwiftSequence:

/* Swift 3 version of Github use oisdk:s SwiftSequence's 'chunk' method:
   https://github.com/oisdk/SwiftSequence/blob/master/Sources/ChunkWindowSplit.swift */
extension Collection {
    public func chunk(n: IndexDistance) -> [SubSequence] {
        var res: [SubSequence] = []
        var i = startIndex
        var j: Index
        while i != endIndex {
            j = index(i, offsetBy: n, limitedBy: endIndex) ?? endIndex
            res.append(self[i..<j])
            i = j
        }
        return res
    }
}

In which case implementing your custom formatting is a simple case of creating 4-character chunks and joining these by "-":

func customStringFormatting(of str: String) -> String {
    return str.characters.chunk(n: 4)
        .map{ String($0) }.joined(separator: "-")
}

Example usage:

print(customStringFormatting(of: "5022222222222222")) // 5022-2222-2222-2222
print(customStringFormatting(of: "50222222222222"))   // 5022-2222-2222-22
print(customStringFormatting(of: "5022222"))          // 5022-222

If applying to be used in the textField(_:shouldChangeCharactersIn:replacementString:) method of UITextFieldDelegate, we might want to filter out existing separators in the customStringFormatting(of:) method method, as well as implementing it as a String extension:

extension String {
    func chunkFormatted(withChunkSize chunkSize: Int = 4, 
        withSeparator separator: Character = "-") -> String {
        return characters.filter { $0 != separator }.chunk(n: chunkSize)
            .map{ String($0) }.joined(separator: String(separator))
    }
}

And implement the controlled updating of the textfield e.g. as follows:

let maxNumberOfCharacters = 16

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    // only allow numerical characters
    guard string.characters.flatMap({ Int(String($0)) }).count ==
        string.characters.count else { return false }

    let text = textField.text ?? ""

    if string.characters.count == 0 {
        textField.text = String(text.characters.dropLast()).chunkFormatted()
    }
    else {
        let newText = String((text + string).characters
            .filter({ $0 != "-" }).prefix(maxNumberOfCharacters))
        textField.text = newText.chunkFormatted()
    }
    return false
}

The last part above will truncate possible pasted strings from the user (given that it's all numeric), e.g.

// current 
1234-1234-123

// user paste:
777777777
  /* ^^^^ will not be included due to truncation */  

// will result in
1234-1234-1237-7777

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...