Last active
October 17, 2019 02:38
-
-
Save rsaenzi/5480ade975d3b78d2e5496aa75d003e0 to your computer and use it in GitHub Desktop.
Extension to add Phone Number mask on a textfield in iOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // UITextField+PhoneMask.swift | |
| // | |
| // Created by Rigoberto Sáenz Imbacuán (https://www.linkedin.com/in/rsaenzi/) | |
| // Copyright © 2019. All rights reserved. | |
| // | |
| import UIKit | |
| extension UITextField { | |
| func applyPhoneMask(on phoneNumber: String, shouldRemoveLastDigit: Bool = false) { | |
| guard !phoneNumber.isEmpty else { | |
| self.text = "" | |
| return | |
| } | |
| guard let regex = try? NSRegularExpression(pattern: "[\\s-\\(\\)]", options: .caseInsensitive) else { | |
| self.text = "" | |
| return | |
| } | |
| let r = NSString(string: phoneNumber).range(of: phoneNumber) | |
| var number = regex.stringByReplacingMatches(in: phoneNumber, options: .init(rawValue: 0), range: r, withTemplate: "") | |
| if number.count > 10 { | |
| let tenthDigitIndex = number.index(number.startIndex, offsetBy: 10) | |
| number = String(number[number.startIndex..<tenthDigitIndex]) | |
| } | |
| if shouldRemoveLastDigit { | |
| let end = number.index(number.startIndex, offsetBy: number.count-1) | |
| number = String(number[number.startIndex..<end]) | |
| } | |
| if number.count < 7 { | |
| let end = number.index(number.startIndex, offsetBy: number.count) | |
| let range = number.startIndex..<end | |
| number = number.replacingOccurrences(of: "(\\d{3})(\\d+)", with: "$1-$2", options: .regularExpression, range: range) | |
| } else { | |
| let end = number.index(number.startIndex, offsetBy: number.count) | |
| let range = number.startIndex..<end | |
| number = number.replacingOccurrences(of: "(\\d{3})(\\d{3})(\\d+)", with: "$1-$2-$3", options: .regularExpression, range: range) | |
| } | |
| self.text = number | |
| } | |
| } | |
| // --------------- | |
| // Usage example: | |
| // --------------- | |
| extension MyViewController: UITextFieldDelegate { | |
| func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { | |
| // Deletion is enabled | |
| if string.count == 0 { | |
| return true | |
| } | |
| // Only numbers are permitted | |
| guard string.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil else { | |
| return false | |
| } | |
| // Max digits allowed | |
| let fullLength: Int = textField.text!.count + string.count | |
| if fullLength > 12 { // 10 digits + 2 mask characters | |
| return false | |
| } | |
| // Phone mask | |
| let fullString: String = "\(textField.text!)\(string)" | |
| if range.length == 1 { | |
| textField.applyPhoneMask(on: fullString, shouldRemoveLastDigit: true) | |
| } else { | |
| textField.applyPhoneMask(on: fullString) | |
| } | |
| return false | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment