Skip to content

Instantly share code, notes, and snippets.

@rsaenzi
Last active October 17, 2019 02:38
Show Gist options
  • Select an option

  • Save rsaenzi/5480ade975d3b78d2e5496aa75d003e0 to your computer and use it in GitHub Desktop.

Select an option

Save rsaenzi/5480ade975d3b78d2e5496aa75d003e0 to your computer and use it in GitHub Desktop.
Extension to add Phone Number mask on a textfield in iOS
//
// 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