在文本字段中键入时在文本字符之间添加空格

时间:2016-12-03 09:15:06

标签: ios swift uitextfield

我有一个textfield,最大字符数为16,每4个字符后,我想添加减去字符或空格,然后写下其余的字符,如此样本5022-2222-2222-2222。 有我的代码,但这不起作用,怎么办呢?

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

            }

我在UITextField shouldChangeCharactersIn范围方法中添加了此代码。

3 个答案:

答案 0 :(得分:7)

我们可以首先实现oisdk:chunk(n:) methodSwiftSequenceCollection)的Swift 3版本:

/* 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
    }
}

在这种情况下,实现自定义格式是一个简单的例子,即创建4个字符的块并通过“ - ”连接它们:

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

使用示例:

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

如果要申请在UITextFieldDelegate customStringFormatting(of:)方法中使用,我们可能希望在String方法方法中过滤掉现有的分隔符,并将其作为{{{ 1}}扩展名:

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))
    }
}

实现文本字段的受控更新,例如如下:

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
}

上面的最后一部分将截断用户可能粘贴的字符串(假设它都是数字),例如

// current 
1234-1234-123

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

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

答案 1 :(得分:5)

像这样使用shouldChangeCharactersIn

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if [6, 11, 16].contains(textField.text?.count ?? 0) && string.isEmpty {
        textField.text = String(textField.text!.dropLast())
        return true
    }
    let text = NSString(string: textField.text ?? "").replacingCharacters(in: range, with: string).replacingOccurrences(of: "-", with: "")
    if text.count >= 4 && text.count <= 16 {
        var newString = ""
        for i in stride(from: 0, to: text.count, by: 4) {
            let upperBoundIndex = i + 4
            let lowerBound = String.Index.init(encodedOffset: i)
            let upperBound = String.Index.init(encodedOffset: upperBoundIndex)
            if upperBoundIndex <= text.count  {
                newString += String(text[lowerBound..<upperBound]) + "-"
                if newString.count > 19 {
                   newString = String(newString.dropLast())
                }
            }
            else if i <= text.count {
                newString += String(text[lowerBound...])
            }
        }
        textField.text = newString
        return false
    }
    if text.count > 16 {
        return false
    }
    return true
}

注意:我使用了- (Hyphen)如果您想要Space而不是Space,只需将其替换为- (Hyphen)

编辑:代码编辑为最​​新的swift 4. *,对于较旧的swift版本,请检查编辑历史记录。

答案 2 :(得分:0)

要“即时”执行此操作,我将Editing更改为此IBAction;还需要注意退格

 @IBAction func editingTestField(_ sender: UITextField) {
      if sender.text!.count > 0 && sender.text!.count % 5 == 0 && sender.text!.last! != "-" {
         sender.text!.insert("-", at:sender.text!.index(sender.text!.startIndex, offsetBy: sender.text!.count-1) )
      }
 }