Thank you Roman Filippov...
**
//MacOS
**
Phone Number Field for playing with... Just copy and paste into New Project...
AutoFill Leading digit(s) (ie +1)
Formatting after is Country-specific
import SwiftUI
@main
struct phoneField: App {
var body: some Scene {
WindowGroup {
TJH1()
}
}
}
struct PhoneNumberFormat {
let leadingDigits: String
let format: String
let textFieldMaxChar: Int
}func phoneNumberFormats() -> [String: PhoneNumberFormat] {
let formats = [
"United States": PhoneNumberFormat(leadingDigits: "+1", format: "+X (XXX) XXX-XXXX", textFieldMaxChar: 11),
"Argentina": PhoneNumberFormat(leadingDigits: "+54", format: "+XX (X) XXXX-XXXX", textFieldMaxChar: 11),
"Australia": PhoneNumberFormat(leadingDigits: "+61", format: "+XX (X) XXXX XXXX", textFieldMaxChar: 11),
"Brazil": PhoneNumberFormat(leadingDigits: "+55", format: "+XX (XX) XXXX-XXXX", textFieldMaxChar: 12),
"Canada": PhoneNumberFormat(leadingDigits: "+1", format: "+X (XXX) XXX-XXXX", textFieldMaxChar: 11),
"China": PhoneNumberFormat(leadingDigits: "+86", format: "+XX (XXX) XXXX-XXXX", textFieldMaxChar: 13),
"France": PhoneNumberFormat(leadingDigits: "+33", format: "+XX (X) XX XX XX XX", textFieldMaxChar: 11),
"Germany": PhoneNumberFormat(leadingDigits: "+49", format: "+XX (XXX) XXXXXXX", textFieldMaxChar: 12),
"India": PhoneNumberFormat(leadingDigits: "+91", format: "+XX XXXXX-XXXXX", textFieldMaxChar: 12),
"Italy": PhoneNumberFormat(leadingDigits: "+39", format: "+XX (XXX) XXXXXXX", textFieldMaxChar: 12),
"Japan": PhoneNumberFormat(leadingDigits: "+81", format: "+XX (X) XXXX-XXXX", textFieldMaxChar: 11),
"Mexico": PhoneNumberFormat(leadingDigits: "+52", format: "+XX (X) XXXX XXXX", textFieldMaxChar: 11),
"Netherlands": PhoneNumberFormat(leadingDigits: "+31", format: "+XX (X) XXXX XXXX", textFieldMaxChar: 11),
"New Zealand": PhoneNumberFormat(leadingDigits: "+64", format: "+XX (X) XXXX XXXX", textFieldMaxChar: 11),
"Russia": PhoneNumberFormat(leadingDigits: "+7", format: "+X (XXX) XXX-XX-XX", textFieldMaxChar: 11),
"Saudi Arabia": PhoneNumberFormat(leadingDigits: "+966", format: "+XXX (X) XXX-XXXX", textFieldMaxChar: 11),
"Singapore": PhoneNumberFormat(leadingDigits: "+65", format: "+XX XXXX XXXX", textFieldMaxChar: 10),
"South Africa": PhoneNumberFormat(leadingDigits: "+27", format: "+XX (X) XXX XXXX", textFieldMaxChar: 10),
"South Korea": PhoneNumberFormat(leadingDigits: "+82", format: "+XX (XX) XXXX-XXXX", textFieldMaxChar: 12),
"Spain": PhoneNumberFormat(leadingDigits: "+34", format: "+XX XXX XXX XXX", textFieldMaxChar: 11),
"Sweden": PhoneNumberFormat(leadingDigits: "+46", format: "+XX (X) XXXX-XXXX", textFieldMaxChar: 11),
"Switzerland": PhoneNumberFormat(leadingDigits: "+41", format: "+XX (XX) XXX XX XX", textFieldMaxChar: 11),
"Turkey": PhoneNumberFormat(leadingDigits: "+90", format: "+XX (XXX) XXX-XXXX", textFieldMaxChar: 12),
"United Arab Emirates": PhoneNumberFormat(leadingDigits: "+971", format: "+XXX (X) XXX-XXXX", textFieldMaxChar: 11),
"United Kingdom": PhoneNumberFormat(leadingDigits: "+44", format: "+XX (X) XXXX XXX", textFieldMaxChar: 10),
]
return formats
}
struct TJH1: View {
@State private var PNField: String = ""
@State private var selectedCountry = "United States"
func maskFormat(with mask: String, phone: String) -> String {
let numbers = phone.replacingOccurrences(of: "[^0-9]", with: "", options: .regularExpression)
var result = ""
var index = numbers.startIndex
var maskIndex = mask.startIndex
while index < numbers.endIndex && maskIndex < mask.endIndex {
let maskChar = mask[maskIndex]
let numberChar = numbers[index]
if maskChar == "X" {
result.append(numberChar)
index = numbers.index(after: index)
} else {
result.append(maskChar)
}
maskIndex = mask.index(after: maskIndex)
}
return result
}
var countries: [String] {
Array(phoneNumberFormats().keys).sorted()
}
var body: some View {
GeometryReader { geometry in
VStack {
TextField("", text: $PNField, onEditingChanged: { begin in })
.onChange(of: PNField) { newValue in
PNField = maskFormat(with: phoneNumberFormats()[selectedCountry]!.format, phone: newValue)
if PNField.filter({ $0.isNumber }).count <= (phoneNumberFormats()[selectedCountry]!.leadingDigits.filter({ $0.isNumber }).count) {
let regex = try? NSRegularExpression(pattern: "[^0-9]+")
let matches = regex?.matches(in: newValue, options: [], range: NSRange(location: 0, length: newValue.count))
let count = matches?.count ?? 0
if count != 0 {
PNField = phoneNumberFormats()[selectedCountry]!.leadingDigits
} else {
PNField = phoneNumberFormats()[selectedCountry]!.leadingDigits + newValue
}
}
}
Picker("Country", selection: $selectedCountry) {
ForEach(countries, id: \.self) { country in
Text(country)
.pickerStyle(.menu)
.onChange(of: selectedCountry) { newValue in
PNField = ""
}
}
}
}
}
}
}
struct TJH1_Previews: PreviewProvider {
static var previews: some View {
TJH1()
}
}
//iOS App
Phone Number Field for playing with... Just copy and Past into New Project...
AutoFill Leading digit(s) (ie +1)
Formatting after is Country-specific
import SwiftUI
@main
struct TOPPS_PizzaApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct PhoneNumberFormat {
let leadingDigits: String
let format: String
let textFieldMaxChar: Int
}
func phoneNumberFormats() -> [String: PhoneNumberFormat] {
let formats = [
"United States": PhoneNumberFormat(leadingDigits: "+1", format: "+X (XXX) XXX-XXXX", textFieldMaxChar: 11),
"Argentina": PhoneNumberFormat(leadingDigits: "+54", format: "+XX (X) XXXX-XXXX", textFieldMaxChar: 11),
"Australia": PhoneNumberFormat(leadingDigits: "+61", format: "+XX (X) XXXX XXXX", textFieldMaxChar: 11),
"Brazil": PhoneNumberFormat(leadingDigits: "+55", format: "+XX (XX) XXXX-XXXX", textFieldMaxChar: 12),
"Canada": PhoneNumberFormat(leadingDigits: "+1", format: "+X (XXX) XXX-XXXX", textFieldMaxChar: 11),
"China": PhoneNumberFormat(leadingDigits: "+86", format: "+XX (XXX) XXXX-XXXX", textFieldMaxChar: 13),
"France": PhoneNumberFormat(leadingDigits: "+33", format: "+XX (X) XX XX XX XX", textFieldMaxChar: 11),
"Germany": PhoneNumberFormat(leadingDigits: "+49", format: "+XX (XXX) XXXXXXX", textFieldMaxChar: 12),
"India": PhoneNumberFormat(leadingDigits: "+91", format: "+XX XXXXX-XXXXX", textFieldMaxChar: 12),
"Italy": PhoneNumberFormat(leadingDigits: "+39", format: "+XX (XXX) XXXXXXX", textFieldMaxChar: 12),
"Japan": PhoneNumberFormat(leadingDigits: "+81", format: "+XX (X) XXXX-XXXX", textFieldMaxChar: 11),
"Mexico": PhoneNumberFormat(leadingDigits: "+52", format: "+XX (X) XXXX XXXX", textFieldMaxChar: 11),
"Netherlands": PhoneNumberFormat(leadingDigits: "+31", format: "+XX (X) XXXX XXXX", textFieldMaxChar: 11),
"New Zealand": PhoneNumberFormat(leadingDigits: "+64", format: "+XX (X) XXXX XXXX", textFieldMaxChar: 11),
"Russia": PhoneNumberFormat(leadingDigits: "+7", format: "+X (XXX) XXX-XX-XX", textFieldMaxChar: 11),
"Saudi Arabia": PhoneNumberFormat(leadingDigits: "+966", format: "+XXX (X) XXX-XXXX", textFieldMaxChar: 11),
"Singapore": PhoneNumberFormat(leadingDigits: "+65", format: "+XX XXXX XXXX", textFieldMaxChar: 10),
"South Africa": PhoneNumberFormat(leadingDigits: "+27", format: "+XX (X) XXX XXXX", textFieldMaxChar: 10),
"South Korea": PhoneNumberFormat(leadingDigits: "+82", format: "+XX (XX) XXXX-XXXX", textFieldMaxChar: 12),
"Spain": PhoneNumberFormat(leadingDigits: "+34", format: "+XX XXX XXX XXX", textFieldMaxChar: 11),
"Sweden": PhoneNumberFormat(leadingDigits: "+46", format: "+XX (X) XXXX-XXXX", textFieldMaxChar: 11),
"Switzerland": PhoneNumberFormat(leadingDigits: "+41", format: "+XX (XX) XXX XX XX", textFieldMaxChar: 11),
"Turkey": PhoneNumberFormat(leadingDigits: "+90", format: "+XX (XXX) XXX-XXXX", textFieldMaxChar: 12),
"United Arab Emirates": PhoneNumberFormat(leadingDigits: "+971", format: "+XXX (X) XXX-XXXX", textFieldMaxChar: 11),
"United Kingdom": PhoneNumberFormat(leadingDigits: "+44", format: "+XX (X) XXXX XXX", textFieldMaxChar: 10),
]
return formats
}
struct ContentView: View {
@State private var PNField: String = ""
@State private var selectedCountry = "United States"
func maskFormat(with mask: String, phone: String) -> String {
let numbers = phone.replacingOccurrences(of: "[^0-9]", with: "", options: .regularExpression)
var result = ""
var index = numbers.startIndex
var maskIndex = mask.startIndex
while index < numbers.endIndex && maskIndex < mask.endIndex {
let maskChar = mask[maskIndex]
let numberChar = numbers[index]
if maskChar == "X" {
result.append(numberChar)
index = numbers.index(after: index)
} else {
result.append(maskChar)
}
maskIndex = mask.index(after: maskIndex)
}
return result
}
var countries: [String] {
Array(phoneNumberFormats().keys).sorted()
}
var body: some View {
VStack {
TextField("", text: $PNField, onEditingChanged: { begin in })
.overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.black, lineWidth: 0.5))
.onChange(of: PNField) { newValue in
PNField = maskFormat(with: phoneNumberFormats()[selectedCountry]!.format, phone: newValue)
if PNField.filter({ $0.isNumber }).count <= (phoneNumberFormats()[selectedCountry]!.leadingDigits.filter({ $0.isNumber }).count) {
let regex = try? NSRegularExpression(pattern: "[^0-9]+")
let matches = regex?.matches(in: newValue, options: [], range: NSRange(location: 0, length: newValue.count))
let count = matches?.count ?? 0
if count != 0 {
PNField = phoneNumberFormats()[selectedCountry]!.leadingDigits
} else {
PNField = phoneNumberFormats()[selectedCountry]!.leadingDigits + newValue
}
}
}
Picker("Country", selection: $selectedCountry) {
ForEach(countries, id: \.self) { country in
Text(country)
.onChange(of: selectedCountry) { newValue in
PNField = ""
}
}
}
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}