         addSubview(placeholderLabel)
     }
 
-    @IBInspectable open var textMask: String? {
-        didSet(oldMask) {
-            var cursorPosition: Int = 0
-            if let selectedRange = selectedCharactersRange, let text = text {
-                cursorPosition = text.distance(from: text.startIndex, to: selectedRange.lowerBound)
-            } else {
-                cursorPosition = 0
-            }
-
-            let unformattedText = unformatterText(fromText: (text ?? ""), textMask: oldMask, cursorPosition: &cursorPosition)
-            let newFormattedText = formattedText(fromText: unformattedText, textMask: textMask, cursorPosition: &cursorPosition)
-            text = newFormattedText
-
+    @IBInspectable open var textFormatter: TextFromatter? {
+        didSet(oldFormatter) {
+            let text = (self.text ?? "")
+            let selectedRange = selectedCharactersRange ?? text.startIndex..<text.startIndex
+
+            var unformattedText = text
+            var unformattedRange = selectedRange
+            if let oldFormatter = oldFormatter {
+                (unformattedText, unformattedRange) = oldFormatter.unformattedText(from: text, range: selectedRange)
+            }
+
+            var formattedText = unformattedText
+            var formattedRange = unformattedRange
+            if let formatter = textFormatter {
+                (formattedText, formattedRange) = formatter.formattedText(from: unformattedText, range: unformattedRange)
+            }
+
+            self.text = formattedText
             if selectedTextRange != nil {
-                let cursorIndex = newFormattedText.index(newFormattedText.startIndex, offsetBy: cursorPosition, limitedBy: newFormattedText.endIndex) ?? newFormattedText.endIndex
-                selectedCharactersRange = cursorIndex..<cursorIndex
+                selectedCharactersRange = formattedRange.upperBound..<formattedRange.upperBound
             }
         }
     }

}

open class FormattedTextField: UITextField {
    open static let maskSymbol: Character = "×"

    public override init(frame: CGRect) {
        placeholderLabel = UILabel()

                return false
            }
        }
        let text = self.text ?? ""
        let charactersRange = text.range(fromUtf16NsRange: range)!

        let unformattedText: String
        var unformattedRange: Range<String.Index>
        if let formatter = textFormatter {
            (unformattedText, unformattedRange) = formatter.unformattedText(from: text, range: charactersRange)
        } else {
            unformattedText = text
            unformattedRange = charactersRange
        }

        let isBackspace = (string.characters.count == 0 && unformattedRange.isEmpty)
        if isBackspace && unformattedRange.lowerBound != unformattedText.startIndex {
            unformattedRange = unformattedText.index(before: unformattedRange.lowerBound)..<unformattedRange.upperBound
        }

        if let originDelegate = (delegateProxy.delegate as? FormattedTextFieldDelegate),
            originDelegate.responds(to: #selector(FormattedTextFieldDelegate.textField(_:shouldChangeUnformattedText:in:replacementString:))) {
            let utf16UnformattedRange = unformattedText.utf16Nsrange(fromRange: unformattedRange)
            if !originDelegate.textField!(self, shouldChangeUnformattedText:unformattedText, in:utf16UnformattedRange, replacementString: string) {
                return false
            }
        }

        let newUnformattedText = unformattedText.replacingCharacters(in: unformattedRange, with: string)
        let selectionOffset = unformattedText.distance(from: unformattedText.startIndex, to: unformattedRange.lowerBound)
        let cursorPosition = newUnformattedText.index(newUnformattedText.startIndex, offsetBy: selectionOffset + string.characters.count)

        let formattedText: String
        let formattedRange: Range<String.Index>
        if let formatter = textFormatter {
            (formattedText, formattedRange) = formatter.formattedText(from: newUnformattedText, range: cursorPosition..<cursorPosition)
        } else {
            formattedText = newUnformattedText
            formattedRange = cursorPosition..<cursorPosition
        }
        self.text = formattedText
        selectedCharactersRange = formattedRange.upperBound..<formattedRange.upperBound

        placeholderLabel.isHidden = (newUnformattedText.characters.count > 0)

        sendActions(for: .editingChanged)

        return false
    }
}

