Skip to content

Instantly share code, notes, and snippets.

@insidegui
Created March 31, 2017 23:31
Show Gist options
  • Save insidegui/0cb7fc8d3f9c0716f1ff8c0010f49250 to your computer and use it in GitHub Desktop.
Save insidegui/0cb7fc8d3f9c0716f1ff8c0010f49250 to your computer and use it in GitHub Desktop.
//
// PUPatternTextField.swift
// PeixeUrbano
//
// Created by Guilherme Rambo on 24/01/17.
//
//
import UIKit
/// A text field that can have its input masked using a `MaskPattern`
open class PUPatternTextField: UITextField {
public var textChangeHandler: ((String) -> ())?
public var programmaticTextChangeHandler: ((String) -> ())?
/// Mask pattern to be applied to the field's input
public var pattern: MaskPattern? {
didSet {
// reapply pattern when changed
let textBeforePatternChange = self.inputText
self.inputText = textBeforePatternChange
}
}
/// Use this property to set the input's text programmatically
public var inputText: String? {
didSet {
text = inputText
if !isUserEditing {
programmaticTextChangeHandler?(rawInput)
}
}
}
/// This property stores the raw input string, without the pattern applied to it
public var rawInput: String {
if let filter = pattern?.filter {
return filter.closure(text ?? "")
} else {
return text ?? ""
}
}
private var isUserEditing = false
override public init(frame: CGRect) {
super.init(frame: frame)
registerObserver()
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
registerObserver()
}
private func registerObserver() {
NotificationCenter.default.addObserver(self,
selector: #selector(textDidChange),
name: NSNotification.Name.UITextFieldTextDidChange,
object: self)
}
@objc private func textDidChange() {
isUserEditing = true
processTextInput()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.isUserEditing = false
}
}
private func processTextInput() {
guard let pattern = pattern else { return }
guard let inputText = text, inputText.characters.count > 0 else { return }
self.text = pattern.apply(to: inputText)
textChangeHandler?(rawInput)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment