• Stars
    star
    572
  • Rank 75,011 (Top 2 %)
  • Language
    Swift
  • License
    MIT License
  • Created over 7 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

User input masking library repo.

Input Mask

Pod Version Badge Awesome Actions Android Telegram license

Input masks restrict data input and allow you to guide users to enter correct values.
Check out our wiki for quick start and further reading.

⚙️ Features

  • Apply formatting to your text fields, see examples
  • Filter out nonessential symbols (e.g. extract 0123456 from +1 (999) 012-34-56)
  • For international phone numbers
    • guess the country from the entered digits
    • apply corresponding value restrictions (e.g. a 🇺🇸US phone will have a format like +1 201 456-7890)
  • Apply number/currency formatting
  • SwiftUI support
  • macOS support
  • Phone numbers: +1 ([000]) [000] [00] [00]
  • Dates: [00]{.}[00]{.}[9900]
  • Serial numbers: [AA]-[00000099]
  • IPv4: [099]{.}[099]{.}[099]{.}[099]
  • Visa/MasterCard numbers: [0000] [0000] [0000] [0000]
  • UK IBAN: GB[00] [____] [0000] [0000] [0000] [00]

Swift Package Manager

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

CocoaPods

pod 'InputMask'

Manual

  1. git clone this repository;
  2. Add InputMask.xcodeproj into your project/workspace;
  3. Go to your target's settings, add InputMask.framework under the Embedded Binaries section
  4. For ObjC projects:
    • (~Xcode 8.x) make sure Build Options has Embedded Content Contains Swift Code enabled;
    • import bridging header.

📢 Communication, Questions & Issues

Please take a closer look at our Known issues section before you incorporate our library into your project.

For your bugreports and feature requests please file new issues via GitHub.

Should you have any questions, please search for closed issues or ask questions at StackOverflow with the input-mask tag.

UITextFieldTextDidChange notification and target-action editingChanged event

UITextField with assigned MaskedTextFieldDelegate object won't issue UITextFieldTextDidChange notifications and editingChanged control events. This happens due to the textField(_:shouldChangeCharactersIn:replacementString:) method implementation, which always returns false.

Consider using following workaround in case if you do really need to catch editing events:

class NotifyingMaskedTextFieldDelegate: MaskedTextFieldDelegate {
    weak var editingListener: NotifyingMaskedTextFieldDelegateListener?
    
    override func textField(
        _ textField: UITextField,
        shouldChangeCharactersIn range: NSRange,
        replacementString string: String
    ) -> Bool {
        defer {
            self.editingListener?.onEditingChanged(inTextField: textField)
        }
        return super.textField(textField, shouldChangeCharactersIn: range, replacementString: string)
    }
}


protocol NotifyingMaskedTextFieldDelegateListener: class {
    func onEditingChanged(inTextField: UITextField)
}

Please, avoid at all costs sending SDK events and notifications manually.

Carthage vs. IBDesignables, IBInspectables, views and their outlets

Interface Builder struggles to support modules imported in a form of a dynamic framework. For instance, custom views annotated as IBDesignable, containing IBInspectable and IBOutlet fields aren't recognized properly from the drag'n'dropped *.framework.

In case you are using our library as a Carthage-built dynamic framework, be aware you won't be able to easily wire your MaskedTextFieldDelegate objects and their listeners from storyboards in your project. There is a couple of workarounds described in the corresponding discussion, though.

Also, consider filing a radar to Apple, like this one.

Cut action doesn't put text into the pasteboard

When you cut text, characters get deleted yet you won't be able to paste them somewhere as they aren't actually in your pasteboard.

iOS hardwires UIMenuController's cut action to the UITextFieldDelegate's textField(_:shouldChangeCharactersIn:replacementString:) return value. This means "Cut" behaviour actually depends on the ability to edit the text.

Bad news are, our library returns false in textField(_:shouldChangeCharactersIn:replacementString:), and heavily depends on this false. It would require us to rewrite a lot of logic in order to change this design, and there's no guarantee we'll be able to do so.

Essentially, there's no distinct way to differentiate "Cut selection" and "Delete selection" actions on the UITextFieldDelegate side. However, you may consider using a workaround, which will require you to subclass UITextField overriding its cut(sender:) method like this:

class UITextFieldMonkeyPatch: UITextField {
    override func cut(_ sender: Any?) {
        copy(sender)
        super.cut(sender)
    }
}

From our library perspective, this looks like a highly invasive solution. Thus, in the long term, we are going to investigate a "costly" method to bring the behaviour matching the iOS SDK logic. Yet, here "long term" might mean months.

Incorrect cursor position after pasting

Shortly after new text is being pasted from the clipboard, every UITextInput receives a new value for its selectedTextRange property from the system. This new range is not consistent with the formatted text and calculated caret position most of the time, yet it's being assigned just after set caretPosition call.

To ensure correct caret position is set, it might be assigned asynchronously (presumably after a vanishingly small delay), if caret movement is set to be non-atomic; see MaskedTextFieldDelegate.atomicCursorMovement property.

MaskedTextInputListener

In case you are wondering why do we have two separate UITextFieldDelegate and UITextViewDelegate implementations, the answer is simple: prior to iOS 11 UITextField and UITextView had different behaviour in some key situations, which made it difficult to implement common logic.

