Library / SDK
RedMadRobot/input-mask-ios avatar
RedMadRobot/input-mask-ios

InputMask: masking and formatting text fields on iOS

User input masking library repo.

590 stars96 forksSwiftMIT

At a glance

What is it?
InputMask is a Swift library that formats text field input as the user types, filtering out unwanted characters and guessing the country for international phone numbers, with a pattern language, SwiftUI and macOS support. Its most instructive feature is the list of known issues it publishes, because the delegate design has consequences you have to work around.
Who is it for?
Adopt InputMask if you have iOS forms with phone numbers, card numbers, dates or other fixed formats where a mask is better than validation after the fact, and you are willing to work around the delegate behaviour it documents. Do not adopt it if you rely on UITextFieldTextDidChange notifications, on the cut action, or on wiring a masked delegate from a storyboard with Carthage, because each of those has a known issue with a workaround rather than a fix.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 81 days ago.
What is it written in?
Mainly Swift, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Formatting as a side effect of typing

Input masks restrict data input and allow you to guide users to enter correct values. That sentence is the whole product, and it is a different approach from validating a field after the user has finished with it.

The distinction matters because of where the error surfaces. A validator that runs on blur tells a user they got the format wrong after they have already typed it, and the fix means retyping. A mask changes what can be typed in the first place, so the invalid state never exists. The features list puts it as applying formatting to your text fields, and filtering out nonessential symbols, with the example of extracting 0123456 from +1 (999) 012-34-56.

The pattern language is the mechanism. The examples in the readme are compact:

And the mask patterns themselves are written as templates, with phone numbers as `+1 ([000]) [000] [00] [00]`, dates as `[00]{.}[00]{.}[9900]`, serial numbers as `[AA]-[00000099]`, IPv4 as `[099]{.}[099]{.}[099]{.}[099]`, Visa or MasterCard numbers as `[0000] [0000] [0000] [0000]`, and a UK IBAN as `GB[00] [____] [0000] [0000] [0000] [00]`.

The syntax is worth reading closely because it does the work of describing both what is allowed and what the display looks like. Square brackets are fixed placeholders, the characters inside them say what may be typed there, and the braces group optional segments, which is how the date mask can accept a two digit or four digit year. The dots and spaces in the pattern are literal separators that appear in the output.

The library is Swift, MIT licensed, and published as InputMask on CocoaPods at version 7.3.2, with Swift Package Manager and manual installation also supported.

Phone numbers, and guessing the country

The international phone number handling is the feature that distinguishes this from a generic mask library, and it is the one that changes how you design the screen around it.

For international phone numbers, the library guesses the country from the entered digits and then applies the corresponding value restrictions, with a US phone having a format like +1 201 456-7890. That is a two stage behaviour rather than a single mask. A fixed mask cannot express a country code that the user chooses at runtime, so the country has to be inferred from what is typed and the mask then adapts to it.

That inference is what makes the library more useful than a fixed pattern, and it is also what makes it harder to reason about, because the format of the field changes under the user as they type. The consequence for an app is that the placeholder and the allowed length are not static, and a validation message that says the number is 10 digits long may be wrong depending on the country that was detected.

Alongside the phone handling there is number and currency formatting, which is a separate capability from masking. Currency formatting is a display concern, and the readme does not say whether it is applied on input or on output, so it is worth checking the wiki before assuming it behaves like the masks.

The remaining feature list is small. SwiftUI support and macOS support are both present, and the repository carries a .spi.yml, which is the Swift Package Index manifest, and an InputMask.podspec, so the library is distributed through both of the usual channels for Swift. The Android counterpart is a separate repository, and the Telegram contact in the badges is the maintainer.

The known issues are the real documentation

What makes this repository unusual is that it publishes a detailed known issues section, and those entries are the part worth reading before you adopt the library.

The first one is the delegate and notification behaviour. A UITextField with an assigned MaskedTextFieldDelegate object will not issue UITextFieldTextDidChange notifications or editingChanged control events. The cause is given precisely: it happens because of the textField(_:shouldChangeCharactersIn:replacementString:) method implementation, which always returns false.

That single design decision explains all three issues. The delegate returns false because the library is in full control of what ends up in the field, and the mask is what decides that. The consequence is that the normal notification path is cut off, and the readme provides a workaround subclass that overrides the method, calls super, and fires a listener in a defer block. The advice at the end is to avoid at all costs sending SDK events and notifications manually, which is a sensible instruction because the library already sets the text and sending events again would double-apply the change.

The second issue is Carthage and Interface Builder. Interface Builder struggles to support modules imported in the form of a dynamic framework, so custom views annotated as IBDesignable, containing IBInspectable and IBOutlet fields, are not recognized properly from a dragged and dropped framework. The practical effect is that if you build with Carthage as a dynamic framework you will not be able to easily wire your MaskedTextFieldDelegate objects and their listeners from storyboards. The readme links workarounds in the Carthage issue tracker and suggests filing a radar with Apple.

