refactored into FieldTypeHandlers first cut
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
eab8e72785
commit
14c578edbd
@ -146,6 +146,10 @@
|
||||
EAC58C0A2BED004E00BA39FA /* FieldType.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC58C092BED004E00BA39FA /* FieldType.swift */; };
|
||||
EAC58C0C2BED01D500BA39FA /* Telephone.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC58C0B2BED01D500BA39FA /* Telephone.swift */; };
|
||||
EAC58C0E2BED021600BA39FA /* Password.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC58C0D2BED021600BA39FA /* Password.swift */; };
|
||||
EAC58C122BED0DDD00BA39FA /* Text.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC58C112BED0DDD00BA39FA /* Text.swift */; };
|
||||
EAC58C142BED0DEC00BA39FA /* Number.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC58C132BED0DEC00BA39FA /* Number.swift */; };
|
||||
EAC58C162BED0E0300BA39FA /* InlineAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC58C152BED0E0300BA39FA /* InlineAction.swift */; };
|
||||
EAC58C182BED0E2300BA39FA /* SecurityCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC58C172BED0E2300BA39FA /* SecurityCode.swift */; };
|
||||
EAC71A1D2A2E155A00E47A9F /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC71A1C2A2E155A00E47A9F /* Checkbox.swift */; };
|
||||
EAC71A1F2A2E173D00E47A9F /* RadioButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC71A1E2A2E173D00E47A9F /* RadioButton.swift */; };
|
||||
EAC846F3294B95CE00F685BA /* ButtonGroupCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC846F2294B95CE00F685BA /* ButtonGroupCollectionViewCell.swift */; };
|
||||
@ -347,6 +351,10 @@
|
||||
EAC58C092BED004E00BA39FA /* FieldType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FieldType.swift; sourceTree = "<group>"; };
|
||||
EAC58C0B2BED01D500BA39FA /* Telephone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Telephone.swift; sourceTree = "<group>"; };
|
||||
EAC58C0D2BED021600BA39FA /* Password.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Password.swift; sourceTree = "<group>"; };
|
||||
EAC58C112BED0DDD00BA39FA /* Text.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Text.swift; sourceTree = "<group>"; };
|
||||
EAC58C132BED0DEC00BA39FA /* Number.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Number.swift; sourceTree = "<group>"; };
|
||||
EAC58C152BED0E0300BA39FA /* InlineAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InlineAction.swift; sourceTree = "<group>"; };
|
||||
EAC58C172BED0E2300BA39FA /* SecurityCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityCode.swift; sourceTree = "<group>"; };
|
||||
EAC71A1C2A2E155A00E47A9F /* Checkbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = "<group>"; };
|
||||
EAC71A1E2A2E173D00E47A9F /* RadioButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButton.swift; sourceTree = "<group>"; };
|
||||
EAC846F2294B95CE00F685BA /* ButtonGroupCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroupCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||
@ -891,8 +899,12 @@
|
||||
EAC58C092BED004E00BA39FA /* FieldType.swift */,
|
||||
EAC58C052BED000200BA39FA /* CreditCard.swift */,
|
||||
EAC58C072BED002D00BA39FA /* Date.swift */,
|
||||
EAC58C0B2BED01D500BA39FA /* Telephone.swift */,
|
||||
EAC58C152BED0E0300BA39FA /* InlineAction.swift */,
|
||||
EAC58C132BED0DEC00BA39FA /* Number.swift */,
|
||||
EAC58C0D2BED021600BA39FA /* Password.swift */,
|
||||
EAC58C172BED0E2300BA39FA /* SecurityCode.swift */,
|
||||
EAC58C0B2BED01D500BA39FA /* Telephone.swift */,
|
||||
EAC58C112BED0DDD00BA39FA /* Text.swift */,
|
||||
);
|
||||
path = FieldTypes;
|
||||
sourceTree = "<group>";
|
||||
@ -1224,6 +1236,7 @@
|
||||
EAB1D2CF28ABEF2B00DAE764 /* Typography+Base.swift in Sources */,
|
||||
EA0D1C3B2A6AD51B00E5C127 /* Typogprahy+Styles.swift in Sources */,
|
||||
EAF7F09A2899B17200B287F5 /* CATransaction.swift in Sources */,
|
||||
EAC58C162BED0E0300BA39FA /* InlineAction.swift in Sources */,
|
||||
EA0D1C3D2A6AD57600E5C127 /* Typography+Enums.swift in Sources */,
|
||||
EAF1FE9B29DB1A6000101452 /* Changeable.swift in Sources */,
|
||||
EAC58C0C2BED01D500BA39FA /* Telephone.swift in Sources */,
|
||||
@ -1263,6 +1276,7 @@
|
||||
EA985BF5296C60C000F2FF2E /* Icon.swift in Sources */,
|
||||
EA3361AA288B25E40071C351 /* Disabling.swift in Sources */,
|
||||
EA3361B6288B2A410071C351 /* Control.swift in Sources */,
|
||||
EAC58C122BED0DDD00BA39FA /* Text.swift in Sources */,
|
||||
5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */,
|
||||
EAF7F0B7289C12A600B287F5 /* UITapGestureRecognizer.swift in Sources */,
|
||||
EA0D1C392A6AD4DF00E5C127 /* Typography+SpacingConfig.swift in Sources */,
|
||||
@ -1279,7 +1293,9 @@
|
||||
EA3361B8288B2AAA0071C351 /* ViewProtocol.swift in Sources */,
|
||||
EA3361A8288B23300071C351 /* UIColor.swift in Sources */,
|
||||
EA2DC9B42BE2C6FE004F58C5 /* TextField.swift in Sources */,
|
||||
EAC58C182BED0E2300BA39FA /* SecurityCode.swift in Sources */,
|
||||
EAC9257D29119B5400091998 /* TextLink.swift in Sources */,
|
||||
EAC58C142BED0DEC00BA39FA /* Number.swift in Sources */,
|
||||
EA596ABF2A16B4F500300C4B /* Tabs.swift in Sources */,
|
||||
EAD062A72A3B67770015965D /* UIView+CALayer.swift in Sources */,
|
||||
EAD068942A560C13002E3A2D /* LoaderLaunchable.swift in Sources */,
|
||||
|
||||
@ -75,6 +75,29 @@ extension InputField {
|
||||
}
|
||||
}
|
||||
|
||||
class CreditCardHandler: NSObject, FieldTypeHandler {
|
||||
static let shared = CreditCardHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .numberPad }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {
|
||||
if let text = inputField.textField.text, text.count > 0 {
|
||||
let rule = CharacterCountRule().copyWith {
|
||||
$0.maxLength = inputField.creditCardType.maxLength
|
||||
$0.compareType = .equals
|
||||
$0.errorMessage = "Enter a valid credit card."
|
||||
}
|
||||
inputField.rules.append(.init(rule))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal func formatCreditCardNumber(_ number: String) -> String {
|
||||
let formattedInput = number.filter { $0.isNumber } // Remove any existing slashes
|
||||
return String.format(formattedInput, indices: creditCardType.separatorIndices, with: " ")
|
||||
|
||||
@ -6,8 +6,33 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
extension InputField {
|
||||
|
||||
class DateHandler: NSObject, FieldTypeHandler {
|
||||
static let shared = DateHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .numberPad }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {
|
||||
if let text = inputField.textField.text, text.count > 0 {
|
||||
let rule = CharacterCountRule().copyWith {
|
||||
$0.maxLength = inputField.dateFormat.maxLength
|
||||
$0.compareType = .equals
|
||||
$0.errorMessage = "Enter a valid date."
|
||||
}
|
||||
inputField.rules.append(.init(rule))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum DateFormat: String, CaseIterable {
|
||||
case mmyy
|
||||
case mmddyy
|
||||
|
||||
@ -9,7 +9,7 @@ import Foundation
|
||||
import UIKit
|
||||
|
||||
extension InputField {
|
||||
protocol FieldHandler: UITextFieldDelegate {
|
||||
protocol FieldTypeHandler: UITextFieldDelegate {
|
||||
var keyboardType: UIKeyboardType { get }
|
||||
func configure(for inputField: InputField)
|
||||
func appendRules(for inputField: InputField)
|
||||
@ -18,7 +18,7 @@ extension InputField {
|
||||
public enum FieldType: String, CaseIterable {
|
||||
case text, number, inlineAction, password, creditCard, telephone, date, securityCode
|
||||
|
||||
func handler() -> FieldHandler {
|
||||
func handler() -> FieldTypeHandler {
|
||||
switch self {
|
||||
case .text:
|
||||
return TextHandler.shared
|
||||
@ -43,150 +43,5 @@ extension InputField {
|
||||
handler().keyboardType
|
||||
}
|
||||
|
||||
internal func appendRules(for textField: InputField) {
|
||||
handler().appendRules(for: textField)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension InputField {
|
||||
class TextHandler: NSObject, FieldHandler {
|
||||
static let shared = TextHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .default }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {}
|
||||
}
|
||||
|
||||
class NumberHandler: NSObject, FieldHandler {
|
||||
static let shared = NumberHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .numberPad }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {}
|
||||
}
|
||||
|
||||
class InlineActionHandler: NSObject, FieldHandler {
|
||||
static let shared = InlineActionHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .default }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {}
|
||||
}
|
||||
|
||||
class PasswordHandler: NSObject, FieldHandler {
|
||||
static let shared = PasswordHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .default }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {}
|
||||
}
|
||||
|
||||
class CreditCardHandler: NSObject, FieldHandler {
|
||||
static let shared = CreditCardHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .numberPad }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {
|
||||
if let text = inputField.textField.text, text.count > 0 {
|
||||
let rule = CharacterCountRule().copyWith {
|
||||
$0.maxLength = inputField.creditCardType.maxLength
|
||||
$0.compareType = .equals
|
||||
$0.errorMessage = "Enter a valid credit card."
|
||||
}
|
||||
inputField.rules.append(.init(rule))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TelephoneHandler: NSObject, FieldHandler {
|
||||
static let shared = TelephoneHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .phonePad }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {
|
||||
if let text = inputField.textField.text, text.count > 0 {
|
||||
let rule = CharacterCountRule().copyWith {
|
||||
$0.maxLength = "XXX-XXX-XXXX".count
|
||||
$0.compareType = .equals
|
||||
$0.errorMessage = "Enter a valid telephone."
|
||||
}
|
||||
inputField.rules.append(.init(rule))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DateHandler: NSObject, FieldHandler {
|
||||
static let shared = DateHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .numberPad }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {
|
||||
if let text = inputField.textField.text, text.count > 0 {
|
||||
let rule = CharacterCountRule().copyWith {
|
||||
$0.maxLength = inputField.dateFormat.maxLength
|
||||
$0.compareType = .equals
|
||||
$0.errorMessage = "Enter a valid date."
|
||||
}
|
||||
inputField.rules.append(.init(rule))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SecurityCodeHandler: NSObject, FieldHandler {
|
||||
static let shared = SecurityCodeHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .numberPad }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
//
|
||||
// InlineAction.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Matt Bruce on 5/9/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
extension InputField {
|
||||
|
||||
class InlineActionHandler: NSObject, FieldTypeHandler {
|
||||
static let shared = InlineActionHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .default }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {}
|
||||
}
|
||||
|
||||
}
|
||||
27
VDS/Components/TextFields/InputField/FieldTypes/Number.swift
Normal file
27
VDS/Components/TextFields/InputField/FieldTypes/Number.swift
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// Number.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Matt Bruce on 5/9/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
extension InputField {
|
||||
|
||||
class NumberHandler: NSObject, FieldTypeHandler {
|
||||
static let shared = NumberHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .numberPad }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {}
|
||||
}
|
||||
|
||||
}
|
||||
@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
extension InputField {
|
||||
|
||||
@ -17,4 +18,18 @@ extension InputField {
|
||||
}
|
||||
}
|
||||
|
||||
class PasswordHandler: NSObject, FieldTypeHandler {
|
||||
static let shared = PasswordHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .default }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
//
|
||||
// SecurityCode.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Matt Bruce on 5/9/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
extension InputField {
|
||||
|
||||
class SecurityCodeHandler: NSObject, FieldTypeHandler {
|
||||
static let shared = SecurityCodeHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .numberPad }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {}
|
||||
}
|
||||
|
||||
}
|
||||
@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
extension InputField {
|
||||
|
||||
@ -40,4 +41,27 @@ extension InputField {
|
||||
return formattedNumber
|
||||
}
|
||||
|
||||
class TelephoneHandler: NSObject, FieldTypeHandler {
|
||||
static let shared = TelephoneHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .phonePad }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {
|
||||
if let text = inputField.textField.text, text.count > 0 {
|
||||
let rule = CharacterCountRule().copyWith {
|
||||
$0.maxLength = "XXX-XXX-XXXX".count
|
||||
$0.compareType = .equals
|
||||
$0.errorMessage = "Enter a valid telephone."
|
||||
}
|
||||
inputField.rules.append(.init(rule))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
25
VDS/Components/TextFields/InputField/FieldTypes/Text.swift
Normal file
25
VDS/Components/TextFields/InputField/FieldTypes/Text.swift
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// Text.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Matt Bruce on 5/9/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
extension InputField {
|
||||
class TextHandler: NSObject, FieldTypeHandler {
|
||||
static let shared = TextHandler()
|
||||
|
||||
var keyboardType: UIKeyboardType { .default }
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func configure(for inputField: InputField) {}
|
||||
|
||||
func appendRules(for inputField: InputField) {}
|
||||
}
|
||||
}
|
||||
@ -349,7 +349,7 @@ open class InputField: EntryFieldBase {
|
||||
|
||||
override func updateRules() {
|
||||
super.updateRules()
|
||||
fieldType.appendRules(for: self)
|
||||
fieldType.handler().appendRules(for: self)
|
||||
}
|
||||
|
||||
/// Used to update any Accessibility properties.
|
||||
@ -389,31 +389,6 @@ open class InputField: EntryFieldBase {
|
||||
}
|
||||
return super.resignFirstResponder()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Methods
|
||||
//--------------------------------------------------
|
||||
internal func cursorPosition(textField: UITextField, range: NSRange, replacementString string: String, rawNumber: String, formattedNumber: String) -> UITextPosition? {
|
||||
let start = range.location
|
||||
let length = string.count
|
||||
|
||||
let newCursorLocation = start + length
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Password
|
||||
//--------------------------------------------------
|
||||
@ -491,8 +466,7 @@ extension InputField: UITextFieldDelegate {
|
||||
textField.text = formattedNumber
|
||||
|
||||
// Calculate the new cursor position
|
||||
if let newPosition = cursorPosition(textField: textField,
|
||||
range: range,
|
||||
if let newPosition = textField.cursorPosition(range: range,
|
||||
replacementString: string,
|
||||
rawNumber: rawNumber,
|
||||
formattedNumber: formattedNumber) {
|
||||
@ -551,8 +525,7 @@ extension InputField: UITextFieldDelegate {
|
||||
textField.text = formattedNumber
|
||||
|
||||
// Calculate the new cursor position
|
||||
if let newPosition = cursorPosition(textField: textField,
|
||||
range: range,
|
||||
if let newPosition = textField.cursorPosition(range: range,
|
||||
replacementString: string,
|
||||
rawNumber: rawNumber,
|
||||
formattedNumber: formattedNumber) {
|
||||
@ -592,3 +565,26 @@ extension String {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension UITextField {
|
||||
internal func cursorPosition(range: NSRange, replacementString string: String, rawNumber: String, formattedNumber: String) -> UITextPosition? {
|
||||
let start = range.location
|
||||
let length = string.count
|
||||
|
||||
let newCursorLocation = start + length
|
||||
|
||||
// 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 position(from: beginningOfDocument, offset: finalCursorLocation)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user