Columbina 的掩码格式化器

example workflow

一个完全可定制的格式化器,用于为文本创建掩码。

let mask = "##/$$-@@"

let rules = [
    MaskedFormatter.Rule(maskCharacter: "#", validation: { $0.isNumber }),
    MaskedFormatter.Rule(maskCharacter: "$", validation: { $0.isLetter }),
    MaskedFormatter.Rule(maskCharacter: "@", validation: { (Int(String($0)) ?? 0) >= 5 })
]

let maskedFormatter = MaskedFormatter(mask: mask, rules: rules)

let input = "123ABC456"
let output = maskedFormatter.string(for: input)

print(output!)
// "12/AB-56"

快速开始

1. 导入模块

import MaskedFormatter

2. 定义一个掩码

例如,一个“到期日期”掩码,通常用于信用卡表格,可以这样定义

let mask = "##/##"

3. 定义规则

使用相同的“到期日期”掩码示例,我们的规则将如下所示

let rule = MaskedFormatter.Rule(maskCharacter: "#", validation: { $0.isNumber })

4. 初始化一个 MaskedFormatter

let maskedFormatter = MaskedFormatter(mask: mask, rules: [rule])

5. 应用格式化器

let input = "1234"
let output = maskedFormatter.string(for: input)
print(output!)
// "12/34"

提示

创建您自己的格式化器

例如,通过继承 MaskedFormatter

class CreditCardFormatter: MaskedFormatter {
    init() {
        let mask = "#### #### #### ####"
        let rule = MaskedFormatter.Rule(maskCharacter: "#", validation: { $0.isNumber })
        super.init(mask: mask, rules: [rule])
    }
    ...
}

应用于 UITextField

通过监听 textfield 中的更改来“实时”掩码 UITextField

let textField = UITextField()
textField.addTarget(self, 
                    action: #selector(textFieldDidChange(_:)),
                    for: .editingChanged)

...
@objc func textFieldDidChange(_ textField: UITextField) {
    textField.text = maskedFormatter.string(for: textField.text)
}

应用于 SwiftUI 的 TextField

通过 onChange “实时”掩码 TextField

@State var text: String
...
TextField(placeholder, text: $text)
    .onChange(of: text) { value in
        text = maskedFormatter.string(for: text) ?? ""
    }

更多细节

规则

MaskedFormatter.Rule(maskCharacter: Character, validation: @escaping (Character) -> Bool)

规则会告诉格式化器,掩码中的哪些字符应该被什么(字母、数字等)替换。在我们的“到期日期”掩码示例 (##/##) 中,我们有两个不同的字符,#/。 我们想要替换 #,因此我们将为该字符创建一个规则。

MaskedFormatter.Rule(maskCharacter: "#", validation: { ... })

为了判断哪个输入对该特定字符有效,我们使用验证参数。此参数接收一个 Character 并返回一个 Bool

MaskedFormatter.Rule(maskCharacter: "#", validation: { (char: Character) -> Bool in
    ...
})

在我们的例子中,我们希望用一个数字替换 # 字符,所以我们可以检查 char 并查看它是否是一个数字

MaskedFormatter.Rule(maskCharacter: "#", validation: { (char: Character) -> Bool in
    char.isNumber
})

现在我们可以在一个或多个 MaskedFormatter 中使用此规则

let rule = MaskedFormatter.Rule(maskCharacter: "#", validation: { $0.isNumber })
let formatter1 = MaskedFormatter(mask: "##", rules: [rule])
let formatter2 = MaskedFormatter(mask: "#/#", rules: [rule])