diff --git a/MultiplatformDemo/MultiplatformDemo/Assets.xcassets/AccentColor.colorset/Contents.json b/Demo/MultiplatformDemo/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from MultiplatformDemo/MultiplatformDemo/Assets.xcassets/AccentColor.colorset/Contents.json rename to Demo/MultiplatformDemo/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/MultiplatformDemo/MultiplatformDemo/Assets.xcassets/AppIcon.appiconset/Contents.json b/Demo/MultiplatformDemo/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from MultiplatformDemo/MultiplatformDemo/Assets.xcassets/AppIcon.appiconset/Contents.json rename to Demo/MultiplatformDemo/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/MultiplatformDemo/MultiplatformDemo/Assets.xcassets/Contents.json b/Demo/MultiplatformDemo/Assets.xcassets/Contents.json similarity index 100% rename from MultiplatformDemo/MultiplatformDemo/Assets.xcassets/Contents.json rename to Demo/MultiplatformDemo/Assets.xcassets/Contents.json diff --git a/MultiplatformDemo/MultiplatformDemo/ContentView.swift b/Demo/MultiplatformDemo/ContentView.swift similarity index 83% rename from MultiplatformDemo/MultiplatformDemo/ContentView.swift rename to Demo/MultiplatformDemo/ContentView.swift index ff3bdc5..3bf2dcb 100644 --- a/MultiplatformDemo/MultiplatformDemo/ContentView.swift +++ b/Demo/MultiplatformDemo/ContentView.swift @@ -30,6 +30,11 @@ struct ContentView: View { $0.numberPlaceholderColor = .label } .padding() + .background( + RoundedRectangle(cornerRadius: 15) + .fill(Color(.secondarySystemGroupedBackground)) + ) + .padding() } } } diff --git a/Demo/MultiplatformDemo/GitHubIssues/issue118.swift b/Demo/MultiplatformDemo/GitHubIssues/issue118.swift new file mode 100644 index 0000000..0d47c30 --- /dev/null +++ b/Demo/MultiplatformDemo/GitHubIssues/issue118.swift @@ -0,0 +1,21 @@ +import SwiftUI +import iPhoneNumberField + +struct Issue118: View { + @State private var phoneNumber = "" + @State private var selectedCountry: String = "US" + + var body: some View { + iPhoneNumberField("Phone Number", text: $phoneNumber) + .flagSelectable(true) + .defaultRegion(selectedCountry) + .formatted(true) + .prefixHidden(false) + .flagHidden(false) + } +} + +#Preview { + Issue118() + .padding() +} diff --git a/Demo/MultiplatformDemo/GitHubIssues/issue119.swift b/Demo/MultiplatformDemo/GitHubIssues/issue119.swift new file mode 100644 index 0000000..306bbba --- /dev/null +++ b/Demo/MultiplatformDemo/GitHubIssues/issue119.swift @@ -0,0 +1,17 @@ +import SwiftUI +import iPhoneNumberField + +/// Issue: When applying placeholderColor modifier, nothing happens. Placeholder color always the same. +/// +/// This issue is due to a dependency. There is another PR for this [here](https://github.com/marmelroy/PhoneNumberKit/issues/831) +struct Issue119: View { + var body: some View { + iPhoneNumberField("Phone Number", text: .constant("")) + .placeholderColor(Color.red) + } +} + +#Preview { + Issue119() + .padding() +} diff --git a/MultiplatformDemo/MultiplatformDemo/MultiplatformDemo.entitlements b/Demo/MultiplatformDemo/MultiplatformDemo.entitlements similarity index 100% rename from MultiplatformDemo/MultiplatformDemo/MultiplatformDemo.entitlements rename to Demo/MultiplatformDemo/MultiplatformDemo.entitlements diff --git a/Demo/MultiplatformDemo/MultiplatformDemoApp.swift b/Demo/MultiplatformDemo/MultiplatformDemoApp.swift new file mode 100644 index 0000000..ce20b92 --- /dev/null +++ b/Demo/MultiplatformDemo/MultiplatformDemoApp.swift @@ -0,0 +1,27 @@ +// +// MultiplatformDemoApp.swift +// MultiplatformDemo +// +// Created by Seyed Mojtaba Hosseini Zeidabadi on 8/8/22. +// + +import SwiftUI + +@main +struct MultiplatformDemoApp: App { + private let issue: String? + + init() { + let argument = ProcessInfo.processInfo.arguments.first { $0.hasPrefix("UIT-GHI-") } + self.issue = argument?.split(separator: "-").map(String.init).last + } + + var body: some Scene { + WindowGroup { + switch issue { + case "118": Issue118() + default: ContentView() + } + } + } +} diff --git a/MultiplatformDemo/MultiplatformDemo/Preview Content/Preview Assets.xcassets/Contents.json b/Demo/MultiplatformDemo/Preview Content/Preview Assets.xcassets/Contents.json similarity index 100% rename from MultiplatformDemo/MultiplatformDemo/Preview Content/Preview Assets.xcassets/Contents.json rename to Demo/MultiplatformDemo/Preview Content/Preview Assets.xcassets/Contents.json diff --git a/MultiplatformDemo/MultiplatformDemo.xcodeproj/project.pbxproj b/Demo/iPhoneNumberFieldDemo.xcodeproj/project.pbxproj similarity index 68% rename from MultiplatformDemo/MultiplatformDemo.xcodeproj/project.pbxproj rename to Demo/iPhoneNumberFieldDemo.xcodeproj/project.pbxproj index fd886a8..ac2a0a1 100644 --- a/MultiplatformDemo/MultiplatformDemo.xcodeproj/project.pbxproj +++ b/Demo/iPhoneNumberFieldDemo.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 56; + objectVersion = 70; objects = { /* Begin PBXBuildFile section */ @@ -12,18 +12,37 @@ 2AA44DCB28A11688001BF8F0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2AA44DCA28A11688001BF8F0 /* Assets.xcassets */; }; 2AA44DCF28A11688001BF8F0 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2AA44DCE28A11688001BF8F0 /* Preview Assets.xcassets */; }; 2AA44DD928A116D8001BF8F0 /* iPhoneNumberField in Frameworks */ = {isa = PBXBuildFile; productRef = 2AA44DD828A116D8001BF8F0 /* iPhoneNumberField */; }; + 2AD9C8152D6F21E4008B6062 /* issue118.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD9C8142D6F21E4008B6062 /* issue118.swift */; }; + 2AD9D0D72D719A21008B6062 /* issue119.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AD9D0D62D719A21008B6062 /* issue119.swift */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 2AD9C8212D6F2321008B6062 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 2AA44DBB28A11687001BF8F0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2AA44DC228A11687001BF8F0; + remoteInfo = iPhoneNumberFieldDemo; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ - 2AA44DC328A11687001BF8F0 /* MultiplatformDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MultiplatformDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 2AA44DC328A11687001BF8F0 /* iPhoneNumberFieldDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneNumberFieldDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 2AA44DC628A11687001BF8F0 /* MultiplatformDemoApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiplatformDemoApp.swift; sourceTree = ""; }; 2AA44DC828A11687001BF8F0 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 2AA44DCA28A11688001BF8F0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 2AA44DCC28A11688001BF8F0 /* MultiplatformDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MultiplatformDemo.entitlements; sourceTree = ""; }; 2AA44DCE28A11688001BF8F0 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 2AA44DD628A11699001BF8F0 /* iPhoneNumberField */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = iPhoneNumberField; path = ..; sourceTree = ""; }; + 2AD9C8142D6F21E4008B6062 /* issue118.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = issue118.swift; sourceTree = ""; }; + 2AD9C81B2D6F2321008B6062 /* iPhoneNumberFieldDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = iPhoneNumberFieldDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 2AD9D0D62D719A21008B6062 /* issue119.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = issue119.swift; sourceTree = ""; }; /* End PBXFileReference section */ +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 2AD9C81C2D6F2321008B6062 /* iPhoneNumberFieldDemoUITests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = iPhoneNumberFieldDemoUITests; sourceTree = ""; }; +/* End PBXFileSystemSynchronizedRootGroup section */ + /* Begin PBXFrameworksBuildPhase section */ 2AA44DC028A11687001BF8F0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; @@ -33,6 +52,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2AD9C8182D6F2321008B6062 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -41,6 +67,7 @@ children = ( 2AA44DD528A11699001BF8F0 /* Packages */, 2AA44DC528A11687001BF8F0 /* MultiplatformDemo */, + 2AD9C81C2D6F2321008B6062 /* iPhoneNumberFieldDemoUITests */, 2AA44DC428A11687001BF8F0 /* Products */, 2AA44DD728A116D8001BF8F0 /* Frameworks */, ); @@ -49,7 +76,8 @@ 2AA44DC428A11687001BF8F0 /* Products */ = { isa = PBXGroup; children = ( - 2AA44DC328A11687001BF8F0 /* MultiplatformDemo.app */, + 2AA44DC328A11687001BF8F0 /* iPhoneNumberFieldDemo.app */, + 2AD9C81B2D6F2321008B6062 /* iPhoneNumberFieldDemoUITests.xctest */, ); name = Products; sourceTree = ""; @@ -59,6 +87,7 @@ children = ( 2AA44DC628A11687001BF8F0 /* MultiplatformDemoApp.swift */, 2AA44DC828A11687001BF8F0 /* ContentView.swift */, + 2AD9C8162D6F222C008B6062 /* GitHubIssues */, 2AA44DCA28A11688001BF8F0 /* Assets.xcassets */, 2AA44DCC28A11688001BF8F0 /* MultiplatformDemo.entitlements */, 2AA44DCD28A11688001BF8F0 /* Preview Content */, @@ -89,12 +118,21 @@ name = Frameworks; sourceTree = ""; }; + 2AD9C8162D6F222C008B6062 /* GitHubIssues */ = { + isa = PBXGroup; + children = ( + 2AD9C8142D6F21E4008B6062 /* issue118.swift */, + 2AD9D0D62D719A21008B6062 /* issue119.swift */, + ); + path = GitHubIssues; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 2AA44DC228A11687001BF8F0 /* MultiplatformDemo */ = { + 2AA44DC228A11687001BF8F0 /* iPhoneNumberFieldDemo */ = { isa = PBXNativeTarget; - buildConfigurationList = 2AA44DD228A11688001BF8F0 /* Build configuration list for PBXNativeTarget "MultiplatformDemo" */; + buildConfigurationList = 2AA44DD228A11688001BF8F0 /* Build configuration list for PBXNativeTarget "iPhoneNumberFieldDemo" */; buildPhases = ( 2AA44DBF28A11687001BF8F0 /* Sources */, 2AA44DC028A11687001BF8F0 /* Frameworks */, @@ -104,14 +142,37 @@ ); dependencies = ( ); - name = MultiplatformDemo; + name = iPhoneNumberFieldDemo; packageProductDependencies = ( 2AA44DD828A116D8001BF8F0 /* iPhoneNumberField */, ); productName = MultiplatformDemo; - productReference = 2AA44DC328A11687001BF8F0 /* MultiplatformDemo.app */; + productReference = 2AA44DC328A11687001BF8F0 /* iPhoneNumberFieldDemo.app */; productType = "com.apple.product-type.application"; }; + 2AD9C81A2D6F2321008B6062 /* iPhoneNumberFieldDemoUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2AD9C8232D6F2321008B6062 /* Build configuration list for PBXNativeTarget "iPhoneNumberFieldDemoUITests" */; + buildPhases = ( + 2AD9C8172D6F2321008B6062 /* Sources */, + 2AD9C8182D6F2321008B6062 /* Frameworks */, + 2AD9C8192D6F2321008B6062 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 2AD9C8222D6F2321008B6062 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + 2AD9C81C2D6F2321008B6062 /* iPhoneNumberFieldDemoUITests */, + ); + name = iPhoneNumberFieldDemoUITests; + packageProductDependencies = ( + ); + productName = iPhoneNumberFieldDemoUITests; + productReference = 2AD9C81B2D6F2321008B6062 /* iPhoneNumberFieldDemoUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -119,15 +180,19 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1400; + LastSwiftUpdateCheck = 1620; LastUpgradeCheck = 1400; TargetAttributes = { 2AA44DC228A11687001BF8F0 = { CreatedOnToolsVersion = 14.0; }; + 2AD9C81A2D6F2321008B6062 = { + CreatedOnToolsVersion = 16.2; + TestTargetID = 2AA44DC228A11687001BF8F0; + }; }; }; - buildConfigurationList = 2AA44DBE28A11687001BF8F0 /* Build configuration list for PBXProject "MultiplatformDemo" */; + buildConfigurationList = 2AA44DBE28A11687001BF8F0 /* Build configuration list for PBXProject "iPhoneNumberFieldDemo" */; compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; @@ -140,7 +205,8 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 2AA44DC228A11687001BF8F0 /* MultiplatformDemo */, + 2AA44DC228A11687001BF8F0 /* iPhoneNumberFieldDemo */, + 2AD9C81A2D6F2321008B6062 /* iPhoneNumberFieldDemoUITests */, ); }; /* End PBXProject section */ @@ -155,6 +221,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2AD9C8192D6F2321008B6062 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -163,12 +236,29 @@ buildActionMask = 2147483647; files = ( 2AA44DC928A11687001BF8F0 /* ContentView.swift in Sources */, + 2AD9D0D72D719A21008B6062 /* issue119.swift in Sources */, 2AA44DC728A11687001BF8F0 /* MultiplatformDemoApp.swift in Sources */, + 2AD9C8152D6F21E4008B6062 /* issue118.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2AD9C8172D6F2321008B6062 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 2AD9C8222D6F2321008B6062 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 2AA44DC228A11687001BF8F0 /* iPhoneNumberFieldDemo */; + targetProxy = 2AD9C8212D6F2321008B6062 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin XCBuildConfiguration section */ 2AA44DD028A11688001BF8F0 /* Debug */ = { isa = XCBuildConfiguration; @@ -300,12 +390,12 @@ "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; + IPHONEOS_DEPLOYMENT_TARGET = 14; LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 12.5; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.iphonetextfield.MultiplatformDemo; + PRODUCT_BUNDLE_IDENTIFIER = com.example.iphonetextfield.demo; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; @@ -336,12 +426,12 @@ "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; + IPHONEOS_DEPLOYMENT_TARGET = 14; LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 12.5; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.iphonetextfield.MultiplatformDemo; + PRODUCT_BUNDLE_IDENTIFIER = com.example.iphonetextfield.demo; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; @@ -351,10 +441,56 @@ }; name = Release; }; + 2AD9C8242D6F2321008B6062 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.2; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.iphonetextfield.demo.uitests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = iPhoneNumberFieldDemo; + }; + name = Debug; + }; + 2AD9C8252D6F2321008B6062 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.2; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.iphonetextfield.demo.uitests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = iPhoneNumberFieldDemo; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 2AA44DBE28A11687001BF8F0 /* Build configuration list for PBXProject "MultiplatformDemo" */ = { + 2AA44DBE28A11687001BF8F0 /* Build configuration list for PBXProject "iPhoneNumberFieldDemo" */ = { isa = XCConfigurationList; buildConfigurations = ( 2AA44DD028A11688001BF8F0 /* Debug */, @@ -363,7 +499,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 2AA44DD228A11688001BF8F0 /* Build configuration list for PBXNativeTarget "MultiplatformDemo" */ = { + 2AA44DD228A11688001BF8F0 /* Build configuration list for PBXNativeTarget "iPhoneNumberFieldDemo" */ = { isa = XCConfigurationList; buildConfigurations = ( 2AA44DD328A11688001BF8F0 /* Debug */, @@ -372,6 +508,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 2AD9C8232D6F2321008B6062 /* Build configuration list for PBXNativeTarget "iPhoneNumberFieldDemoUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2AD9C8242D6F2321008B6062 /* Debug */, + 2AD9C8252D6F2321008B6062 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCSwiftPackageProductDependency section */ diff --git a/MultiplatformDemo/MultiplatformDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Demo/iPhoneNumberFieldDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from MultiplatformDemo/MultiplatformDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to Demo/iPhoneNumberFieldDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/MultiplatformDemo/MultiplatformDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Demo/iPhoneNumberFieldDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from MultiplatformDemo/MultiplatformDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to Demo/iPhoneNumberFieldDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/MultiplatformDemo/MultiplatformDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Demo/iPhoneNumberFieldDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved similarity index 100% rename from MultiplatformDemo/MultiplatformDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved rename to Demo/iPhoneNumberFieldDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/Demo/iPhoneNumberFieldDemoUITests/iPhoneNumberFieldDemoUITests.swift b/Demo/iPhoneNumberFieldDemoUITests/iPhoneNumberFieldDemoUITests.swift new file mode 100644 index 0000000..a20ee63 --- /dev/null +++ b/Demo/iPhoneNumberFieldDemoUITests/iPhoneNumberFieldDemoUITests.swift @@ -0,0 +1,45 @@ +// +// iPhoneNumberFieldDemoUITests.swift +// iPhoneNumberFieldDemoUITests +// +// Created by Seyed Mojtaba Hosseini Zeidabadi on 2/26/25. +// + +import XCTest + +final class iPhoneNumberFieldDemoUITests: XCTestCase { + + func testIssue118() throws { + let app = XCUIApplication() + app.launchArguments.append("UIT-GHI-118") + app.launch() + + let usFlag = "๐Ÿ‡บ๐Ÿ‡ธ" + let expectedFlag = "๐Ÿ‡ฆ๐Ÿ‡ซ" + + // I have set up the iPhoneNumberField like: + // @State private var selectedCountry: String = "US" + let selectYourCountryCodeButton = app.buttons["Select your country code"] + let countryFlag = selectYourCountryCodeButton.staticTexts.firstMatch + XCTAssert(countryFlag.label.contains(usFlag), "Expected US flag") + + // When I change the country flag + selectYourCountryCodeButton.tap() + + // Find and tap the Afghanistan entry using the flag + let allStaticTexts = app.tables.staticTexts.allElementsBoundByIndex + let expectedEntry = try XCTUnwrap(allStaticTexts.first { $0.label.contains(expectedFlag) }) + expectedEntry.tap() + + XCTAssert(countryFlag.label.contains(expectedFlag), "Expected another flag") + + // And begin to type in a phone number + app.textFields["Phone Number"].tap() + app.keys["1"].tap() + app.keys["2"].tap() + app.keys["3"].tap() + + // the flag just reverts back to US (unexpected). + XCTAssert(countryFlag.label.contains(expectedFlag), "Expected the flag to stay the same") + } +} diff --git a/MultiplatformDemo/MultiplatformDemo/MultiplatformDemoApp.swift b/MultiplatformDemo/MultiplatformDemo/MultiplatformDemoApp.swift deleted file mode 100644 index 0837691..0000000 --- a/MultiplatformDemo/MultiplatformDemo/MultiplatformDemoApp.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// MultiplatformDemoApp.swift -// MultiplatformDemo -// -// Created by Seyed Mojtaba Hosseini Zeidabadi on 8/8/22. -// - -import SwiftUI - -@main -struct MultiplatformDemoApp: App { - var body: some Scene { - WindowGroup { - ContentView() - } - } -} diff --git a/README.md b/README.md index a3888a4..b63374e 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ struct ContentView: View {

