From 3134327dd5d8ef4e51edba88a71ae9000c44eee8 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 8 May 2024 15:25:51 -0500 Subject: [PATCH] fixed the tel type Signed-off-by: Matt Bruce --- .../TextFields/InputField/InputField.swift | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/VDS/Components/TextFields/InputField/InputField.swift b/VDS/Components/TextFields/InputField/InputField.swift index 00e7404f..4a78203f 100644 --- a/VDS/Components/TextFields/InputField/InputField.swift +++ b/VDS/Components/TextFields/InputField/InputField.swift @@ -433,6 +433,61 @@ open class InputField: EntryFieldBase { //-------------------------------------------------- open var dateFormat: DateFormat = .mmddyy { didSet { setNeedsUpdate() } } + // MARK: - Telephone + //--------------------------------------------------- + private func formatUSNumber(_ number: String) -> String { + // Format the number in the style XXX-XXX-XXXX + let areaCodeLength = 3 + let centralOfficeCodeLength = 3 + let lineNumberLength = 4 + + var formattedNumber = "" + + if number.count > 0 { + formattedNumber.append(contentsOf: number.prefix(areaCodeLength)) + } + + if number.count > areaCodeLength { + let startIndex = number.index(number.startIndex, offsetBy: areaCodeLength) + let endIndex = number.index(startIndex, offsetBy: min(centralOfficeCodeLength, number.count - areaCodeLength)) + let centralOfficeCode = number[startIndex.. areaCodeLength + centralOfficeCodeLength { + let startIndex = number.index(number.startIndex, offsetBy: areaCodeLength + centralOfficeCodeLength) + let endIndex = number.index(startIndex, offsetBy: min(lineNumberLength, number.count - areaCodeLength - centralOfficeCodeLength)) + let lineNumber = number[startIndex.. UITextPosition? { + let start = range.location + let length = string.count + + let newCursorLocation = start + length + let rawNumberCount = rawNumber.count + + // Adjust the cursor position to skip over formatting characters + var formattedCharacterCount = 0 + for (index, character) in formattedNumber.enumerated() { + if index >= newCursorLocation + formattedCharacterCount { + break + } + if !character.isNumber { + formattedCharacterCount += 1 + } + } + + let finalCursorLocation = min(newCursorLocation + formattedCharacterCount, formattedNumber.count) + return textField.position(from: textField.beginningOfDocument, offset: finalCursorLocation) + } + } extension InputField: UITextFieldDelegate { @@ -457,13 +512,59 @@ extension InputField: UITextFieldDelegate { } public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + +// case text, number, inlineAction, password, creditCard, tel, date, securityCode + switch fieldType { case .date: // Allow only numbers and limit the length of text. let allowedCharacters = CharacterSet.decimalDigits let characterSet = CharacterSet(charactersIn: string) return allowedCharacters.isSuperset(of: characterSet) && ((textField.text?.count ?? 0) + string.count - range.length) <= dateFormat.maxLength + + case .number: + // Allow only numbers + let allowedCharacters = CharacterSet.decimalDigits + let characterSet = CharacterSet(charactersIn: string) + return allowedCharacters.isSuperset(of: characterSet) + + case .tel: + // Allow only numbers and limit the length of text. + let allowedCharacters = CharacterSet(charactersIn: "01233456789") + let characterSet = CharacterSet(charactersIn: string) + let currentText = textField.text ?? "" + if !allowedCharacters.isSuperset(of: characterSet) { return false } + // Calculate the new text + let newText = (currentText as NSString).replacingCharacters(in: range, with: string) + + // Remove any existing formatting + let rawNumber = newText.filter { $0.isNumber } + + // Format the number with dashes + let formattedNumber = formatUSNumber(rawNumber) + + // Set the formatted text + textField.text = formattedNumber + + // Calculate the new cursor position + if let newPosition = getNewCursorPosition(textField: textField, + range: range, + replacementString: string, + rawNumber: rawNumber, + formattedNumber: formattedNumber) { + textField.selectedTextRange = textField.textRange(from: newPosition, to: newPosition) + } + + // Prevent the default behavior + return false + + case .securityCode: + // Allow only numbers and limit the length of text. + let allowedCharacters = CharacterSet.decimalDigits + let characterSet = CharacterSet(charactersIn: string) + return allowedCharacters.isSuperset(of: characterSet) && ((textField.text?.count ?? 0) + string.count - range.length) <= 4 + default: return true }