From c5a10f11d69a7e35be4c5e1684d2e8c6715a37f3 Mon Sep 17 00:00:00 2001 From: Blinov Evgeny Date: Tue, 28 May 2024 17:06:53 +0300 Subject: [PATCH 1/6] - upd PhoneNumberKit target version - pass PhoneNumberKit via init --- .../xcshareddata/swiftpm/Package.resolved | 4 +- Package.swift | 2 +- .../iPhoneNumberField+ViewModifiers.swift | 6 -- .../iPhoneNumberField/iPhoneNumberField.swift | 58 +++++++++++-------- 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/Demo/iPhoneNumberFieldDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Demo/iPhoneNumberFieldDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 0404312..39b3815 100644 --- a/Demo/iPhoneNumberFieldDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Demo/iPhoneNumberFieldDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/marmelroy/PhoneNumberKit", "state": { "branch": null, - "revision": "104a53d62c55aa5794faf30b29ccad319653b552", - "version": "3.4.5" + "revision": "ee5d7114934e60812c9b47c333f01b67d002be2d", + "version": "3.7.10" } } ] diff --git a/Package.swift b/Package.swift index df2a346..0b71121 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( ], dependencies: [ // Dependencies declare other packages that this package depends on. - .package(url: "https://github.com/marmelroy/PhoneNumberKit", .upToNextMajor(from: "3.4.5")) + .package(url: "https://github.com/marmelroy/PhoneNumberKit", .upToNextMajor(from: "3.7.10")) ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. diff --git a/Sources/iPhoneNumberField/iPhoneNumberField+ViewModifiers.swift b/Sources/iPhoneNumberField/iPhoneNumberField+ViewModifiers.swift index 554ded9..2b6f7b3 100644 --- a/Sources/iPhoneNumberField/iPhoneNumberField+ViewModifiers.swift +++ b/Sources/iPhoneNumberField/iPhoneNumberField+ViewModifiers.swift @@ -368,10 +368,4 @@ public extension iPhoneNumberField { view.formatted = formatted return view } - - /// Our packages inherently voids the functionality of textContentType ๐Ÿ™ƒ. As described by Apple ๐Ÿ‘ฉโ€๐Ÿ’ป, "The textContentType property is designed to provide the keyboard with extra information about the semantic intent of the text document". However, in `iPhoneNumberField`'s case the semantic intent is always to write a phone number ๐Ÿ˜โ˜Ž - /// - Parameter textContentType: - /// - Returns: self -// @available(*, deprecated, message: "Our packages inherently voids the functionality of textContentType ๐Ÿ™ƒ") -// func textContentType(_ textContentType: UITextContentType?) -> some View { return self } } diff --git a/Sources/iPhoneNumberField/iPhoneNumberField.swift b/Sources/iPhoneNumberField/iPhoneNumberField.swift index 3f54378..d4782ec 100644 --- a/Sources/iPhoneNumberField/iPhoneNumberField.swift +++ b/Sources/iPhoneNumberField/iPhoneNumberField.swift @@ -94,11 +94,11 @@ public struct iPhoneNumberField: UIViewRepresentable { /// An action to perform when editing on the phone number field begins. โ–ถ๏ธ /// The closure requires a `PhoneNumberTextField` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. - internal var onBeginEditingHandler = { (view: PhoneNumberTextField) in } + internal var onBeginEditingHandler = { (view: UIViewType) in } /// An action to perform when any characters in the phone number field are changed. ๐Ÿ’ฌ /// The closure requires a `PhoneNumberTextField` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. - internal var onEditingChangeHandler = { (view: PhoneNumberTextField) in } + internal var onEditingChangeHandler = { (view: UIViewType) in } /// An action to perform when any characters in the phone number field are changed. โ˜Ž๏ธ /// The closure requires a `PhoneNumber` parameter, that you can change each time this is called, if desired. @@ -106,18 +106,18 @@ public struct iPhoneNumberField: UIViewRepresentable { /// An action to perform when editing on the phone number field ends. โน /// The closure requires a `PhoneNumberTextField` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. - internal var onEndEditingHandler = { (view: PhoneNumberTextField) in } + internal var onEndEditingHandler = { (view: UIViewType) in } /// An action to perform when the phone number field is cleared. โŒ /// The closure requires a `PhoneNumberTextField` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. - internal var onClearHandler = { (view: PhoneNumberTextField) in } + internal var onClearHandler = { (view: UIViewType) in } /// An action to perform when the return key on the phone number field is pressed. โ†ช๏ธ /// The closure requires a `PhoneNumberTextField` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. - internal var onReturnHandler = { (view: PhoneNumberTextField) in } + internal var onReturnHandler = { (view: UIViewType) in } /// A closure that requires a `PhoneNumberTextField` object to be configured in the body. โš™๏ธ - public var configuration = { (view: PhoneNumberTextField) in } + public var configuration = { (view: UIViewType) in } @Environment(\.layoutDirection) internal var layoutDirection: LayoutDirection /// The horizontal alignment of the phone number field. @@ -132,22 +132,27 @@ public struct iPhoneNumberField: UIViewRepresentable { /// Whether the phone number field is enabled for interaction. โœ… internal var isUserInteractionEnabled = true - public init(_ title: String? = nil, - text: Binding, - isEditing: Binding? = nil, - formatted: Bool = true, - configuration: @escaping (UIViewType) -> () = { _ in } ) { - + internal var phoneNumberKit: PhoneNumberKit + + public init( + _ title: String? = nil, + text: Binding, + isEditing: Binding? = nil, + formatted: Bool = true, + phoneNumberKit: PhoneNumberKit = PhoneNumberKit(), + configuration: @escaping (UIViewType) -> () = { _ in } + ) { self.placeholder = title self.externalIsFirstResponder = isEditing self.formatted = formatted self._text = text self._displayedText = State(initialValue: text.wrappedValue) + self.phoneNumberKit = phoneNumberKit self.configuration = configuration } public func makeUIView(context: UIViewRepresentableContext) -> PhoneNumberTextField { - let uiView = UIViewType() + let uiView = UIViewType(withPhoneNumberKit: phoneNumberKit) uiView.setContentHuggingPriority(.defaultHigh, for: .vertical) uiView.addTarget(context.coordinator, @@ -203,22 +208,27 @@ public struct iPhoneNumberField: UIViewRepresentable { configuration(uiView) } } +} + +// MARK: - Coordinator - public func makeCoordinator() -> Coordinator { +public extension iPhoneNumberField { + func makeCoordinator() -> Coordinator { Coordinator( text: $text, - displayedText: $displayedText, - isFirstResponder: externalIsFirstResponder ?? $internalIsFirstResponder, - formatted: formatted, - onBeginEditing: onBeginEditingHandler, - onEditingChange: onEditingChangeHandler, - onPhoneNumberChange: onPhoneNumberChangeHandler, - onEndEditing: onEndEditingHandler, - onClear: onClearHandler, - onReturn: onReturnHandler) + displayedText: $displayedText, + isFirstResponder: externalIsFirstResponder ?? $internalIsFirstResponder, + formatted: formatted, + onBeginEditing: onBeginEditingHandler, + onEditingChange: onEditingChangeHandler, + onPhoneNumberChange: onPhoneNumberChangeHandler, + onEndEditing: onEndEditingHandler, + onClear: onClearHandler, + onReturn: onReturnHandler + ) } - public class Coordinator: NSObject, UITextFieldDelegate { + class Coordinator: NSObject, UITextFieldDelegate { internal init( text: Binding, displayedText: Binding, From 555d801f0b07db0323023fb279d854a03ce942d8 Mon Sep 17 00:00:00 2001 From: Blinov Evgeny Date: Tue, 4 Jun 2024 15:41:14 +0300 Subject: [PATCH 2/6] Using `insertText` on `makeUIView`, if text value is present. It allows to trigger `textViewDidChange` --- Sources/iPhoneNumberField/iPhoneNumberField.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sources/iPhoneNumberField/iPhoneNumberField.swift b/Sources/iPhoneNumberField/iPhoneNumberField.swift index d4782ec..d2d7a8d 100644 --- a/Sources/iPhoneNumberField/iPhoneNumberField.swift +++ b/Sources/iPhoneNumberField/iPhoneNumberField.swift @@ -159,6 +159,9 @@ public struct iPhoneNumberField: UIViewRepresentable { action: #selector(Coordinator.textViewDidChange), for: .editingChanged) uiView.delegate = context.coordinator + if !text.isEmpty { + uiView.insertText(text) + } uiView.withExamplePlaceholder = placeholder == nil if let defaultRegion = defaultRegion { uiView.partialFormatter.defaultRegion = defaultRegion From 45a840856008c5a6f0f66ea5aa40c4195fe00c5e Mon Sep 17 00:00:00 2001 From: Blinov Evgeny Date: Tue, 4 Jun 2024 18:23:26 +0300 Subject: [PATCH 3/6] `insertText` overriden to use with formatted phone number. Using `insertText` in case when `text` has initial value --- Package.resolved | 4 +- .../PhoneNumberTextField.swift | 17 ++++++ .../iPhoneNumberField/iPhoneNumberField.swift | 53 ++++++++++--------- 3 files changed, 48 insertions(+), 26 deletions(-) create mode 100644 Sources/iPhoneNumberField/PhoneNumberTextField.swift diff --git a/Package.resolved b/Package.resolved index f290fe5..39b3815 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/marmelroy/PhoneNumberKit", "state": { "branch": null, - "revision": "b2c695c9aedc70edd8494e3ed0902a0817e57e41", - "version": "3.5.3" + "revision": "ee5d7114934e60812c9b47c333f01b67d002be2d", + "version": "3.7.10" } } ] diff --git a/Sources/iPhoneNumberField/PhoneNumberTextField.swift b/Sources/iPhoneNumberField/PhoneNumberTextField.swift new file mode 100644 index 0000000..4362c86 --- /dev/null +++ b/Sources/iPhoneNumberField/PhoneNumberTextField.swift @@ -0,0 +1,17 @@ +// +// PhoneNumberTextField.swift +// +// +// Created by Evgeny Blinov on 04.06.2024. +// + +import Foundation +import PhoneNumberKit + +open class PhoneNumberField: PhoneNumberTextField { + override open func insertText(_ text: String) { + let textToInsert = isPartialFormatterEnabled ? partialFormatter.formatPartial(text) : text + super.insertText(textToInsert) + self.updateFlag() + } +} diff --git a/Sources/iPhoneNumberField/iPhoneNumberField.swift b/Sources/iPhoneNumberField/iPhoneNumberField.swift index d2d7a8d..5c97a58 100644 --- a/Sources/iPhoneNumberField/iPhoneNumberField.swift +++ b/Sources/iPhoneNumberField/iPhoneNumberField.swift @@ -15,6 +15,7 @@ import PhoneNumberKit /// A text field view representable structure that formats the user's phone number as they type. public struct iPhoneNumberField: UIViewRepresentable { + public typealias UIViewType = PhoneNumberField /// The formatted phone number `String`. /// This variable writes to the binding provided in the initializer. @@ -93,11 +94,11 @@ public struct iPhoneNumberField: UIViewRepresentable { internal var formatted: Bool = true /// An action to perform when editing on the phone number field begins. โ–ถ๏ธ - /// The closure requires a `PhoneNumberTextField` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. + /// The closure requires a `UIViewType` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. internal var onBeginEditingHandler = { (view: UIViewType) in } /// An action to perform when any characters in the phone number field are changed. ๐Ÿ’ฌ - /// The closure requires a `PhoneNumberTextField` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. + /// The closure requires a `UIViewType` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. internal var onEditingChangeHandler = { (view: UIViewType) in } /// An action to perform when any characters in the phone number field are changed. โ˜Ž๏ธ @@ -105,18 +106,18 @@ public struct iPhoneNumberField: UIViewRepresentable { internal var onPhoneNumberChangeHandler = { (phoneNumber: PhoneNumber?) in } /// An action to perform when editing on the phone number field ends. โน - /// The closure requires a `PhoneNumberTextField` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. + /// The closure requires a `UIViewType` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. internal var onEndEditingHandler = { (view: UIViewType) in } /// An action to perform when the phone number field is cleared. โŒ - /// The closure requires a `PhoneNumberTextField` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. + /// The closure requires a `UIViewType` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. internal var onClearHandler = { (view: UIViewType) in } /// An action to perform when the return key on the phone number field is pressed. โ†ช๏ธ - /// The closure requires a `PhoneNumberTextField` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. + /// The closure requires a `UIViewType` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. internal var onReturnHandler = { (view: UIViewType) in } - /// A closure that requires a `PhoneNumberTextField` object to be configured in the body. โš™๏ธ + /// A closure that requires a `UIViewType` object to be configured in the body. โš™๏ธ public var configuration = { (view: UIViewType) in } @Environment(\.layoutDirection) internal var layoutDirection: LayoutDirection @@ -151,7 +152,7 @@ public struct iPhoneNumberField: UIViewRepresentable { self.configuration = configuration } - public func makeUIView(context: UIViewRepresentableContext) -> PhoneNumberTextField { + public func makeUIView(context: UIViewRepresentableContext) -> UIViewType { let uiView = UIViewType(withPhoneNumberKit: phoneNumberKit) uiView.setContentHuggingPriority(.defaultHigh, for: .vertical) @@ -170,10 +171,14 @@ public struct iPhoneNumberField: UIViewRepresentable { return uiView } - public func updateUIView(_ uiView: PhoneNumberTextField, context: UIViewRepresentableContext) { + public func updateUIView(_ uiView: UIViewType, context: UIViewRepresentableContext) { DispatchQueue.main.async { uiView.textContentType = .telephoneNumber //allow auto-fill to work with telephone text field - uiView.text = text + if (uiView.text?.isEmpty ?? true) && !text.isEmpty { + uiView.insertText(text) + } else { + uiView.text = text + } uiView.font = font uiView.maxDigits = maxDigits uiView.clearButtonMode = clearButtonMode @@ -237,12 +242,12 @@ public extension iPhoneNumberField { displayedText: Binding, isFirstResponder: Binding, formatted: Bool, - onBeginEditing: @escaping (PhoneNumberTextField) -> () = { (view: PhoneNumberTextField) in }, - onEditingChange: @escaping (PhoneNumberTextField) -> () = { (view: PhoneNumberTextField) in }, + onBeginEditing: @escaping (UIViewType) -> () = { (view: UIViewType) in }, + onEditingChange: @escaping (UIViewType) -> () = { (view: UIViewType) in }, onPhoneNumberChange: @escaping (PhoneNumber?) -> () = { (view: PhoneNumber?) in }, - onEndEditing: @escaping (PhoneNumberTextField) -> () = { (view: PhoneNumberTextField) in }, - onClear: @escaping (PhoneNumberTextField) -> () = { (view: PhoneNumberTextField) in }, - onReturn: @escaping (PhoneNumberTextField) -> () = { (view: PhoneNumberTextField) in } ) + onEndEditing: @escaping (UIViewType) -> () = { (view: UIViewType) in }, + onClear: @escaping (UIViewType) -> () = { (view: UIViewType) in }, + onReturn: @escaping (UIViewType) -> () = { (view: UIViewType) in } ) { self.text = text self.displayedText = displayedText @@ -261,18 +266,18 @@ public extension iPhoneNumberField { var isFirstResponder: Binding var formatted: Bool - var onBeginEditing = { (view: PhoneNumberTextField) in } - var onEditingChange = { (view: PhoneNumberTextField) in } + var onBeginEditing = { (view: UIViewType) in } + var onEditingChange = { (view: UIViewType) in } var onPhoneNumberChange = { (phoneNumber: PhoneNumber?) in } - var onEndEditing = { (view: PhoneNumberTextField) in } - var onClear = { (view: PhoneNumberTextField) in } - var onReturn = { (view: PhoneNumberTextField) in } + var onEndEditing = { (view: UIViewType) in } + var onClear = { (view: UIViewType) in } + var onReturn = { (view: UIViewType) in } @objc public func textViewDidChange(_ textField: UITextField) { DispatchQueue.main.async { [weak self] in guard let self else { return } - guard let textField = textField as? PhoneNumberTextField else { + guard let textField = textField as? UIViewType else { return assertionFailure("Undefined state") } @@ -302,7 +307,7 @@ public extension iPhoneNumberField { DispatchQueue.main.async { [weak self] in guard let self else { return } isFirstResponder.wrappedValue = true - onBeginEditing(textField as! PhoneNumberTextField) + onBeginEditing(textField as! UIViewType) } } @@ -310,7 +315,7 @@ public extension iPhoneNumberField { DispatchQueue.main.async { [weak self] in guard let self else { return } isFirstResponder.wrappedValue = false - onBeginEditing(textField as! PhoneNumberTextField) + onBeginEditing(textField as! UIViewType) } } @@ -318,7 +323,7 @@ public extension iPhoneNumberField { DispatchQueue.main.async { [weak self] in guard let self else { return } displayedText.wrappedValue = "" - onClear(textField as! PhoneNumberTextField) + onClear(textField as! UIViewType) } return true } @@ -326,7 +331,7 @@ public extension iPhoneNumberField { public func textFieldShouldReturn(_ textField: UITextField) -> Bool { DispatchQueue.main.async { [weak self] in guard let self else { return } - onReturn(textField as! PhoneNumberTextField) + onReturn(textField as! UIViewType) } return true } From c314b99cd43524fc6791ecfea96fda3677e0f125 Mon Sep 17 00:00:00 2001 From: Blinov Evgeny Date: Thu, 12 Mar 2026 14:17:51 +0300 Subject: [PATCH 4/6] updated PNK version, removed annoying emojis --- Demo/MultiplatformDemo/ContentView.swift | 51 ++++-- Package.resolved | 4 +- Package.swift | 2 +- Sources/iPhoneNumberField/UIFont+Init.swift | 2 +- .../iPhoneNumberField+ViewModifiers.swift | 154 +++++++++--------- .../iPhoneNumberField/iPhoneNumberField.swift | 54 +++--- 6 files changed, 148 insertions(+), 119 deletions(-) diff --git a/Demo/MultiplatformDemo/ContentView.swift b/Demo/MultiplatformDemo/ContentView.swift index 3bf2dcb..2e1bd85 100644 --- a/Demo/MultiplatformDemo/ContentView.swift +++ b/Demo/MultiplatformDemo/ContentView.swift @@ -18,23 +18,42 @@ struct ContentView: View { .yellow .ignoresSafeArea() .onTapGesture { isEditing = false } - - iPhoneNumberField( - "Title", - text: $text, - isEditing: $isEditing, - formatted: true - ) { - $0.numberPlaceholderColor = .red - $0.textColor = .label - $0.numberPlaceholderColor = .label + VStack { + iPhoneNumberField( + "Title", + text: $text, + isEditing: $isEditing, + formatted: true + ) { + $0.numberPlaceholderColor = .red + $0.textColor = .label + $0.numberPlaceholderColor = .label + } + .defaultRegion("EG") + .onEdit(perform: { + print("onEdit \($0.phoneNumber)") + }) + .onEditingEnded(perform: { + print("onEditingEnded \($0.phoneNumber)") + }) + .onNumberChange(perform: {_ in + print("onNumberCHange") + }) + .padding() + .background( + RoundedRectangle(cornerRadius: 15) + .fill(Color(.secondarySystemGroupedBackground)) + ) + .padding() + } + .onAppear { + text = "+201111112255" + } + Button { + text = "+201111112255" + } label: { + Text("set phone number") } - .padding() - .background( - RoundedRectangle(cornerRadius: 15) - .fill(Color(.secondarySystemGroupedBackground)) - ) - .padding() } } } diff --git a/Package.resolved b/Package.resolved index 39b3815..40dbef9 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/marmelroy/PhoneNumberKit", "state": { "branch": null, - "revision": "ee5d7114934e60812c9b47c333f01b67d002be2d", - "version": "3.7.10" + "revision": "ad20aba8db84a6ba373abfcffe38b1c8e6f8258b", + "version": "4.2.7" } } ] diff --git a/Package.swift b/Package.swift index 0b71121..bdd696a 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( ], dependencies: [ // Dependencies declare other packages that this package depends on. - .package(url: "https://github.com/marmelroy/PhoneNumberKit", .upToNextMajor(from: "3.7.10")) + .package(url: "https://github.com/marmelroy/PhoneNumberKit", .upToNextMajor(from: "4.2.7")) ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. diff --git a/Sources/iPhoneNumberField/UIFont+Init.swift b/Sources/iPhoneNumberField/UIFont+Init.swift index 1d1ff69..1b7b3c6 100644 --- a/Sources/iPhoneNumberField/UIFont+Init.swift +++ b/Sources/iPhoneNumberField/UIFont+Init.swift @@ -16,7 +16,7 @@ public typealias NativeFontDescriptor = UIFontDescriptor #endif public extension NativeFont { - /// Initializes a `UIFont` using the same system initializer syntax available in `Font` ๐Ÿ” ๐Ÿ”ก + /// Initializes a `UIFont` using the same system initializer syntax available in `Font` /// - Parameters: /// - size: The font size as a `CGFloat` /// - weight: Font weight from the `UIFont.Weight` types diff --git a/Sources/iPhoneNumberField/iPhoneNumberField+ViewModifiers.swift b/Sources/iPhoneNumberField/iPhoneNumberField+ViewModifiers.swift index 2b6f7b3..b8f4174 100644 --- a/Sources/iPhoneNumberField/iPhoneNumberField+ViewModifiers.swift +++ b/Sources/iPhoneNumberField/iPhoneNumberField+ViewModifiers.swift @@ -15,10 +15,10 @@ import PhoneNumberKit public extension iPhoneNumberField { - /// Modifies the text fieldโ€™s **font** from a `UIFont` object. ๐Ÿ” ๐Ÿ”ก - /// - Parameter font: The desired font ๐Ÿ…ฐ๏ธ๐Ÿ†— - /// - Returns: An updated text field using the desired font ๐Ÿ’ฌ - /// - Warning: โš ๏ธ Accepts a `UIFont` object rather than SwiftUI `Font` โš ๏ธ + /// Modifies the text fieldโ€™s **font** from a `UIFont` object. + /// - Parameter font: The desired font + /// - Returns: An updated text field using the desired font + /// - Warning: Accepts a `UIFont` object rather than SwiftUI `Font` /// - SeeAlso: [`UIFont`](https://developer.apple.com/documentation/uikit/uifont) func font(_ font: UIFont?) -> Self { var view = self @@ -26,9 +26,9 @@ public extension iPhoneNumberField { return view } - /// Modifies the **text color** ๐ŸŽจ of the text field. - /// - Parameter color: The desired text color ๐ŸŒˆ - /// - Returns: An updated text field using the desired text color ๐Ÿšฆ + /// Modifies the **text color** of the text field. + /// - Parameter color: The desired text color + /// - Returns: An updated text field using the desired text color @available(iOS 14, *) func foregroundColor(_ color: Color?) -> Self { if let color = color { @@ -37,10 +37,10 @@ public extension iPhoneNumberField { return nilForegroundColor() } } - /// Modifies the **text color** ๐ŸŽจ of the text field from a `CGColor` object. - /// - Parameter color: The desired text color ๐ŸŒˆ - /// - Returns: An updated text field using the desired text color ๐Ÿšฆ - /// - Warning: โš ๏ธ Accepts a `CGColor` object rather than SwiftUI `Color` โš ๏ธ + /// Modifies the **text color** of the text field from a `CGColor` object. + /// - Parameter color: The desired text color + /// - Returns: An updated text field using the desired text color + /// - Warning: Accepts a `CGColor` object rather than SwiftUI `Color` /// - SeeAlso: [`CGColor`](https://developer.apple.com/documentation/coregraphics/cgcolor) func foregroundColor(_ color: CGColor?) -> Self { if let color = color { @@ -50,10 +50,10 @@ public extension iPhoneNumberField { } } - /// Modifies the **text color** ๐ŸŽจ of the text field from an `UIColor` object. - /// - Parameter color: The desired text color ๐ŸŒˆ - /// - Returns: An updated text field using the desired text color ๐Ÿšฆ - /// - Warning: โš ๏ธ Accepts a `UIColor` object rather than SwiftUI `Color` โš ๏ธ + /// Modifies the **text color** of the text field from an `UIColor` object. + /// - Parameter color: The desired text color + /// - Returns: An updated text field using the desired text color + /// - Warning: Accepts a `UIColor` object rather than SwiftUI `Color` /// - SeeAlso: [`UIColor`](https://developer.apple.com/documentation/uikit/uicolor) func foregroundColor(_ color: UIColor?) -> Self { var view = self @@ -67,9 +67,9 @@ public extension iPhoneNumberField { return view } - /// Modifies the **placeholder color** ๐ŸŒˆ of the text field. - /// - Parameter color: The placeholder color. ๐ŸŽจ - /// - Returns: A phone number text field with updated placeholder color. ๐Ÿšฅ๐Ÿ– + /// Modifies the **placeholder color** of the text field. + /// - Parameter color: The placeholder color. + /// - Returns: A phone number text field with updated placeholder color. @available(iOS 14, *) func placeholderColor(_ color: Color?) -> Self { self @@ -77,26 +77,26 @@ public extension iPhoneNumberField { .countryCodePlaceholderColor(color) } - /// Modifies the **placeholder color** ๐ŸŒˆ of the text field. - /// - Parameter color: The placeholder color. ๐ŸŽจ - /// - Returns: A phone number text field with updated placeholder color. ๐Ÿšฅ๐Ÿ– + /// Modifies the **placeholder color** of the text field. + /// - Parameter color: The placeholder color. + /// - Returns: A phone number text field with updated placeholder color. func placeholderColor(_ color: UIColor?) -> Self { self .numberPlaceholderColor(color) .countryCodePlaceholderColor(color) } - /// Modifies the **placeholder color** ๐ŸŒˆ of the text field. - /// - Parameter color: The placeholder color. ๐ŸŽจ - /// - Returns: A phone number text field with updated number placeholder color. ๐Ÿšฅ๐Ÿ– + /// Modifies the **placeholder color** of the text field. + /// - Parameter color: The placeholder color. + /// - Returns: A phone number text field with updated number placeholder color. func placeholderColor(_ color: CGColor?) -> Self { self .numberPlaceholderColor(color) .countryCodePlaceholderColor(color) } - /// Modifies the **number placeholder color** ๐ŸŒˆ of the text field. - /// - Parameter color: The placeholder color. ๐ŸŽจ + /// Modifies the **number placeholder color** of the text field. + /// - Parameter color: The placeholder color. /// - Returns: A phone number text field with updated number placeholder color. @available(iOS 14, *) func numberPlaceholderColor(_ color: Color?) -> Self { @@ -107,10 +107,10 @@ public extension iPhoneNumberField { } } - /// Modifies the **number placeholder color** ๐ŸŒˆ of the text field. - /// - Parameter color: The placeholder color. ๐ŸŽจ + /// Modifies the **number placeholder color** of the text field. + /// - Parameter color: The placeholder color. /// - Returns: A phone number text field with updated number placeholder color. - /// - Warning: โš ๏ธ Accepts a `UIColor` object rather than SwiftUI `Color` โš ๏ธ + /// - Warning: Accepts a `UIColor` object rather than SwiftUI `Color` /// - SeeAlso: [`UIFont`](https://developer.apple.com/documentation/uikit/uicolor) func numberPlaceholderColor(_ color: UIColor?) -> Self { var view = self @@ -118,10 +118,10 @@ public extension iPhoneNumberField { return view } - /// Modifies the **number placeholder color** ๐ŸŒˆ of the text field. - /// - Parameter color: The number placeholder color. ๐ŸŽจ + /// Modifies the **number placeholder color** of the text field. + /// - Parameter color: The number placeholder color. /// - Returns: A phone number text field with updated number placeholder color. - /// - Warning: โš ๏ธ Accepts a `CGColor` object rather than SwiftUI `Color` โš ๏ธ + /// - Warning: Accepts a `CGColor` object rather than SwiftUI `Color` /// - SeeAlso: [`UIFont`](https://developer.apple.com/documentation/coregraphics/cgcolor) func numberPlaceholderColor(_ color: CGColor?) -> Self { if let color = color { @@ -131,8 +131,8 @@ public extension iPhoneNumberField { } } - /// Modifies the **country code placeholder color** ๐ŸŒˆ of the text field. - /// - Parameter color: The country code placeholder color ๐ŸŽจ + /// Modifies the **country code placeholder color** of the text field. + /// - Parameter color: The country code placeholder color /// - Returns: A phone number text field with updated country code placeholder color @available(iOS 14, *) func countryCodePlaceholderColor(_ color: Color?) -> Self { @@ -143,10 +143,10 @@ public extension iPhoneNumberField { } } - /// Modifies the **country code placeholder color** ๐ŸŒˆ of the text field. - /// - Parameter color: The country code placeholder color ๐ŸŽจ + /// Modifies the **country code placeholder color** of the text field. + /// - Parameter color: The country code placeholder color /// - Returns: A phone number text field with updated country code placeholder color - /// - Warning: โš ๏ธ Accepts a `UIColor` object rather than SwiftUI `Color` โš ๏ธ + /// - Warning: Accepts a `UIColor` object rather than SwiftUI `Color` /// - SeeAlso: [`UIFont`](https://developer.apple.com/documentation/uikit/uicolor) func countryCodePlaceholderColor(_ color: UIColor?) -> Self { var view = self @@ -154,10 +154,10 @@ public extension iPhoneNumberField { return view } - /// Modifies the **country code placeholder color** ๐ŸŒˆ of the text field. - /// - Parameter color: The country code placeholder color ๐ŸŽจ + /// Modifies the **country code placeholder color** of the text field. + /// - Parameter color: The country code placeholder color /// - Returns: A phone number text field with updated country code placeholder color - /// - Warning: โš ๏ธ Accepts a `CGColor` object rather than SwiftUI `Font` โš ๏ธ + /// - Warning: Accepts a `CGColor` object rather than SwiftUI `Font` /// - SeeAlso: [`UIFont`](https://developer.apple.com/documentation/coregraphics/cgcolor) func countryCodePlaceholderColor(_ color: CGColor?) -> Self { if let color = color { @@ -183,9 +183,9 @@ public extension iPhoneNumberField { return self } - /// Modifies the **text alignment** of a text field. โฌ…๏ธ โ†”๏ธ โžก๏ธ - /// - Parameter alignment: The desired text alignment ๐Ÿ‘ˆ๐Ÿ‘‰ - /// - Returns: An updated text field using the desired text alignment โ†ฉ๏ธโ†ช๏ธ + /// Modifies the **text alignment** of a text field. + /// - Parameter alignment: The desired text alignment + /// - Returns: An updated text field using the desired text alignment func multilineTextAlignment(_ alignment: TextAlignment) -> Self { var view = self switch alignment { @@ -199,16 +199,16 @@ public extension iPhoneNumberField { return view } - /// Modifies the **clear-on-begin-editing** setting of a text field. โŒโ–ถ๏ธ - /// - Parameter shouldClear: Whether the text field should clear on editing beginning ๐Ÿ“ญ๐Ÿ - /// - Returns: A text field with updated clear-on-begin-editing settings ๐Ÿ” + /// Modifies the **clear-on-begin-editing** setting of a text field. + /// - Parameter shouldClear: Whether the text field should clear on editing beginning + /// - Returns: A text field with updated clear-on-begin-editing settings func clearsOnEditingBegan(_ shouldClear: Bool) -> Self { var view = self view.clearsOnBeginEditing = shouldClear return view } - /// Modifies the **clear-on-insertion** setting of a text field. ๐Ÿ‘† + /// Modifies the **clear-on-insertion** setting of a text field. /// - Parameter shouldClear: Whether the text field should clear on insertion /// - Returns: A text field with updated clear-on-insertion settings func clearsOnInsert(_ shouldClear: Bool) -> Self { @@ -217,7 +217,7 @@ public extension iPhoneNumberField { return view } - /// Modifies whether and when the text field **clear button** appears on the view. โญ•๏ธ โŒ + /// Modifies whether and when the text field **clear button** appears on the view. /// - Parameter showsButton: Whether the clear button should be visible. /// - Returns: A text field with updated clear button settings. func clearButtonMode(_ mode: UITextField.ViewMode) -> Self { @@ -226,7 +226,7 @@ public extension iPhoneNumberField { return view } - /// Modifies the style of the text field. โ˜‘๏ธ + /// Modifies the style of the text field. /// - Parameter style: The text field style. /// - Returns: A text field with the updated style. func textFieldStyle(_ style: UITextField.BorderStyle) -> Self { @@ -235,7 +235,7 @@ public extension iPhoneNumberField { return view } - /// Modifies the maximum number of digits the text field allows. ๐Ÿ”Ÿ + /// Modifies the maximum number of digits the text field allows. /// - Parameter max: The maximum number of digits in the text field. /// - Returns: A text field with the updated maximum digits settings. func maximumDigits(_ max: Int?) -> Self { @@ -244,7 +244,7 @@ public extension iPhoneNumberField { return view } - /// Modifies whether the text field hides the country flag on the left. ๐Ÿ‡ฆ๐Ÿ‡ถ + /// Modifies whether the text field hides the country flag on the left. /// - Parameter hidden: Whether the text field hides the flag. /// - Returns: A text field with the updated flag visibility. func flagHidden(_ hidden: Bool) -> Self { @@ -253,7 +253,7 @@ public extension iPhoneNumberField { return view } - /// Modifies whether the flag is selectable. ๐Ÿ‡ธ๐Ÿ‡ฎ + /// Modifies whether the flag is selectable. /// When set to `true`, tapping on the flag will pull up a sheet allowing the user to select a flag. /// - Parameter selectable: Whether the flag is selectable. /// - Returns: A text field with the updated flag-selectability settings. @@ -263,7 +263,7 @@ public extension iPhoneNumberField { return view } - /// Modifies whether the country code prefix should be hidden. โž•1๏ธโƒฃ + /// Modifies whether the country code prefix should be hidden. /// - Parameter hidden: Whether the country code prefix should be hidden. /// - Returns: A text field with the updated prefix settings. func prefixHidden(_ hidden: Bool) -> Self { @@ -272,7 +272,7 @@ public extension iPhoneNumberField { return view } - /// Modifies whether the country code prefix should be autofilled. โž•1๏ธโƒฃ + /// Modifies whether the country code prefix should be autofilled. /// - Parameter hidden: Whether the country code prefix should be hidden. /// - Returns: A text field with the updated prefix settings. func autofillPrefix(_ autofill: Bool) -> Self { @@ -281,7 +281,7 @@ public extension iPhoneNumberField { return view } - /// Modifies the default prefix of the number. โž•9๏ธโƒฃ8๏ธโƒฃ + /// Modifies the default prefix of the number. /// - Parameter region: The region that the textField uses to show the default number prefix. Defaulted to the device's current region. /// - Returns: A text field with the updated prefix settings. /// - Note: Use `showPrefix` modifier to change prefix visibility. @@ -291,51 +291,59 @@ public extension iPhoneNumberField { return view } - /// Modifies the function called when text editing **begins**. โ–ถ๏ธ + /// Modifies the function called when text editing **begins**. /// - Parameter action: The action to perform. If `action` is `nil`, the call has no effect. - /// - Returns: An updated text field using the desired function called when text editing begins โžก๏ธ + /// - Returns: An updated text field using the desired function called when text editing begins func onEditingBegan(perform action: ((UIViewType) -> ())? = nil) -> Self { var view = self - if let action = action { - view.onBeginEditingHandler = action + if let action { + DispatchQueue.main.async { + view.onBeginEditingHandler = action + } } return view } - /// Modifies the function called when the user makes any **changes** to the text in the text field. ๐Ÿ’ฌ + /// Modifies the function called when the user makes any **changes** to the text in the text field. /// - Parameter action: The action to perform. If `action` is `nil`, the call has no effect. - /// - Returns: An updated text field using the desired function called when the user makes any changes to the text in the text field ๐Ÿ”„ + /// - Returns: An updated text field using the desired function called when the user makes any changes to the text in the text field func onNumberChange(perform action: ((PhoneNumber?) -> ())? = nil) -> Self { var view = self - if let action = action { - view.onPhoneNumberChangeHandler = action + if let action { + DispatchQueue.main.async { + view.onPhoneNumberChangeHandler = action + } } return view } - /// Modifies the function called when the user makes any **changes** to the text in the text field. ๐Ÿ’ฌ + /// Modifies the function called when the user makes any **changes** to the text in the text field. /// - Parameter action: The action to perform. If `action` is `nil`, the call has no effect. - /// - Returns: An updated text field using the desired function called when the user makes any changes to the text in the text field ๐Ÿ”„ + /// - Returns: An updated text field using the desired function called when the user makes any changes to the text in the text field func onEdit(perform action: ((UIViewType) -> ())? = nil) -> Self { var view = self - if let action = action { - view.onEditingChangeHandler = action + if let action { + DispatchQueue.main.async { + view.onEditingChangeHandler = action + } } return view } - /// Modifies the function called when text editing **ends**. ๐Ÿ”š + /// Modifies the function called when text editing **ends**. /// - Parameter action: The action to perform. If `action` is `nil`, the call has no effect. - /// - Returns: An updated text field using the desired function called when text editing ends โœ‹ + /// - Returns: An updated text field using the desired function called when text editing ends func onEditingEnded(perform action: ((UIViewType) -> ())? = nil) -> Self { var view = self - if let action = action { - view.onEndEditingHandler = action + if let action { + DispatchQueue.main.async { + view.onEndEditingHandler = action + } } return view } - /// Modifies the function called when the user clears the text field. โŒ + /// Modifies the function called when the user clears the text field. /// - Parameter action: The action to perform. If `action` is `nil`, the call has no effect. /// - Returns: An updated text field using the desired function called when the user clears the text field. func onClear(perform action: ((PhoneNumberTextField) -> Void)? = nil) -> Self { @@ -346,7 +354,7 @@ public extension iPhoneNumberField { return view } - /// Modifies the function called when the user presses return. โ†ช๏ธ + /// Modifies the function called when the user presses return. /// - Parameter action: The action to perform. If `action` is `nil`, the call has no effect. /// - Returns: An updated text field using the desired function called when the user presses the return key. func onReturn(perform action: ((PhoneNumberTextField) -> Void)? = nil) -> Self { diff --git a/Sources/iPhoneNumberField/iPhoneNumberField.swift b/Sources/iPhoneNumberField/iPhoneNumberField.swift index 5c97a58..bcb2263 100644 --- a/Sources/iPhoneNumberField/iPhoneNumberField.swift +++ b/Sources/iPhoneNumberField/iPhoneNumberField.swift @@ -30,7 +30,7 @@ public struct iPhoneNumberField: UIViewRepresentable { /// This variable is used only if an `isEditing` binding was not provided in the initializer. @State private var internalIsFirstResponder: Bool = false - /// Whether or not the phone number field is editing. ๐Ÿ’ฌ + /// Whether or not the phone number field is editing. /// This variable uses `externalIsFirstResponder` binding variable if an `isEditing` binding was provided in the initializer, otherwise it uses the `internalIsFirstResponder` state variable. private var isFirstResponder: Bool { get { externalIsFirstResponder?.wrappedValue ?? internalIsFirstResponder } @@ -43,38 +43,38 @@ public struct iPhoneNumberField: UIViewRepresentable { } } - /// The maximum number of digits the phone number field allows. ๐Ÿ”ข + /// The maximum number of digits the phone number field allows. internal var maxDigits: Int? - /// The font of the phone number field. ๐Ÿ”ก + /// The font of the phone number field. internal var font: UIFont? - /// The phone number field's "clear button" mode. ๐Ÿšซ + /// The phone number field's "clear button" mode. internal var clearButtonMode: UITextField.ViewMode = .never /// The text displayed in the phone number field when no number has been typed yet. /// Setting this `nil` will display a default phone number as the placeholder. private let placeholder: String? - /// Whether the country flag should be displayed in the phone number field. ๐Ÿ‡ฆ๐Ÿ‡ถ + /// Whether the country flag should be displayed in the phone number field. internal var showFlag: Bool = false - /// Whether tapping the flag should show a sheet containing all of the country flags. ๐Ÿดโ€โ˜ ๏ธ + /// Whether tapping the flag should show a sheet containing all of the country flags. internal var selectableFlag: Bool = false - /// Whether the country code should be automatically filled for the end user. โž• + /// Whether the country code should be automatically filled for the end user. internal var autofillPrefix: Bool = false - /// Whether the country code should be automatically displayed for the end user. ๐ŸŽ“ + /// Whether the country code should be automatically displayed for the end user. internal var previewPrefix: Bool = false - /// Change the default prefix number by setting the region. ๐Ÿ‡ฎ๐Ÿ‡ท + /// Change the default prefix number by setting the region. internal var defaultRegion: String? - /// The color of the text of the phone number field. ๐ŸŽจ + /// The color of the text of the phone number field. internal var textColor: UIColor? - /// The color of the phone number field's cursor and highlighting. ๐Ÿ– + /// The color of the phone number field's cursor and highlighting. internal var accentColor: UIColor? /// The color of the number (excluding country code) portion of the placeholder. @@ -83,7 +83,7 @@ public struct iPhoneNumberField: UIViewRepresentable { /// The color of the country code portion of the placeholder color. internal var countryCodePlaceholderColor: UIColor? - /// The visual style of the phone number field. ๐ŸŽ€ + /// The visual style of the phone number field. /// For now, this uses `UITextField.BorderStyle`. Updates on this modifier to come. internal var borderStyle: UITextField.BorderStyle = .none @@ -93,54 +93,54 @@ public struct iPhoneNumberField: UIViewRepresentable { /// When set to `true`, the binding displays exactly what is in the text field. internal var formatted: Bool = true - /// An action to perform when editing on the phone number field begins. โ–ถ๏ธ + /// An action to perform when editing on the phone number field begins. /// The closure requires a `UIViewType` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. internal var onBeginEditingHandler = { (view: UIViewType) in } - /// An action to perform when any characters in the phone number field are changed. ๐Ÿ’ฌ + /// An action to perform when any characters in the phone number field are changed. /// The closure requires a `UIViewType` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. internal var onEditingChangeHandler = { (view: UIViewType) in } - /// An action to perform when any characters in the phone number field are changed. โ˜Ž๏ธ + /// An action to perform when any characters in the phone number field are changed. /// The closure requires a `PhoneNumber` parameter, that you can change each time this is called, if desired. internal var onPhoneNumberChangeHandler = { (phoneNumber: PhoneNumber?) in } - /// An action to perform when editing on the phone number field ends. โน + /// An action to perform when editing on the phone number field ends. /// The closure requires a `UIViewType` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. internal var onEndEditingHandler = { (view: UIViewType) in } - /// An action to perform when the phone number field is cleared. โŒ + /// An action to perform when the phone number field is cleared. /// The closure requires a `UIViewType` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. internal var onClearHandler = { (view: UIViewType) in } - /// An action to perform when the return key on the phone number field is pressed. โ†ช๏ธ + /// An action to perform when the return key on the phone number field is pressed. /// The closure requires a `UIViewType` parameter, which is the underlying `UIView`, that you can change each time this is called, if desired. internal var onReturnHandler = { (view: UIViewType) in } - /// A closure that requires a `UIViewType` object to be configured in the body. โš™๏ธ + /// A closure that requires a `UIViewType` object to be configured in the body. public var configuration = { (view: UIViewType) in } @Environment(\.layoutDirection) internal var layoutDirection: LayoutDirection /// The horizontal alignment of the phone number field. internal var textAlignment: NSTextAlignment? - /// Whether the phone number field clears when editing begins. ๐ŸŽฌ + /// Whether the phone number field clears when editing begins. internal var clearsOnBeginEditing = false - /// Whether the phone number field clears when text is inserted. ๐Ÿ‘† + /// Whether the phone number field clears when text is inserted. internal var clearsOnInsertion = false - /// Whether the phone number field is enabled for interaction. โœ… + /// Whether the phone number field is enabled for interaction. internal var isUserInteractionEnabled = true - internal var phoneNumberKit: PhoneNumberKit + internal var phoneNumberKit: PhoneNumberUtility public init( _ title: String? = nil, text: Binding, isEditing: Binding? = nil, formatted: Bool = true, - phoneNumberKit: PhoneNumberKit = PhoneNumberKit(), + phoneNumberKit: PhoneNumberUtility = PhoneNumberUtility(), configuration: @escaping (UIViewType) -> () = { _ in } ) { self.placeholder = title @@ -153,7 +153,7 @@ public struct iPhoneNumberField: UIViewRepresentable { } public func makeUIView(context: UIViewRepresentableContext) -> UIViewType { - let uiView = UIViewType(withPhoneNumberKit: phoneNumberKit) + let uiView = UIViewType(utility: phoneNumberKit) uiView.setContentHuggingPriority(.defaultHigh, for: .vertical) uiView.addTarget(context.coordinator, @@ -188,7 +188,9 @@ public struct iPhoneNumberField: UIViewRepresentable { uiView.withFlag = showFlag uiView.withDefaultPickerUI = selectableFlag uiView.withPrefix = previewPrefix - uiView.partialFormatter.defaultRegion = defaultRegion ?? PhoneNumberKit.defaultRegionCode() + if let defaultRegion { + uiView.partialFormatter.defaultRegion = defaultRegion + } if placeholder != nil { uiView.placeholder = placeholder } else { From 1c675aa95be447081cb43e252714e69488ce27dc Mon Sep 17 00:00:00 2001 From: Blinov Evgeny Date: Fri, 13 Mar 2026 15:46:04 +0300 Subject: [PATCH 5/6] fixed callback --- Sources/iPhoneNumberField/iPhoneNumberField.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/iPhoneNumberField/iPhoneNumberField.swift b/Sources/iPhoneNumberField/iPhoneNumberField.swift index bcb2263..6bfad03 100644 --- a/Sources/iPhoneNumberField/iPhoneNumberField.swift +++ b/Sources/iPhoneNumberField/iPhoneNumberField.swift @@ -317,7 +317,7 @@ public extension iPhoneNumberField { DispatchQueue.main.async { [weak self] in guard let self else { return } isFirstResponder.wrappedValue = false - onBeginEditing(textField as! UIViewType) + onEndEditing(textField as! UIViewType) } } From 556f4d398bac99178ed3a5cea1386f96f427ae78 Mon Sep 17 00:00:00 2001 From: Blinov Evgeny Date: Fri, 13 Mar 2026 17:15:40 +0300 Subject: [PATCH 6/6] do not execute on main --- .../iPhoneNumberField+ViewModifiers.swift | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/Sources/iPhoneNumberField/iPhoneNumberField+ViewModifiers.swift b/Sources/iPhoneNumberField/iPhoneNumberField+ViewModifiers.swift index b8f4174..e7bf948 100644 --- a/Sources/iPhoneNumberField/iPhoneNumberField+ViewModifiers.swift +++ b/Sources/iPhoneNumberField/iPhoneNumberField+ViewModifiers.swift @@ -297,9 +297,7 @@ public extension iPhoneNumberField { func onEditingBegan(perform action: ((UIViewType) -> ())? = nil) -> Self { var view = self if let action { - DispatchQueue.main.async { - view.onBeginEditingHandler = action - } + view.onBeginEditingHandler = action } return view } @@ -310,9 +308,7 @@ public extension iPhoneNumberField { func onNumberChange(perform action: ((PhoneNumber?) -> ())? = nil) -> Self { var view = self if let action { - DispatchQueue.main.async { - view.onPhoneNumberChangeHandler = action - } + view.onPhoneNumberChangeHandler = action } return view } @@ -323,9 +319,7 @@ public extension iPhoneNumberField { func onEdit(perform action: ((UIViewType) -> ())? = nil) -> Self { var view = self if let action { - DispatchQueue.main.async { - view.onEditingChangeHandler = action - } + view.onEditingChangeHandler = action } return view } @@ -336,9 +330,7 @@ public extension iPhoneNumberField { func onEditingEnded(perform action: ((UIViewType) -> ())? = nil) -> Self { var view = self if let action { - DispatchQueue.main.async { - view.onEndEditingHandler = action - } + view.onEndEditingHandler = action } return view } @@ -348,7 +340,7 @@ public extension iPhoneNumberField { /// - Returns: An updated text field using the desired function called when the user clears the text field. func onClear(perform action: ((PhoneNumberTextField) -> Void)? = nil) -> Self { var view = self - if let action = action { + if let action { view.onClearHandler = action } return view @@ -359,7 +351,7 @@ public extension iPhoneNumberField { /// - Returns: An updated text field using the desired function called when the user presses the return key. func onReturn(perform action: ((PhoneNumberTextField) -> Void)? = nil) -> Self { var view = self - if let action = action { + if let action { view.onReturnHandler = action } return view