Focus and unfocus ๐Ÿ”

-

Use iPhoneNumberField's optional binding and iTextField to programmatically change text field.

+

Use iPhoneNumberField's optional binding and programmatically change the text field.

@@ -94,10 +94,8 @@ struct ContentView: View { var body: some View { VStack { - iTextField("Name", text: $nameText) - .font(UIFont(size: 24, weight: .light, design: .monospaced)) + TextField("Name", text: $nameText) .padding() - .onReturn { phoneEditing = true } iPhoneNumberField("Phone", text: $phoneText, isEditing: $phoneEditing) .font(UIFont(size: 24, weight: .light, design: .monospaced)) .padding() @@ -222,11 +220,11 @@ dependencies: [ ``` # ๐ŸŒŸ Become a Paid Subscriber -This library is under the **MIT** license and completely **FREE**. Anyone can use it anywhere and any contribution is wellcomed. +This library is under the **MIT** license and completely **FREE**. Anyone can use it anywhere, and any contribution is welcome. In addition, you can show your support and [become My sponsor](https://www.buymeacoffee.com/mojtabahs/membership). By supporting me, you will gainยน: -- Tickets for code level support in any project you want (not just this one) +- Tickets for code-level support in any project you want (not just this one) - Access me through my socials and we can discuss technologies together. - Discounts and early access to my premium products. - Early access to updates and bug fixes. diff --git a/Sources/iPhoneNumberField/iPhoneNumberField.swift b/Sources/iPhoneNumberField/iPhoneNumberField.swift index 2b27de2..01c7097 100644 --- a/Sources/iPhoneNumberField/iPhoneNumberField.swift +++ b/Sources/iPhoneNumberField/iPhoneNumberField.swift @@ -159,49 +159,50 @@ public struct iPhoneNumberField: UIViewRepresentable { uiView.partialFormatter.defaultRegion = defaultRegion } + configuration(uiView) return uiView } public func updateUIView(_ uiView: PhoneNumberTextField, context: UIViewRepresentableContext) { - uiView.textContentType = .telephoneNumber //allow auto-fill to work with telephone text field - uiView.text = text - uiView.font = font - uiView.maxDigits = maxDigits - uiView.clearButtonMode = clearButtonMode - uiView.placeholder = placeholder - uiView.borderStyle = borderStyle - uiView.textColor = textColor - uiView.withFlag = showFlag - uiView.withDefaultPickerUI = selectableFlag - uiView.withPrefix = previewPrefix - uiView.partialFormatter.defaultRegion = defaultRegion ?? PhoneNumberKit.defaultRegionCode() - if placeholder != nil { + DispatchQueue.main.async { + uiView.textContentType = .telephoneNumber //allow auto-fill to work with telephone text field + uiView.text = text + uiView.font = font + uiView.maxDigits = maxDigits + uiView.clearButtonMode = clearButtonMode uiView.placeholder = placeholder - } else { - uiView.withExamplePlaceholder = autofillPrefix - } - - uiView.tintColor = accentColor - - if let numberPlaceholderColor = numberPlaceholderColor { - uiView.numberPlaceholderColor = numberPlaceholderColor - } - if let countryCodePlaceholderColor = countryCodePlaceholderColor { - uiView.countryCodePlaceholderColor = countryCodePlaceholderColor - } - if let textAlignment = textAlignment { - uiView.textAlignment = textAlignment - } + uiView.borderStyle = borderStyle + uiView.textColor = textColor + uiView.withFlag = showFlag + uiView.withDefaultPickerUI = selectableFlag + uiView.withPrefix = previewPrefix + uiView.partialFormatter.defaultRegion = defaultRegion ?? PhoneNumberKit.defaultRegionCode() + if placeholder != nil { + uiView.placeholder = placeholder + } else { + uiView.withExamplePlaceholder = autofillPrefix + } + + uiView.tintColor = accentColor + + if let numberPlaceholderColor = numberPlaceholderColor { + uiView.numberPlaceholderColor = numberPlaceholderColor + } + if let countryCodePlaceholderColor = countryCodePlaceholderColor { + uiView.countryCodePlaceholderColor = countryCodePlaceholderColor + } + if let textAlignment = textAlignment { + uiView.textAlignment = textAlignment + } - DispatchQueue.main.async { if isFirstResponder { uiView.becomeFirstResponder() } else { uiView.resignFirstResponder() } + + configuration(uiView) } - - configuration(uiView) } public func makeCoordinator() -> Coordinator { @@ -256,53 +257,65 @@ public struct iPhoneNumberField: UIViewRepresentable { var onReturn = { (view: PhoneNumberTextField) in } @objc public func textViewDidChange(_ textField: UITextField) { - guard let textField = textField as? PhoneNumberTextField else { - return assertionFailure("Undefined state") - } - - // Updating the binding - if formatted { - // Display the text exactly if unformatted - text.wrappedValue = textField.text ?? "" - } else { - if let number = textField.phoneNumber { - // If we have a valid number, update the binding - let country = String(number.countryCode) - let nationalNumber = String(number.nationalNumber) - text.wrappedValue = "+" + country + nationalNumber + DispatchQueue.main.async { [weak self] in + guard let self else { return } + + guard let textField = textField as? PhoneNumberTextField else { + return assertionFailure("Undefined state") + } + + // Updating the binding + if formatted { + // Display the text exactly if unformatted + text.wrappedValue = textField.text ?? "" } else { - // Otherwise, maintain an empty string - text.wrappedValue = "" + if let number = textField.phoneNumber { + // If we have a valid number, update the binding + let country = String(number.countryCode) + let nationalNumber = String(number.nationalNumber) + text.wrappedValue = "+" + country + nationalNumber + } else { + // Otherwise, maintain an empty string + text.wrappedValue = "" + } } + + displayedText.wrappedValue = textField.text ?? "" + onEditingChange(textField) + onPhoneNumberChange(textField.phoneNumber) } - - displayedText.wrappedValue = textField.text ?? "" - onEditingChange(textField) - onPhoneNumberChange(textField.phoneNumber) } public func textFieldDidBeginEditing(_ textField: UITextField) { - DispatchQueue.main.async { [isFirstResponder] in + DispatchQueue.main.async { [weak self] in + guard let self else { return } isFirstResponder.wrappedValue = true + onBeginEditing(textField as! PhoneNumberTextField) } - onBeginEditing(textField as! PhoneNumberTextField) } public func textFieldDidEndEditing(_ textField: UITextField) { - DispatchQueue.main.async { [isFirstResponder] in + DispatchQueue.main.async { [weak self] in + guard let self else { return } isFirstResponder.wrappedValue = false + onBeginEditing(textField as! PhoneNumberTextField) } - onEndEditing(textField as! PhoneNumberTextField) } public func textFieldShouldClear(_ textField: UITextField) -> Bool { - displayedText.wrappedValue = "" - onClear(textField as! PhoneNumberTextField) + DispatchQueue.main.async { [weak self] in + guard let self else { return } + displayedText.wrappedValue = "" + onClear(textField as! PhoneNumberTextField) + } return true } public func textFieldShouldReturn(_ textField: UITextField) -> Bool { - onReturn(textField as! PhoneNumberTextField) + DispatchQueue.main.async { [weak self] in + guard let self else { return } + onReturn(textField as! PhoneNumberTextField) + } return true } }