The third issue is the cut action. When you cut text, the characters get deleted but you cannot paste them, because they were never in the pasteboard. The reason is that iOS hardwires the UIMenuController cut action to the delegate's shouldChangeCharactersIn return value, so cut behaviour depends on the ability to edit the text, and this library returns false and heavily depends on that. The readme is honest that changing it would require rewriting a lot of logic with no guarantee it could be done, and that there is no distinct way to tell a cut selection from a delete selection on the delegate side.

The readme asks you to look at the known issues before incorporating the library, and for a component that rewrites text on every keystroke that advice is well placed.

Installing it, and where the documentation lives

There are three installation routes and they differ in more than convenience.

Swift Package Manager is the first, and the package dependency is declared as:

swift
dependencies: [
    .Package(url: "https://github.com/RedMadRobot/input-mask-ios", majorVersion: 7)
]

The repository is pointed at The major version pin is the useful detail, because the readme elsewhere warns that the library's delegate behaviour and the known issues are part of its design, so a major version bump is likely to mean more than an additive change.

CocoaPods is the second, with the pod named InputMask, and the CocoaPods badge shows version 7.3.2. The 7.3.2 release is titled as a macOS release, which tells you the macOS support was a late addition to an iOS-first library.

Manual installation is the third and it is spelled out in numbered steps. You git clone the repository, add InputMask.xcodeproj into your project or workspace, go to your target settings and add InputMask.framework under the Embedded Binaries section, and for Objective-C projects there is an extra step, namely that on roughly Xcode 8.x you make sure Build Options has Embedded Content Contains Swift Code enabled, and that you import a bridging header. That is a fair amount of manual work for a library with a Swift Package Manager manifest, and it is the route you take only when your build setup requires it.

The documentation itself is a wiki rather than a set of markdown files, and the readme points there for the quick start and further reading. There is also a Documentation directory in the repository with an Assets folder holding the logo, and a Source directory with the implementation.

For support, the readme points at the issue tracker for bug reports and feature requests, and at StackOverflow with the input-mask tag for questions, and suggests searching the closed issues first. The repository also has a CHANGELOG, a CONTRIBUTING guide, a Travis configuration and a GitHub Actions workflow for Swift, so it is still being built even though the last tagged release is from 2023.

Editorial conclusion

Adopt InputMask if you have iOS forms with phone numbers, card numbers, dates or other fixed formats where a mask is better than validation after the fact, and you are willing to work around the delegate behaviour it documents. Do not adopt it if you rely on UITextFieldTextDidChange notifications, on the cut action, or on wiring a masked delegate from a storyboard with Carthage, because each of those has a known issue with a workaround rather than a fix. Before you commit, read the known issues section in full, decide between CocoaPods, Swift Package Manager and manual embedding, and check the changelog, since the last tagged release is 7.3.2 from July 2023.

Frequently asked questions

What does the InputMask library do for iOS?

It restricts data input and guides users to enter correct values by formatting text fields as they type and filtering out nonessential symbols, with the readme's example of extracting 0123456 from +1 (999) 012-34-56. It also supports number and currency formatting, SwiftUI and macOS.

How are InputMask patterns written?

As templates with square brackets for fixed placeholders whose contents say what may be typed, and braces for optional groups. The readme gives phone numbers as +1 ([000]) [000] [00] [00], dates as [00]{.}[00]{.}[9900], serial numbers as [AA]-[00000099], IPv4 as [099]{.}[099]{.}[099]{.}[099], card numbers as [0000] [0000] [0000] [0000] and a UK IBAN as GB[00] [____] [0000] [0000] [0000] [00].

How does InputMask handle international phone numbers?

It guesses the country from the entered digits and then applies the corresponding value restrictions, so a US phone gets a format like +1 201 456-7890. That means the allowed format of the field changes as the country is detected, rather than being fixed by a single static mask.

What are the known issues with InputMask?

A UITextField with a MaskedTextFieldDelegate will not issue UITextFieldTextDidChange notifications or editingChanged events, because the delegate method always returns false, and a subclass workaround is provided. With Carthage and Interface Builder you cannot easily wire the delegate and its listeners from storyboards. And the cut action deletes the characters without putting them in the pasteboard, because iOS ties the cut action to that same delegate return value.

How do I install InputMask in an iOS project?

Through Swift Package Manager with the package dependency at major version 7, through CocoaPods with the pod named InputMask, or manually by cloning the repository, adding InputMask.xcodeproj to your project, adding InputMask.framework under Embedded Binaries in the target settings, and for Objective-C projects enabling Embedded Content Contains Swift Code and importing a bridging header.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. RedMadRobot/input-mask-ios on GitHub
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/redmadrobot-input-mask-ios.svg)](https://hysenlabs.com/projects/redmadrobot-input-mask-ios)

Was this useful?