Both had the same bug with the UITextInput.beginningOfDocument property, which rendered impossible to use the generic UITextInput protocol UITextField and UITextView have in common.

Since iOS 11 most of the things received their fixes (except for the UITextView edge case). In case your project is not going to support anything below 11, consider using the modern MaskedTextInputListener.

🙏 Special thanks

These folks rock:

The library is distributed under the MIT LICENSE.

More Repositories

1

input-mask-android

User input masking library repo.
Kotlin
1,212
star
2

figma-export

Command line utility to export colors, typography, icons and images from Figma to Xcode / Android Studio project
Swift
684
star
3

Chronos

Android library that handles asynchronous jobs.
Java
134
star
4

state-delegator

Collection of classes that helps you to manage a screen state.
Kotlin
132
star
5

kotlin-style-guide

red_mad_robot Kotlin Style Guide
87
star
6

PINkman

PINkman is a library to help implementing an authentication by a PIN code in a secure manner. The library derives hash from the user's PIN using Argon2 function and stores it in an encrypted file. The file is encrypted with the AES-256 algorithm in the GCM mode and keys are stored in the AndroidKeystore.
Kotlin
84
star
7

DAO

Swift
74
star
8

flipper

Flipper is a simple and useful tool to deal with feature toggles
Kotlin
69
star
9

RMRColorTools-iOS

Objective-C
67
star
10

gradle-version-catalogs

Version catalogs used in red_mad_robot Android team
Kotlin
57
star
11

catbird

Mock server for UI tests
Swift
50
star
12

edge-to-edge-decorator

Edge to edge decorator - is a utility class that is responsible for coloring the statusBar and navigationBar to maintain edge to edge (e2e) mode.
Kotlin
47
star
13

apexy-ios

The library for organizing a network layer in your awesome project.
Swift
44
star
14

NeumorphicWallet

💳 Neumorphic Wallet app concept in SwiftUI
Swift
43
star
15

PrioritizedTabBar

📱 Native iOS TabBar with prioritized layout
Swift
42
star
16

gradle-infrastructure

Set of small plugins to reduce boilerplate in Gradle build scripts.
Kotlin
41
star
17

omega-bank-ios

The Bank you really need.
Swift
28
star
18

redmadrobot-android-ktx

Missing Android KTX extensions.
Kotlin
27
star
19

figmiro-plugin

Figma Integration with Miro (Plugin)
TypeScript
26
star
20

Alarm-Clock

⏰ Alarm Clock / Proof of concept for our Colored Alarm Clock Interface shot @ Dribbble
Swift
26
star
21

perspective-animation-ios

Example of perspective photo animation from camera
Swift
22
star
22

mapmemory

Simple in-memory cache conception built on Map.
Kotlin
21
star
23

acronym-avatar

Library to show avatars with acronyms.
Kotlin
18
star
24

ACSlider

🎚 A slider displaying selected value
Swift
16
star
25

fastlane-plugin-jira_release_notes

Fastlane Plugin for Jira Release Notes
Ruby
14
star
26

synopsis

Swift source code scanner.
Swift
13
star
27

itemsadapter

The simple adapter to render static data in RecyclerView
Kotlin
13
star
28

golden-key

Security framework compatible with CryptoKit
Swift
12
star
29

android-mad-showcase

Welcome to Modern Android Development (MAD) Showcase, the Android application following modern practices: Kotlin, Coroutines, Flow, Compose, GraphQL etc
Kotlin
11
star
30

VolumeButtons

VolumeButtons provides interface for handle clicks on hardware volume buttons on iOS devices
Swift
10
star
31

navidux

Swift
10
star
32

DAO-generator

Swift
10
star
33

AndroidStudioTemplates

Templates for android studio
FreeMarker
9
star
34

android-docker-images

Docker images used in red_mad_robot Android team
Shell
8
star
35

fastlane-plugin-gmail

Fastlane Plugin for Gmail
Ruby
7
star
36

rmr_django

Template Django project
Python
7
star
37

http-transport

Synchronous HTTP transport library.
Swift
7
star
38

figmiro-server

This is proxy server for Figmiro plugin that works with Miro's REST API
TypeScript
6
star
39

debug-panel-android

Library for easy application debugging
Kotlin
5
star
40

autograph

Swift source code generation kit.
Swift
5
star
41

FitnessAppWithDynamicIsland

Demo app designed to demostrate the capabilities of the new Apple Dynamic Island.
Swift
5
star
42

frontend-robopractice-test-task

HTML
5
star
43

use-dropdown

HTML
4
star
44

FitnessDynamicIsland

Swift
4
star
45

service-autograph

Service generation utility.
Swift
4
star
46

fastlane-plugin-imessage

Ruby
4
star
47

model-compiler

Swift
4
star
48

danger-jira_issue_links

Danger plugin
Ruby
4
star
49

core-parser-generator

Swift
3
star
50

core-parser

Swift
3
star
51

parser-autograph

Object parser generation utility.
Swift
3
star
52

techradar-android

RMR Technology Radar
Python
2
star
53

floating-text-input

Swift
2
star
54

opensource

Redmadrobot opensource
Ruby
2
star
55

homebrew-formulae

Redmadrobot Homebrew tap
Ruby
2
star
56

rmr-docker

Shell
1
star
57

service-generator

Swift
1
star
58

Toaster

Swift
1
star