Skip to content

Instantly share code, notes, and snippets.

@Edudjr
Last active November 26, 2017 17:26
Show Gist options
  • Save Edudjr/47b0cd532dd2c6ea626c51f0f07c06ec to your computer and use it in GitHub Desktop.
Save Edudjr/47b0cd532dd2c6ea626c51f0f07c06ec to your computer and use it in GitHub Desktop.
A component that takes multiple masks and automatically updates the textfield based on input's length
//
// SequenceCustomMaskTextField.swift
//
// Created by Domene on 02/02/17.
//
import Foundation
import UIKit
@objc protocol SequenceCustomMaskTextFieldDelegate : UITextFieldDelegate{
@objc optional func sequenceCustomMasktextFieldDidEndEditing(textField: UITextField)
}
/*
* CustomMaskTextField can be used with a list of masks.
* e.g:
* customMaskTextField.setMasks(['**.**', '***-***', '$$-$$$'])
* It will reorder masks by length.
*
* Use $ for digits ($$-$$$$)
* Use * for characters [a-zA-Z] (**-****)
*/
class SequenceCustomMaskTextField: MoveMaisTextField, UITextFieldDelegate{
private var customMask : CustomMask?
private var currentMaskIndex : Int = 0
private var maskSequence : [String] = ["$$$-$$","$$.$$"]
var cleanText : String? {
get {
return self.customMask?.cleanText
}
set {
currentMaskIndex = maskSequence.count-1
customMask?.formattingPattern = maskSequence[currentMaskIndex]
var newText = customMask!.formatString(string: newValue ?? "")
if newText.length < maskSequence[currentMaskIndex].length {
if currentMaskIndex > 0 {
currentMaskIndex -= 1
customMask?.formattingPattern = maskSequence[currentMaskIndex]
newText = customMask!.formatString(string: newValue ?? "")
}
}
self.text = newText
}
}
var customDelegate: CustomMaskTextFieldDelegate? = nil
override func awakeFromNib() {
super.awakeFromNib()
super.delegate = self
customMask = CustomMask(formattingPattern: self.maskSequence.first!)
}
func setMaskSequence(maskSequence: [String]){
self.maskSequence = sortArrayByLength(array: maskSequence);
currentMaskIndex = 0
customMask?.formattingPattern = self.maskSequence[currentMaskIndex];
}
private func sortArrayByLength(array: [String]) -> Array<String>{
let sorted = array.sorted {
$0.length < $1.length
}
return sorted;
}
// MARK : UITextFieldDelegate
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return shouldChangeCharactersInRange(range: range, replacementString: string)
}
func shouldChangeCharactersInRange(range: NSRange, replacementString string: String) -> Bool {
//Check if backspace was pressed
//Detect backspace
let char = string.cString(using: String.Encoding.utf8)!
let isBackSpace = strcmp(char, "\\b")
if (isBackSpace == -92) { //Backspace was pressed
if(currentMaskIndex > 0){
if((self.text!.length-1) <= maskSequence[currentMaskIndex-1].length){
currentMaskIndex -= 1
}
}else{
currentMaskIndex = 0
}
let string = customMask!.formatStringWithRange(range: range, string: string)
self.customMask!.formattingPattern = self.maskSequence[currentMaskIndex]
self.text = customMask!.formatString(string: self.customMask!.finalText!)
return false
}
if maskSequence.count > 0 {
//if text length greater than currentMask length AND currentMask is not the last
if((self.text!.length+1) > maskSequence[currentMaskIndex].length){
if(currentMaskIndex < maskSequence.count-1){
currentMaskIndex += 1
self.customMask?.formattingPattern = self.maskSequence[currentMaskIndex]
self.text = customMask!.formatString(string: self.text!+string)
}
}else{
self.text = customMask!.formatStringWithRange(range: range, string: string)
}
}else{
return true
}
return false
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.customDelegate?.customMasktextFieldDidEndEditing?(textField: textField)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment