When working with forms its is very likely that you will need to do field masking.
In this short article I want to present a small and flexible library called Veil
that allows us to do this very easily.
Veil is a pure swift library that is available through Swift Package Manager, it does not depend on UIKit and instead
is a pure string processing utility, so use on any platform with UIKit or SwiftUI.
If you're a iOS developer its very likely that you might have stumbled with this problem and might have tried solving this by implementing UITextFieldDelegate
shouldReplaceCharacters:in range
method. This is usually a painful experience as dealing with ranges is all around not that comfortable.
Veil offers a very simple solution to masking which does not require the developer to implement UITextFieldDelegate, instead can be easily
used with target action pattern.
Examples
Referring the documentation of the official repository, we can see a common example of formatting date input
into mm/yy
let dateMask = Veil(pattern: "## / ##")
let result = dateMask.mask(input: "234")
// result = "23 / 4"
So first we need to supply some masking pattern, Veil uses a default configuration (which can be replaced)
where #
represent digits while *
any character. Anything else within the pattern will be
inserted automatically into the resulting string, so typing "234" will yield "23 / 4" (including spaces).
Usage with UITextField
let dateMask = Veil(pattern: "## / ##")
@objc func textDidChange(_ sender: UITextField) {
guard let currentText = sender.text else {
return
}
sender.text = dateMask.mask(input: currentText, exhaustive: false)
}
How it works
Internally Veil parses the pattern string into an array of tokens where a Token is
enum Token {
case digit, any
case symbol(Character)
}
So a pattern like "## / ##" will result in the array of tokens:
[.digit, .digit, .symbol(" "), .symbol("/"), .symbol(" "), .digit, .digit]
It will walk through input string matching against the token pattern until either is exhausted.
This also implies you get automatic input blocking.
I encourage everyone to give this a try, and let me know you're thoughts.
Thanks!
Top comments (0)