├── .gitignore ├── Custom Picker.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── slynch.xcuserdatad │ │ ├── UserInterfaceState (Stewarts-iMac.hitronhub.home's conflicted copy 2020-08-14 1).xcuserstate │ │ ├── UserInterfaceState (Stewarts-iMac.hitronhub.home's conflicted copy 2020-08-14 2).xcuserstate │ │ └── UserInterfaceState (Stewarts-iMac.hitronhub.home's conflicted copy 2020-08-14).xcuserstate └── xcuserdata │ └── slynch.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── Custom Picker ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-1024_1024x1024.png │ │ ├── Icon-1024_120x120.png │ │ ├── Icon-1024_152x152.png │ │ ├── Icon-1024_167x167.png │ │ ├── Icon-1024_180x180.png │ │ ├── Icon-1024_20x20.png │ │ ├── Icon-1024_29x29.png │ │ ├── Icon-1024_40x40.png │ │ ├── Icon-1024_58x58.png │ │ ├── Icon-1024_60x60.png │ │ ├── Icon-1024_76x76.png │ │ ├── Icon-1024_80x80.png │ │ └── Icon-1024_87x87.png │ ├── Background.colorset │ │ └── Contents.json │ ├── Contents.json │ └── Working.imageset │ │ ├── Contents.json │ │ └── Working .svg ├── ContentView.swift ├── CountryFiles │ ├── Country.swift │ ├── CountryViewModel.swift │ ├── Store.swift │ └── countries.json ├── CustomPickerTextView.swift ├── CustomPickerView.swift ├── Custom_PickerApp.swift ├── Info.plist └── Preview Content │ └── Preview Assets.xcassets │ └── Contents.json ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ### macOS ### 29 | # General 30 | .DS_Store 31 | 32 | ## App packaging 33 | *.ipa 34 | *.dSYM.zip 35 | *.dSYM 36 | 37 | ## Playgrounds 38 | timeline.xctimeline 39 | playground.xcworkspace 40 | 41 | # Swift Package Manager 42 | # 43 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 44 | # Packages/ 45 | # Package.pins 46 | # Package.resolved 47 | # *.xcodeproj 48 | # 49 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 50 | # hence it is not needed unless you have added a package configuration file to your project 51 | # .swiftpm 52 | 53 | .build/ 54 | 55 | # CocoaPods 56 | # 57 | # We recommend against adding the Pods directory to your .gitignore. However 58 | # you should judge for yourself, the pros and cons are mentioned at: 59 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 60 | # 61 | # Pods/ 62 | # 63 | # Add this line if you want to avoid checking in source code from the Xcode workspace 64 | # *.xcworkspace 65 | 66 | # Carthage 67 | # 68 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 69 | # Carthage/Checkouts 70 | 71 | Carthage/Build/ 72 | 73 | # Accio dependency management 74 | Dependencies/ 75 | .accio/ 76 | 77 | # fastlane 78 | # 79 | # It is recommended to not store the screenshots in the git repo. 80 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 81 | # For more information about the recommended setup visit: 82 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 83 | 84 | fastlane/report.xml 85 | fastlane/Preview.html 86 | fastlane/screenshots/**/*.png 87 | fastlane/test_output 88 | 89 | # Code Injection 90 | # 91 | # After new code Injection tools there's a generated folder /iOSInjectionProject 92 | # https://github.com/johnno1962/injectionforxcode 93 | 94 | iOSInjectionProject/ 95 | -------------------------------------------------------------------------------- /Custom Picker.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | BB41B53824EDD09100A68A05 /* CustomPickerTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB41B53724EDD09100A68A05 /* CustomPickerTextView.swift */; }; 11 | BB9599DD24EAF97500B74898 /* CustomPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB9599DC24EAF97500B74898 /* CustomPickerView.swift */; }; 12 | BBCC25DE24E82FA6007E17F6 /* CountryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBCC25DC24E82FA6007E17F6 /* CountryViewModel.swift */; }; 13 | BBCC25DF24E82FA6007E17F6 /* countries.json in Resources */ = {isa = PBXBuildFile; fileRef = BBCC25DD24E82FA6007E17F6 /* countries.json */; }; 14 | BBCC25E124E82FC5007E17F6 /* Store.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBCC25E024E82FC5007E17F6 /* Store.swift */; }; 15 | BBCC25E324E82FE2007E17F6 /* Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBCC25E224E82FE2007E17F6 /* Country.swift */; }; 16 | BBEBCFAF24E658050016E780 /* Custom_PickerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBEBCFAE24E658050016E780 /* Custom_PickerApp.swift */; }; 17 | BBEBCFB124E658050016E780 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBEBCFB024E658050016E780 /* ContentView.swift */; }; 18 | BBEBCFB324E658060016E780 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BBEBCFB224E658060016E780 /* Assets.xcassets */; }; 19 | BBEBCFB624E658060016E780 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BBEBCFB524E658060016E780 /* Preview Assets.xcassets */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXFileReference section */ 23 | BB41B53724EDD09100A68A05 /* CustomPickerTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPickerTextView.swift; sourceTree = ""; }; 24 | BB9599DC24EAF97500B74898 /* CustomPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPickerView.swift; sourceTree = ""; }; 25 | BBCC25DC24E82FA6007E17F6 /* CountryViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CountryViewModel.swift; sourceTree = ""; }; 26 | BBCC25DD24E82FA6007E17F6 /* countries.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = countries.json; sourceTree = ""; }; 27 | BBCC25E024E82FC5007E17F6 /* Store.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Store.swift; sourceTree = ""; }; 28 | BBCC25E224E82FE2007E17F6 /* Country.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Country.swift; sourceTree = ""; }; 29 | BBEBCFAB24E658050016E780 /* Custom Picker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Custom Picker.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 30 | BBEBCFAE24E658050016E780 /* Custom_PickerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Custom_PickerApp.swift; sourceTree = ""; }; 31 | BBEBCFB024E658050016E780 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 32 | BBEBCFB224E658060016E780 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 33 | BBEBCFB524E658060016E780 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 34 | BBEBCFB724E658060016E780 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 35 | /* End PBXFileReference section */ 36 | 37 | /* Begin PBXFrameworksBuildPhase section */ 38 | BBEBCFA824E658050016E780 /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | ); 43 | runOnlyForDeploymentPostprocessing = 0; 44 | }; 45 | /* End PBXFrameworksBuildPhase section */ 46 | 47 | /* Begin PBXGroup section */ 48 | BBCC25DB24E82FA6007E17F6 /* CountryFiles */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | BBCC25E224E82FE2007E17F6 /* Country.swift */, 52 | BBCC25E024E82FC5007E17F6 /* Store.swift */, 53 | BBCC25DC24E82FA6007E17F6 /* CountryViewModel.swift */, 54 | BBCC25DD24E82FA6007E17F6 /* countries.json */, 55 | ); 56 | path = CountryFiles; 57 | sourceTree = ""; 58 | }; 59 | BBEBCFA224E658050016E780 = { 60 | isa = PBXGroup; 61 | children = ( 62 | BBEBCFAD24E658050016E780 /* Custom Picker */, 63 | BBEBCFAC24E658050016E780 /* Products */, 64 | ); 65 | sourceTree = ""; 66 | }; 67 | BBEBCFAC24E658050016E780 /* Products */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | BBEBCFAB24E658050016E780 /* Custom Picker.app */, 71 | ); 72 | name = Products; 73 | sourceTree = ""; 74 | }; 75 | BBEBCFAD24E658050016E780 /* Custom Picker */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | BBEBCFAE24E658050016E780 /* Custom_PickerApp.swift */, 79 | BB41B53724EDD09100A68A05 /* CustomPickerTextView.swift */, 80 | BB9599DC24EAF97500B74898 /* CustomPickerView.swift */, 81 | BBEBCFB024E658050016E780 /* ContentView.swift */, 82 | BBCC25DB24E82FA6007E17F6 /* CountryFiles */, 83 | BBEBCFB724E658060016E780 /* Info.plist */, 84 | BBEBCFB224E658060016E780 /* Assets.xcassets */, 85 | BBEBCFB424E658060016E780 /* Preview Content */, 86 | ); 87 | path = "Custom Picker"; 88 | sourceTree = ""; 89 | }; 90 | BBEBCFB424E658060016E780 /* Preview Content */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | BBEBCFB524E658060016E780 /* Preview Assets.xcassets */, 94 | ); 95 | path = "Preview Content"; 96 | sourceTree = ""; 97 | }; 98 | /* End PBXGroup section */ 99 | 100 | /* Begin PBXNativeTarget section */ 101 | BBEBCFAA24E658050016E780 /* Custom Picker */ = { 102 | isa = PBXNativeTarget; 103 | buildConfigurationList = BBEBCFBA24E658060016E780 /* Build configuration list for PBXNativeTarget "Custom Picker" */; 104 | buildPhases = ( 105 | BBEBCFA724E658050016E780 /* Sources */, 106 | BBEBCFA824E658050016E780 /* Frameworks */, 107 | BBEBCFA924E658050016E780 /* Resources */, 108 | ); 109 | buildRules = ( 110 | ); 111 | dependencies = ( 112 | ); 113 | name = "Custom Picker"; 114 | packageProductDependencies = ( 115 | ); 116 | productName = "Custom Picker"; 117 | productReference = BBEBCFAB24E658050016E780 /* Custom Picker.app */; 118 | productType = "com.apple.product-type.application"; 119 | }; 120 | /* End PBXNativeTarget section */ 121 | 122 | /* Begin PBXProject section */ 123 | BBEBCFA324E658050016E780 /* Project object */ = { 124 | isa = PBXProject; 125 | attributes = { 126 | LastSwiftUpdateCheck = 1200; 127 | LastUpgradeCheck = 1200; 128 | TargetAttributes = { 129 | BBEBCFAA24E658050016E780 = { 130 | CreatedOnToolsVersion = 12.0; 131 | }; 132 | }; 133 | }; 134 | buildConfigurationList = BBEBCFA624E658050016E780 /* Build configuration list for PBXProject "Custom Picker" */; 135 | compatibilityVersion = "Xcode 9.3"; 136 | developmentRegion = en; 137 | hasScannedForEncodings = 0; 138 | knownRegions = ( 139 | en, 140 | Base, 141 | ); 142 | mainGroup = BBEBCFA224E658050016E780; 143 | packageReferences = ( 144 | ); 145 | productRefGroup = BBEBCFAC24E658050016E780 /* Products */; 146 | projectDirPath = ""; 147 | projectRoot = ""; 148 | targets = ( 149 | BBEBCFAA24E658050016E780 /* Custom Picker */, 150 | ); 151 | }; 152 | /* End PBXProject section */ 153 | 154 | /* Begin PBXResourcesBuildPhase section */ 155 | BBEBCFA924E658050016E780 /* Resources */ = { 156 | isa = PBXResourcesBuildPhase; 157 | buildActionMask = 2147483647; 158 | files = ( 159 | BBCC25DF24E82FA6007E17F6 /* countries.json in Resources */, 160 | BBEBCFB624E658060016E780 /* Preview Assets.xcassets in Resources */, 161 | BBEBCFB324E658060016E780 /* Assets.xcassets in Resources */, 162 | ); 163 | runOnlyForDeploymentPostprocessing = 0; 164 | }; 165 | /* End PBXResourcesBuildPhase section */ 166 | 167 | /* Begin PBXSourcesBuildPhase section */ 168 | BBEBCFA724E658050016E780 /* Sources */ = { 169 | isa = PBXSourcesBuildPhase; 170 | buildActionMask = 2147483647; 171 | files = ( 172 | BBCC25E324E82FE2007E17F6 /* Country.swift in Sources */, 173 | BBEBCFB124E658050016E780 /* ContentView.swift in Sources */, 174 | BBCC25E124E82FC5007E17F6 /* Store.swift in Sources */, 175 | BB9599DD24EAF97500B74898 /* CustomPickerView.swift in Sources */, 176 | BBEBCFAF24E658050016E780 /* Custom_PickerApp.swift in Sources */, 177 | BBCC25DE24E82FA6007E17F6 /* CountryViewModel.swift in Sources */, 178 | BB41B53824EDD09100A68A05 /* CustomPickerTextView.swift in Sources */, 179 | ); 180 | runOnlyForDeploymentPostprocessing = 0; 181 | }; 182 | /* End PBXSourcesBuildPhase section */ 183 | 184 | /* Begin XCBuildConfiguration section */ 185 | BBEBCFB824E658060016E780 /* Debug */ = { 186 | isa = XCBuildConfiguration; 187 | buildSettings = { 188 | ALWAYS_SEARCH_USER_PATHS = NO; 189 | CLANG_ANALYZER_NONNULL = YES; 190 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 191 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 192 | CLANG_CXX_LIBRARY = "libc++"; 193 | CLANG_ENABLE_MODULES = YES; 194 | CLANG_ENABLE_OBJC_ARC = YES; 195 | CLANG_ENABLE_OBJC_WEAK = YES; 196 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 197 | CLANG_WARN_BOOL_CONVERSION = YES; 198 | CLANG_WARN_COMMA = YES; 199 | CLANG_WARN_CONSTANT_CONVERSION = YES; 200 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 201 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 202 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 203 | CLANG_WARN_EMPTY_BODY = YES; 204 | CLANG_WARN_ENUM_CONVERSION = YES; 205 | CLANG_WARN_INFINITE_RECURSION = YES; 206 | CLANG_WARN_INT_CONVERSION = YES; 207 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 208 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 209 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 210 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 211 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 212 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 213 | CLANG_WARN_STRICT_PROTOTYPES = YES; 214 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 215 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 216 | CLANG_WARN_UNREACHABLE_CODE = YES; 217 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 218 | COPY_PHASE_STRIP = NO; 219 | DEBUG_INFORMATION_FORMAT = dwarf; 220 | ENABLE_STRICT_OBJC_MSGSEND = YES; 221 | ENABLE_TESTABILITY = YES; 222 | GCC_C_LANGUAGE_STANDARD = gnu11; 223 | GCC_DYNAMIC_NO_PIC = NO; 224 | GCC_NO_COMMON_BLOCKS = YES; 225 | GCC_OPTIMIZATION_LEVEL = 0; 226 | GCC_PREPROCESSOR_DEFINITIONS = ( 227 | "DEBUG=1", 228 | "$(inherited)", 229 | ); 230 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 231 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 232 | GCC_WARN_UNDECLARED_SELECTOR = YES; 233 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 234 | GCC_WARN_UNUSED_FUNCTION = YES; 235 | GCC_WARN_UNUSED_VARIABLE = YES; 236 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 237 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 238 | MTL_FAST_MATH = YES; 239 | ONLY_ACTIVE_ARCH = YES; 240 | SDKROOT = iphoneos; 241 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 242 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 243 | }; 244 | name = Debug; 245 | }; 246 | BBEBCFB924E658060016E780 /* Release */ = { 247 | isa = XCBuildConfiguration; 248 | buildSettings = { 249 | ALWAYS_SEARCH_USER_PATHS = NO; 250 | CLANG_ANALYZER_NONNULL = YES; 251 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 252 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 253 | CLANG_CXX_LIBRARY = "libc++"; 254 | CLANG_ENABLE_MODULES = YES; 255 | CLANG_ENABLE_OBJC_ARC = YES; 256 | CLANG_ENABLE_OBJC_WEAK = YES; 257 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 258 | CLANG_WARN_BOOL_CONVERSION = YES; 259 | CLANG_WARN_COMMA = YES; 260 | CLANG_WARN_CONSTANT_CONVERSION = YES; 261 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 262 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 263 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 264 | CLANG_WARN_EMPTY_BODY = YES; 265 | CLANG_WARN_ENUM_CONVERSION = YES; 266 | CLANG_WARN_INFINITE_RECURSION = YES; 267 | CLANG_WARN_INT_CONVERSION = YES; 268 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 269 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 270 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 271 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 272 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 273 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 274 | CLANG_WARN_STRICT_PROTOTYPES = YES; 275 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 276 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 277 | CLANG_WARN_UNREACHABLE_CODE = YES; 278 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 279 | COPY_PHASE_STRIP = NO; 280 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 281 | ENABLE_NS_ASSERTIONS = NO; 282 | ENABLE_STRICT_OBJC_MSGSEND = YES; 283 | GCC_C_LANGUAGE_STANDARD = gnu11; 284 | GCC_NO_COMMON_BLOCKS = YES; 285 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 286 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 287 | GCC_WARN_UNDECLARED_SELECTOR = YES; 288 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 289 | GCC_WARN_UNUSED_FUNCTION = YES; 290 | GCC_WARN_UNUSED_VARIABLE = YES; 291 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 292 | MTL_ENABLE_DEBUG_INFO = NO; 293 | MTL_FAST_MATH = YES; 294 | SDKROOT = iphoneos; 295 | SWIFT_COMPILATION_MODE = wholemodule; 296 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 297 | VALIDATE_PRODUCT = YES; 298 | }; 299 | name = Release; 300 | }; 301 | BBEBCFBB24E658060016E780 /* Debug */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 305 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 306 | CODE_SIGN_STYLE = Automatic; 307 | DEVELOPMENT_ASSET_PATHS = "\"Custom Picker/Preview Content\""; 308 | DEVELOPMENT_TEAM = RKV4UP49S6; 309 | ENABLE_PREVIEWS = YES; 310 | INFOPLIST_FILE = "Custom Picker/Info.plist"; 311 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 312 | LD_RUNPATH_SEARCH_PATHS = ( 313 | "$(inherited)", 314 | "@executable_path/Frameworks", 315 | ); 316 | PRODUCT_BUNDLE_IDENTIFIER = "com.createchsol.Custom-Picker"; 317 | PRODUCT_NAME = "$(TARGET_NAME)"; 318 | SWIFT_VERSION = 5.0; 319 | TARGETED_DEVICE_FAMILY = "1,2"; 320 | }; 321 | name = Debug; 322 | }; 323 | BBEBCFBC24E658060016E780 /* Release */ = { 324 | isa = XCBuildConfiguration; 325 | buildSettings = { 326 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 327 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 328 | CODE_SIGN_STYLE = Automatic; 329 | DEVELOPMENT_ASSET_PATHS = "\"Custom Picker/Preview Content\""; 330 | DEVELOPMENT_TEAM = RKV4UP49S6; 331 | ENABLE_PREVIEWS = YES; 332 | INFOPLIST_FILE = "Custom Picker/Info.plist"; 333 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 334 | LD_RUNPATH_SEARCH_PATHS = ( 335 | "$(inherited)", 336 | "@executable_path/Frameworks", 337 | ); 338 | PRODUCT_BUNDLE_IDENTIFIER = "com.createchsol.Custom-Picker"; 339 | PRODUCT_NAME = "$(TARGET_NAME)"; 340 | SWIFT_VERSION = 5.0; 341 | TARGETED_DEVICE_FAMILY = "1,2"; 342 | }; 343 | name = Release; 344 | }; 345 | /* End XCBuildConfiguration section */ 346 | 347 | /* Begin XCConfigurationList section */ 348 | BBEBCFA624E658050016E780 /* Build configuration list for PBXProject "Custom Picker" */ = { 349 | isa = XCConfigurationList; 350 | buildConfigurations = ( 351 | BBEBCFB824E658060016E780 /* Debug */, 352 | BBEBCFB924E658060016E780 /* Release */, 353 | ); 354 | defaultConfigurationIsVisible = 0; 355 | defaultConfigurationName = Release; 356 | }; 357 | BBEBCFBA24E658060016E780 /* Build configuration list for PBXNativeTarget "Custom Picker" */ = { 358 | isa = XCConfigurationList; 359 | buildConfigurations = ( 360 | BBEBCFBB24E658060016E780 /* Debug */, 361 | BBEBCFBC24E658060016E780 /* Release */, 362 | ); 363 | defaultConfigurationIsVisible = 0; 364 | defaultConfigurationName = Release; 365 | }; 366 | /* End XCConfigurationList section */ 367 | }; 368 | rootObject = BBEBCFA324E658050016E780 /* Project object */; 369 | } 370 | -------------------------------------------------------------------------------- /Custom Picker.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Custom Picker.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Custom Picker.xcodeproj/project.xcworkspace/xcuserdata/slynch.xcuserdatad/UserInterfaceState (Stewarts-iMac.hitronhub.home's conflicted copy 2020-08-14 1).xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker.xcodeproj/project.xcworkspace/xcuserdata/slynch.xcuserdatad/UserInterfaceState (Stewarts-iMac.hitronhub.home's conflicted copy 2020-08-14 1).xcuserstate -------------------------------------------------------------------------------- /Custom Picker.xcodeproj/project.xcworkspace/xcuserdata/slynch.xcuserdatad/UserInterfaceState (Stewarts-iMac.hitronhub.home's conflicted copy 2020-08-14 2).xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker.xcodeproj/project.xcworkspace/xcuserdata/slynch.xcuserdatad/UserInterfaceState (Stewarts-iMac.hitronhub.home's conflicted copy 2020-08-14 2).xcuserstate -------------------------------------------------------------------------------- /Custom Picker.xcodeproj/project.xcworkspace/xcuserdata/slynch.xcuserdatad/UserInterfaceState (Stewarts-iMac.hitronhub.home's conflicted copy 2020-08-14).xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker.xcodeproj/project.xcworkspace/xcuserdata/slynch.xcuserdatad/UserInterfaceState (Stewarts-iMac.hitronhub.home's conflicted copy 2020-08-14).xcuserstate -------------------------------------------------------------------------------- /Custom Picker.xcodeproj/xcuserdata/slynch.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /Custom Picker.xcodeproj/xcuserdata/slynch.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Custom Picker.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-1024_40x40.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-1024_60x60.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-1024_58x58.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-1024_87x87.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-1024_80x80.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-1024_120x120.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-1024_120x120.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-1024_180x180.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "20x20", 53 | "idiom" : "ipad", 54 | "filename" : "Icon-1024_20x20.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-1024_40x40.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-1024_29x29.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-1024_58x58.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-1024_40x40.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-1024_80x80.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "76x76", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-1024_76x76.png", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-1024_152x152.png", 97 | "scale" : "2x" 98 | }, 99 | { 100 | "size" : "83.5x83.5", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-1024_167x167.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "1024x1024", 107 | "idiom" : "ios-marketing", 108 | "filename" : "Icon-1024_1024x1024.png", 109 | "scale" : "1x" 110 | } 111 | ], 112 | "info" : { 113 | "version" : 1, 114 | "author" : "com.neriusv.macos.svgassets" 115 | } 116 | } -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_1024x1024.png -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_120x120.png -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_152x152.png -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_167x167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_167x167.png -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_180x180.png -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_20x20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_20x20.png -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_29x29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_29x29.png -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_40x40.png -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_58x58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_58x58.png -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_60x60.png -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_76x76.png -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_80x80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_80x80.png -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_87x87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StewartLynch/Reusable-Custom-Picker-for-SwiftUI/8b6a20717e1e0d34c8bfe0626d12f362738eea76/Custom Picker/Assets.xcassets/AppIcon.appiconset/Icon-1024_87x87.png -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/Background.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.949", 9 | "green" : "0.949", 10 | "red" : "0.949" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | }, 15 | { 16 | "appearances" : [ 17 | { 18 | "appearance" : "luminosity", 19 | "value" : "dark" 20 | } 21 | ], 22 | "color" : { 23 | "color-space" : "srgb", 24 | "components" : { 25 | "alpha" : "1.000", 26 | "blue" : "0.263", 27 | "green" : "0.151", 28 | "red" : "0.072" 29 | } 30 | }, 31 | "idiom" : "universal" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/Working.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Working .svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Custom Picker/Assets.xcassets/Working.imageset/Working .svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Custom Picker/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // Custom Picker 4 | // 5 | // Created by Stewart Lynch on 2020-08-13. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ContentView: View, CustomPicker { 11 | @State private var food = "" 12 | @State private var foodArray = ["Milk", "Apples", "Sugar", "Eggs", "Oranges", "Potatoes", "Corn", "Bread"] 13 | @StateObject private var countriesVM = CountryViewModel() 14 | @State private var country = "" 15 | @State private var presentPicker = false 16 | @State private var tag: Int = 1 17 | 18 | var body: some View { 19 | ZStack { 20 | NavigationView { 21 | ZStack { 22 | Color("Background") 23 | .edgesIgnoringSafeArea(.all) 24 | VStack { 25 | Spacer() 26 | CustomPickerTextView(presentPicker: $presentPicker, 27 | fieldString: $food, 28 | placeholder: "Select a food item.", 29 | tag: $tag, 30 | selectedTag: 1) 31 | CustomPickerTextView(presentPicker: $presentPicker, 32 | fieldString: $country, 33 | placeholder: "Select a country.", 34 | tag: $tag, 35 | selectedTag: 2) 36 | Image("Working") 37 | .resizable() 38 | .frame(width: 400) 39 | .scaledToFit() 40 | Spacer() 41 | } 42 | .textFieldStyle(RoundedBorderTextFieldStyle()) 43 | .frame(width: 250) 44 | .navigationBarTitle("Picker Demo") 45 | } 46 | } 47 | if presentPicker { 48 | if tag == 1 { 49 | CustomPickerView(items: foodArray.sorted(), 50 | pickerField: $food, 51 | presentPicker: $presentPicker, 52 | saveUpdates: saveUpdates) 53 | .zIndex(1.0) 54 | } else { 55 | CustomPickerView(items: countriesVM.countryNamesArray, 56 | pickerField: $country, 57 | presentPicker: $presentPicker) 58 | .zIndex(1.0) 59 | } 60 | } 61 | } 62 | } 63 | 64 | func saveUpdates(_ newItem: String) { 65 | foodArray.append(newItem) 66 | } 67 | 68 | } 69 | 70 | struct ContentView_Previews: PreviewProvider { 71 | static var previews: some View { 72 | ContentView() 73 | } 74 | } 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Custom Picker/CountryFiles/Country.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Country.swift 3 | // CountriesFlagsAndCodes 4 | // 5 | // Created by Stewart Lynch on 2020-04-23. 6 | // Copyright © 2020 Stewart Lynch. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Country: Identifiable,Codable { 12 | var id: UUID? = UUID() 13 | let name: String 14 | let code: String 15 | let flag: String 16 | let appStore: Bool 17 | } 18 | 19 | -------------------------------------------------------------------------------- /Custom Picker/CountryFiles/CountryViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CountryDataSource.swift 3 | // CountriesFlagsAndCodes 4 | // 5 | // Created by Stewart Lynch on 2020-04-23. 6 | // Copyright © 2020 Stewart Lynch. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class CountryViewModel: NSObject, ObservableObject { 12 | @Published var countries = [Country]() 13 | 14 | var countryNamesArray:[String] { 15 | countries.map{"\($0.flag) \($0.name)"}.sorted() 16 | } 17 | 18 | 19 | override init() { 20 | countries = Store.retrieveCountries() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Custom Picker/CountryFiles/Store.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Network.swift 3 | // CountriesFlagsAndCodes 4 | // 5 | // Created by Stewart Lynch on 2020-04-23. 6 | // Copyright © 2020 Stewart Lynch. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | class Store { 12 | 13 | static let bundleURL = Bundle.main.url(forResource: "countries.json", withExtension: nil)! 14 | 15 | static func retrieveCountries() -> [Country] { 16 | let decoder = JSONDecoder() 17 | guard let data = try? Data(contentsOf: bundleURL) else { 18 | fatalError("Unable to load country data") 19 | } 20 | guard let countries = try? decoder.decode([Country].self, from: data) else { 21 | fatalError("Failed to decode JSON from the data") 22 | } 23 | 24 | return countries 25 | 26 | } 27 | 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Custom Picker/CountryFiles/countries.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "United Arab Emirates", 4 | "code": "AE", 5 | "flag": "🇦🇪", 6 | "appStore": true 7 | }, 8 | { 9 | "name": "Afghanistan", 10 | "code": "AF", 11 | "flag": "🇦🇫", 12 | "appStore": true 13 | }, 14 | { 15 | "name": "Antigua & Barbuda", 16 | "code": "AG", 17 | "flag": "🇦🇬", 18 | "appStore": true 19 | }, 20 | { 21 | "name": "Anguilla", 22 | "code": "AI", 23 | "flag": "🇦🇮", 24 | "appStore": true 25 | }, 26 | { 27 | "name": "Albania", 28 | "code": "AL", 29 | "flag": "🇦🇱", 30 | "appStore": true 31 | }, 32 | { 33 | "name": "Armenia", 34 | "code": "AM", 35 | "flag": "🇦🇲", 36 | "appStore": true 37 | }, 38 | { 39 | "name": "Angola", 40 | "code": "AO", 41 | "flag": "🇦🇴", 42 | "appStore": true 43 | }, 44 | { 45 | "name": "Argentina", 46 | "code": "AR", 47 | "flag": "🇦🇷", 48 | "appStore": true 49 | }, 50 | { 51 | "name": "Austria", 52 | "code": "AT", 53 | "flag": "🇦🇹", 54 | "appStore": true 55 | }, 56 | { 57 | "name": "Australia", 58 | "code": "AU", 59 | "flag": "🇦🇺", 60 | "appStore": true 61 | }, 62 | { 63 | "name": "Azerbaijan", 64 | "code": "AZ", 65 | "flag": "🇦🇿", 66 | "appStore": true 67 | }, 68 | { 69 | "name": "Bosnia and Herzegovina", 70 | "code": "BA", 71 | "flag": "🇧🇦", 72 | "appStore": true 73 | }, 74 | { 75 | "name": "Barbados", 76 | "code": "BB", 77 | "flag": "🇧🇧", 78 | "appStore": true 79 | }, 80 | { 81 | "name": "Belgium", 82 | "code": "BE", 83 | "flag": "🇧🇪", 84 | "appStore": true 85 | }, 86 | { 87 | "name": "Burkina Faso", 88 | "code": "BF", 89 | "flag": "🇧🇫", 90 | "appStore": true 91 | }, 92 | { 93 | "name": "Bulgaria", 94 | "code": "BG", 95 | "flag": "🇧🇬", 96 | "appStore": true 97 | }, 98 | { 99 | "name": "Bahrain", 100 | "code": "BH", 101 | "flag": "🇧🇭", 102 | "appStore": true 103 | }, 104 | { 105 | "name": "Benin", 106 | "code": "BJ", 107 | "flag": "🇧🇯", 108 | "appStore": true 109 | }, 110 | { 111 | "name": "Bermuda", 112 | "code": "BM", 113 | "flag": "🇧🇲", 114 | "appStore": true 115 | }, 116 | { 117 | "name": "Brunei", 118 | "code": "BN", 119 | "flag": "🇧🇳", 120 | "appStore": true 121 | }, 122 | { 123 | "name": "Bolivia", 124 | "code": "BO", 125 | "flag": "🇧🇴", 126 | "appStore": true 127 | }, 128 | { 129 | "name": "Brazil", 130 | "code": "BR", 131 | "flag": "🇧🇷", 132 | "appStore": true 133 | }, 134 | { 135 | "name": "Bahamas", 136 | "code": "BS", 137 | "flag": "🇧🇸", 138 | "appStore": true 139 | }, 140 | { 141 | "name": "Bhutan", 142 | "code": "BT", 143 | "flag": "🇧🇹", 144 | "appStore": true 145 | }, 146 | { 147 | "name": "Botswana", 148 | "code": "BW", 149 | "flag": "🇧🇼", 150 | "appStore": true 151 | }, 152 | { 153 | "name": "Belarus", 154 | "code": "BY", 155 | "flag": "🇧🇾", 156 | "appStore": true 157 | }, 158 | { 159 | "name": "Belize", 160 | "code": "BZ", 161 | "flag": "🇧🇿", 162 | "appStore": true 163 | }, 164 | { 165 | "name": "Canada", 166 | "code": "CA", 167 | "flag": "🇨🇦", 168 | "appStore": true 169 | }, 170 | { 171 | "name": "Congo, Democratic Republic Of The", 172 | "code": "CD", 173 | "flag": "🇨🇩", 174 | "appStore": true 175 | }, 176 | { 177 | "name": "Congo, Republic of", 178 | "code": "CG", 179 | "flag": "🇨🇬", 180 | "appStore": true 181 | }, 182 | { 183 | "name": "Switzerland", 184 | "code": "CH", 185 | "flag": "🇨🇭", 186 | "appStore": true 187 | }, 188 | { 189 | "name": "Cote D'Ivoire", 190 | "code": "CI", 191 | "flag": "🇨🇮", 192 | "appStore": true 193 | }, 194 | { 195 | "name": "Chile", 196 | "code": "CL", 197 | "flag": "🇨🇱", 198 | "appStore": true 199 | }, 200 | { 201 | "name": "Cameroon", 202 | "code": "CM", 203 | "flag": "🇨🇲", 204 | "appStore": true 205 | }, 206 | { 207 | "name": "China", 208 | "code": "CN", 209 | "flag": "🇨🇳", 210 | "appStore": true 211 | }, 212 | { 213 | "name": "Columbia", 214 | "code": "CO", 215 | "flag": "🇨🇴", 216 | "appStore": true 217 | }, 218 | { 219 | "name": "Costa Rica", 220 | "code": "CR", 221 | "flag": "🇨🇷", 222 | "appStore": true 223 | }, 224 | { 225 | "name": "Cape Verde", 226 | "code": "CV", 227 | "flag": "🇨🇻", 228 | "appStore": true 229 | }, 230 | { 231 | "name": "Cyprus", 232 | "code": "CY", 233 | "flag": "🇨🇾", 234 | "appStore": true 235 | }, 236 | { 237 | "name": "Czech Republic", 238 | "code": "CZ", 239 | "flag": "🇨🇿", 240 | "appStore": true 241 | }, 242 | { 243 | "name": "Germany", 244 | "code": "DE", 245 | "flag": "🇩🇪", 246 | "appStore": true 247 | }, 248 | { 249 | "name": "Denmark", 250 | "code": "DK", 251 | "flag": "🇩🇰", 252 | "appStore": true 253 | }, 254 | { 255 | "name": "Dominica", 256 | "code": "DM", 257 | "flag": "🇩🇲", 258 | "appStore": true 259 | }, 260 | { 261 | "name": "Dominican Republic", 262 | "code": "DO", 263 | "flag": "🇩🇴", 264 | "appStore": true 265 | }, 266 | { 267 | "name": "Algeria", 268 | "code": "DZ", 269 | "flag": "🇩🇿", 270 | "appStore": true 271 | }, 272 | { 273 | "name": "Ecuador", 274 | "code": "EC", 275 | "flag": "🇪🇨", 276 | "appStore": true 277 | }, 278 | { 279 | "name": "Estonia", 280 | "code": "EE", 281 | "flag": "🇪🇪", 282 | "appStore": true 283 | }, 284 | { 285 | "name": "Egypt", 286 | "code": "EG", 287 | "flag": "🇪🇬", 288 | "appStore": true 289 | }, 290 | { 291 | "name": "Spain", 292 | "code": "ES", 293 | "flag": "🇪🇸", 294 | "appStore": true 295 | }, 296 | { 297 | "name": "Finland", 298 | "code": "FI", 299 | "flag": "🇫🇮", 300 | "appStore": true 301 | }, 302 | { 303 | "name": "Fiji", 304 | "code": "FJ", 305 | "flag": "🇫🇯", 306 | "appStore": true 307 | }, 308 | { 309 | "name": "Micronesia", 310 | "code": "FM", 311 | "flag": "🇫🇲", 312 | "appStore": true 313 | }, 314 | { 315 | "name": "France", 316 | "code": "FR", 317 | "flag": "🇫🇷", 318 | "appStore": true 319 | }, 320 | { 321 | "name": "Gabon", 322 | "code": "GA", 323 | "flag": "🇬🇦", 324 | "appStore": true 325 | }, 326 | { 327 | "name": "United Kingdom", 328 | "code": "GB", 329 | "flag": "🇬🇧", 330 | "appStore": true 331 | }, 332 | { 333 | "name": "Grenada", 334 | "code": "GD", 335 | "flag": "🇬🇩", 336 | "appStore": true 337 | }, 338 | { 339 | "name": "Georgia", 340 | "code": "GE", 341 | "flag": "🇬🇪", 342 | "appStore": true 343 | }, 344 | { 345 | "name": "Ghana", 346 | "code": "GH", 347 | "flag": "🇬🇭", 348 | "appStore": true 349 | }, 350 | { 351 | "name": "Gambia", 352 | "code": "GM", 353 | "flag": "🇬🇲", 354 | "appStore": true 355 | }, 356 | { 357 | "name": "Greece", 358 | "code": "GR", 359 | "flag": "🇬🇷", 360 | "appStore": true 361 | }, 362 | { 363 | "name": "Guatemala", 364 | "code": "GT", 365 | "flag": "🇬🇹", 366 | "appStore": true 367 | }, 368 | { 369 | "name": "Guinea-Bissau", 370 | "code": "GW", 371 | "flag": "🇬🇼", 372 | "appStore": true 373 | }, 374 | { 375 | "name": "Guyana", 376 | "code": "GY", 377 | "flag": "🇬🇾", 378 | "appStore": true 379 | }, 380 | { 381 | "name": "Hong Kong", 382 | "code": "HK", 383 | "flag": "🇭🇰", 384 | "appStore": true 385 | }, 386 | { 387 | "name": "Honduras", 388 | "code": "HN", 389 | "flag": "🇭🇳", 390 | "appStore": true 391 | }, 392 | { 393 | "name": "Croatia", 394 | "code": "HR", 395 | "flag": "🇭🇷", 396 | "appStore": true 397 | }, 398 | { 399 | "name": "Hungary", 400 | "code": "HU", 401 | "flag": "🇭🇺", 402 | "appStore": true 403 | }, 404 | { 405 | "name": "Indonesia", 406 | "code": "ID", 407 | "flag": "🇮🇩", 408 | "appStore": true 409 | }, 410 | { 411 | "name": "Ireland", 412 | "code": "IE", 413 | "flag": "🇮🇪", 414 | "appStore": true 415 | }, 416 | { 417 | "name": "Israel", 418 | "code": "IL", 419 | "flag": "🇮🇱", 420 | "appStore": true 421 | }, 422 | { 423 | "name": "India", 424 | "code": "IN", 425 | "flag": "🇮🇳", 426 | "appStore": true 427 | }, 428 | { 429 | "name": "Iraq", 430 | "code": "IQ", 431 | "flag": "🇮🇶", 432 | "appStore": true 433 | }, 434 | { 435 | "name": "Iceland", 436 | "code": "IS", 437 | "flag": "🇮🇸", 438 | "appStore": true 439 | }, 440 | { 441 | "name": "Italy", 442 | "code": "IT", 443 | "flag": "🇮🇹", 444 | "appStore": true 445 | }, 446 | { 447 | "name": "Jamaica", 448 | "code": "JM", 449 | "flag": "🇯🇲", 450 | "appStore": true 451 | }, 452 | { 453 | "name": "Jordan", 454 | "code": "JO", 455 | "flag": "🇯🇴", 456 | "appStore": true 457 | }, 458 | { 459 | "name": "Japan", 460 | "code": "JP", 461 | "flag": "🇯🇵", 462 | "appStore": true 463 | }, 464 | { 465 | "name": "Kenya", 466 | "code": "KE", 467 | "flag": "🇰🇪", 468 | "appStore": true 469 | }, 470 | { 471 | "name": "Kyrgyzstan", 472 | "code": "KG", 473 | "flag": "🇰🇬", 474 | "appStore": true 475 | }, 476 | { 477 | "name": "Cambodia", 478 | "code": "KH", 479 | "flag": "🇰🇭", 480 | "appStore": true 481 | }, 482 | { 483 | "name": "St. Kitts & Nevis", 484 | "code": "KN", 485 | "flag": "🇰🇳", 486 | "appStore": true 487 | }, 488 | { 489 | "name": "South Korea", 490 | "code": "KR", 491 | "flag": "🇰🇷", 492 | "appStore": true 493 | }, 494 | { 495 | "name": "Kuwait", 496 | "code": "KW", 497 | "flag": "🇰🇼", 498 | "appStore": true 499 | }, 500 | { 501 | "name": "Cayman Islands", 502 | "code": "KY", 503 | "flag": "🇰🇾", 504 | "appStore": true 505 | }, 506 | { 507 | "name": "Kazakhstan", 508 | "code": "KZ", 509 | "flag": "🇰🇿", 510 | "appStore": true 511 | }, 512 | { 513 | "name": "Laos", 514 | "code": "LA", 515 | "flag": "🇱🇦", 516 | "appStore": true 517 | }, 518 | { 519 | "name": "Lebanon", 520 | "code": "LB", 521 | "flag": "🇱🇧", 522 | "appStore": true 523 | }, 524 | { 525 | "name": "Saint Lucia", 526 | "code": "LC", 527 | "flag": "🇱🇨", 528 | "appStore": true 529 | }, 530 | { 531 | "name": "Sri Lanka", 532 | "code": "LK", 533 | "flag": "🇱🇰", 534 | "appStore": true 535 | }, 536 | { 537 | "name": "Liberia", 538 | "code": "LR", 539 | "flag": "🇱🇷", 540 | "appStore": true 541 | }, 542 | { 543 | "name": "Lithuania", 544 | "code": "LT", 545 | "flag": "🇱🇹", 546 | "appStore": true 547 | }, 548 | { 549 | "name": "Luxembourg", 550 | "code": "LU", 551 | "flag": "🇱🇺", 552 | "appStore": true 553 | }, 554 | { 555 | "name": "Latvia", 556 | "code": "LV", 557 | "flag": "🇱🇻", 558 | "appStore": true 559 | }, 560 | { 561 | "name": "Libya", 562 | "code": "LY", 563 | "flag": "🇱🇾", 564 | "appStore": true 565 | }, 566 | { 567 | "name": "Morocco", 568 | "code": "MA", 569 | "flag": "🇲🇦", 570 | "appStore": true 571 | }, 572 | { 573 | "name": "Moldova", 574 | "code": "MD", 575 | "flag": "🇲🇩", 576 | "appStore": true 577 | }, 578 | { 579 | "name": "Montenegro", 580 | "code": "ME", 581 | "flag": "🇲🇪", 582 | "appStore": true 583 | }, 584 | { 585 | "name": "Macedonia", 586 | "code": "MK", 587 | "flag": "🇲🇰", 588 | "appStore": true 589 | }, 590 | { 591 | "name": "Mali", 592 | "code": "ML", 593 | "flag": "🇲🇱", 594 | "appStore": true 595 | }, 596 | { 597 | "name": "Myanmar", 598 | "code": "MM", 599 | "flag": "🇲🇲", 600 | "appStore": true 601 | }, 602 | { 603 | "name": "Mongolia", 604 | "code": "MN", 605 | "flag": "🇲🇳", 606 | "appStore": true 607 | }, 608 | { 609 | "name": "Macau", 610 | "code": "MO", 611 | "flag": "🇲🇴", 612 | "appStore": true 613 | }, 614 | { 615 | "name": "Mauritania", 616 | "code": "MR", 617 | "flag": "🇲🇷", 618 | "appStore": true 619 | }, 620 | { 621 | "name": "Montserrat", 622 | "code": "MS", 623 | "flag": "🇲🇸", 624 | "appStore": true 625 | }, 626 | { 627 | "name": "Malta", 628 | "code": "MT", 629 | "flag": "🇲🇹", 630 | "appStore": true 631 | }, 632 | { 633 | "name": "Mauritius", 634 | "code": "MU", 635 | "flag": "🇲🇺", 636 | "appStore": true 637 | }, 638 | { 639 | "name": "Maldives", 640 | "code": "MV", 641 | "flag": "🇲🇻", 642 | "appStore": true 643 | }, 644 | { 645 | "name": "Malawi", 646 | "code": "MW", 647 | "flag": "🇲🇼", 648 | "appStore": true 649 | }, 650 | { 651 | "name": "Mexico", 652 | "code": "MX", 653 | "flag": "🇲🇽", 654 | "appStore": true 655 | }, 656 | { 657 | "name": "Malaysia", 658 | "code": "MY", 659 | "flag": "🇲🇾", 660 | "appStore": true 661 | }, 662 | { 663 | "name": "Mozambique", 664 | "code": "MZ", 665 | "flag": "🇲🇿", 666 | "appStore": true 667 | }, 668 | { 669 | "name": "Namibia", 670 | "code": "NA", 671 | "flag": "🇳🇦", 672 | "appStore": true 673 | }, 674 | { 675 | "name": "Niger", 676 | "code": "NE", 677 | "flag": "🇳🇪", 678 | "appStore": true 679 | }, 680 | { 681 | "name": "Nigeria", 682 | "code": "NG", 683 | "flag": "🇳🇬", 684 | "appStore": true 685 | }, 686 | { 687 | "name": "Nicaragua", 688 | "code": "NI", 689 | "flag": "🇳🇮", 690 | "appStore": true 691 | }, 692 | { 693 | "name": "Netherlands", 694 | "code": "NL", 695 | "flag": "🇳🇱", 696 | "appStore": true 697 | }, 698 | { 699 | "name": "Norway", 700 | "code": "NO", 701 | "flag": "🇳🇴", 702 | "appStore": true 703 | }, 704 | { 705 | "name": "Nepal", 706 | "code": "NP", 707 | "flag": "🇳🇵", 708 | "appStore": true 709 | }, 710 | { 711 | "name": "Nauru", 712 | "code": "NR", 713 | "flag": "🇳🇷", 714 | "appStore": true 715 | }, 716 | { 717 | "name": "New Zealand", 718 | "code": "NZ", 719 | "flag": "🇳🇿", 720 | "appStore": true 721 | }, 722 | { 723 | "name": "Oman", 724 | "code": "OM", 725 | "flag": "🇴🇲", 726 | "appStore": true 727 | }, 728 | { 729 | "name": "Panama", 730 | "code": "PA", 731 | "flag": "🇵🇦", 732 | "appStore": true 733 | }, 734 | { 735 | "name": "Peru", 736 | "code": "PE", 737 | "flag": "🇵🇪", 738 | "appStore": true 739 | }, 740 | { 741 | "name": "Papua New Guinea", 742 | "code": "PG", 743 | "flag": "🇵🇬", 744 | "appStore": true 745 | }, 746 | { 747 | "name": "Philippines", 748 | "code": "PH", 749 | "flag": "🇵🇭", 750 | "appStore": true 751 | }, 752 | { 753 | "name": "Pakistan", 754 | "code": "PK", 755 | "flag": "🇵🇰", 756 | "appStore": true 757 | }, 758 | { 759 | "name": "Poland", 760 | "code": "PL", 761 | "flag": "🇵🇱", 762 | "appStore": true 763 | }, 764 | { 765 | "name": "Portugal", 766 | "code": "PT", 767 | "flag": "🇵🇹", 768 | "appStore": true 769 | }, 770 | { 771 | "name": "Palau", 772 | "code": "PW", 773 | "flag": "🇵🇼", 774 | "appStore": true 775 | }, 776 | { 777 | "name": "Paraguay", 778 | "code": "PY", 779 | "flag": "🇵🇾", 780 | "appStore": true 781 | }, 782 | { 783 | "name": "Qatar", 784 | "code": "QA", 785 | "flag": "🇶🇦", 786 | "appStore": true 787 | }, 788 | { 789 | "name": "Romania", 790 | "code": "RO", 791 | "flag": "🇷🇴", 792 | "appStore": true 793 | }, 794 | { 795 | "name": "Serbia", 796 | "code": "RS", 797 | "flag": "🇷🇸", 798 | "appStore": true 799 | }, 800 | { 801 | "name": "Russia", 802 | "code": "RU", 803 | "flag": "🇷🇺", 804 | "appStore": true 805 | }, 806 | { 807 | "name": "Rwanda", 808 | "code": "RW", 809 | "flag": "🇷🇼", 810 | "appStore": true 811 | }, 812 | { 813 | "name": "Saudi Arabia", 814 | "code": "SA", 815 | "flag": "🇸🇦", 816 | "appStore": true 817 | }, 818 | { 819 | "name": "Solomon Islands", 820 | "code": "SB", 821 | "flag": "🇸🇧", 822 | "appStore": true 823 | }, 824 | { 825 | "name": "Seychelles", 826 | "code": "SC", 827 | "flag": "🇸🇨", 828 | "appStore": true 829 | }, 830 | { 831 | "name": "Sweden", 832 | "code": "SE", 833 | "flag": "🇸🇪", 834 | "appStore": true 835 | }, 836 | { 837 | "name": "Singapore", 838 | "code": "SG", 839 | "flag": "🇸🇬", 840 | "appStore": true 841 | }, 842 | { 843 | "name": "Slovenia", 844 | "code": "SI", 845 | "flag": "🇸🇮", 846 | "appStore": true 847 | }, 848 | { 849 | "name": "Slovakia", 850 | "code": "SK", 851 | "flag": "🇸🇰", 852 | "appStore": true 853 | }, 854 | { 855 | "name": "Sierra Leone", 856 | "code": "SL", 857 | "flag": "🇸🇱", 858 | "appStore": true 859 | }, 860 | { 861 | "name": "Senegal", 862 | "code": "SN", 863 | "flag": "🇸🇳", 864 | "appStore": true 865 | }, 866 | { 867 | "name": "Suriname", 868 | "code": "SR", 869 | "flag": "🇸🇷", 870 | "appStore": true 871 | }, 872 | { 873 | "name": "Sao Tome & Principe", 874 | "code": "ST", 875 | "flag": "🇸🇹", 876 | "appStore": true 877 | }, 878 | { 879 | "name": "El Salvador", 880 | "code": "SV", 881 | "flag": "🇸🇻", 882 | "appStore": true 883 | }, 884 | { 885 | "name": "Swaziland", 886 | "code": "SZ", 887 | "flag": "🇸🇿", 888 | "appStore": true 889 | }, 890 | { 891 | "name": "Turks & Caicos", 892 | "code": "TC", 893 | "flag": "🇹🇨", 894 | "appStore": true 895 | }, 896 | { 897 | "name": "Chad", 898 | "code": "TD", 899 | "flag": "🇹🇩", 900 | "appStore": true 901 | }, 902 | { 903 | "name": "Thailand", 904 | "code": "TH", 905 | "flag": "🇹🇭", 906 | "appStore": true 907 | }, 908 | { 909 | "name": "Tajikistan", 910 | "code": "TJ", 911 | "flag": "🇹🇯", 912 | "appStore": true 913 | }, 914 | { 915 | "name": "Turkmenistan", 916 | "code": "TM", 917 | "flag": "🇹🇲", 918 | "appStore": true 919 | }, 920 | { 921 | "name": "Tunisia", 922 | "code": "TN", 923 | "flag": "🇹🇳", 924 | "appStore": true 925 | }, 926 | { 927 | "name": "Tonga", 928 | "code": "TO", 929 | "flag": "🇹🇴", 930 | "appStore": true 931 | }, 932 | { 933 | "name": "Turkey", 934 | "code": "TR", 935 | "flag": "🇹🇷", 936 | "appStore": true 937 | }, 938 | { 939 | "name": "Trinidad & Tobago", 940 | "code": "TT", 941 | "flag": "🇹🇹", 942 | "appStore": true 943 | }, 944 | { 945 | "name": "Taiwan", 946 | "code": "TW", 947 | "flag": "🇹🇼", 948 | "appStore": true 949 | }, 950 | { 951 | "name": "Tanzania", 952 | "code": "TZ", 953 | "flag": "🇹🇿", 954 | "appStore": true 955 | }, 956 | { 957 | "name": "Ukraine", 958 | "code": "UA", 959 | "flag": "🇺🇦", 960 | "appStore": true 961 | }, 962 | { 963 | "name": "Uganda", 964 | "code": "UG", 965 | "flag": "🇺🇬", 966 | "appStore": true 967 | }, 968 | { 969 | "name": "United States", 970 | "code": "US", 971 | "flag": "🇺🇸", 972 | "appStore": true 973 | }, 974 | { 975 | "name": "Uruguay", 976 | "code": "UY", 977 | "flag": "🇺🇾", 978 | "appStore": true 979 | }, 980 | { 981 | "name": "Uzbekistan", 982 | "code": "UZ", 983 | "flag": "🇺🇿", 984 | "appStore": true 985 | }, 986 | { 987 | "name": "St. Vincent & The Grenadines", 988 | "code": "VC", 989 | "flag": "🇻🇨", 990 | "appStore": true 991 | }, 992 | { 993 | "name": "Venezuela", 994 | "code": "VE", 995 | "flag": "🇻🇨", 996 | "appStore": true 997 | }, 998 | { 999 | "name": "Virgin Islands", 1000 | "code": "VI", 1001 | "flag": "🇻🇮", 1002 | "appStore": true 1003 | }, 1004 | { 1005 | "name": "Vietnam", 1006 | "code": "VN", 1007 | "flag": "🇻🇳", 1008 | "appStore": true 1009 | }, 1010 | { 1011 | "name": "Vanuatu", 1012 | "code": "VU", 1013 | "flag": "🇰🇳", 1014 | "appStore": true 1015 | }, 1016 | { 1017 | "name": "Kosovo", 1018 | "code": "XK", 1019 | "flag": "🇽🇰", 1020 | "appStore": true 1021 | }, 1022 | { 1023 | "name": "Yemen", 1024 | "code": "YE", 1025 | "flag": "🇾🇪", 1026 | "appStore": true 1027 | }, 1028 | { 1029 | "name": "South Africa", 1030 | "code": "ZA", 1031 | "flag": "🇿🇦", 1032 | "appStore": true 1033 | }, 1034 | { 1035 | "name": "Zambia", 1036 | "code": "ZM", 1037 | "flag": "🇿🇲", 1038 | "appStore": true 1039 | }, 1040 | { 1041 | "name": "Zimbabwe", 1042 | "code": "ZW", 1043 | "flag": "🇿🇼", 1044 | "appStore": true 1045 | }, 1046 | { 1047 | "name": "Andorra", 1048 | "code": "AD", 1049 | "flag": "🇦🇩", 1050 | "appStore": false 1051 | }, 1052 | { 1053 | "name": "Antarctica", 1054 | "code": "AQ", 1055 | "flag": "🇦🇶", 1056 | "appStore": false 1057 | }, 1058 | { 1059 | "name": "American Samoa", 1060 | "code": "AS", 1061 | "flag": "🇦🇸", 1062 | "appStore": false 1063 | }, 1064 | { 1065 | "name": "Aruba", 1066 | "code": "AW", 1067 | "flag": "🇦🇼", 1068 | "appStore": false 1069 | }, 1070 | { 1071 | "name": "Åland Islands", 1072 | "code": "AX", 1073 | "flag": "🇦🇽", 1074 | "appStore": false 1075 | }, 1076 | { 1077 | "name": "Bangladesh", 1078 | "code": "BD", 1079 | "flag": "🇧🇩", 1080 | "appStore": false 1081 | }, 1082 | { 1083 | "name": "Burundi", 1084 | "code": "BI", 1085 | "flag": "🇧🇮", 1086 | "appStore": false 1087 | }, 1088 | { 1089 | "name": "Saint Barthélemy", 1090 | "code": "BL", 1091 | "flag": "🇧🇱", 1092 | "appStore": false 1093 | }, 1094 | { 1095 | "name": "Bonaire, Sint Eustatius and Saba", 1096 | "code": "BQ", 1097 | "flag": "🇧🇶", 1098 | "appStore": false 1099 | }, 1100 | { 1101 | "name": "Bouvet Island", 1102 | "code": "BV", 1103 | "flag": "🇧🇻", 1104 | "appStore": false 1105 | }, 1106 | { 1107 | "name": "Cocos (Keeling) Islands", 1108 | "code": "CC", 1109 | "flag": "🇨🇨", 1110 | "appStore": false 1111 | }, 1112 | { 1113 | "name": "Central African Republic", 1114 | "code": "CF", 1115 | "flag": "🇨🇫", 1116 | "appStore": false 1117 | }, 1118 | { 1119 | "name": "Cook Islands", 1120 | "code": "CK", 1121 | "flag": "🇨🇰", 1122 | "appStore": false 1123 | }, 1124 | { 1125 | "name": "Cameroon", 1126 | "code": "CM", 1127 | "flag": "🇨🇲", 1128 | "appStore": false 1129 | }, 1130 | { 1131 | "name": "Cuba", 1132 | "code": "CU", 1133 | "flag": "🇨🇺", 1134 | "appStore": false 1135 | }, 1136 | { 1137 | "name": "Curaçao", 1138 | "code": "CW", 1139 | "flag": "🇨🇼", 1140 | "appStore": false 1141 | }, 1142 | { 1143 | "name": "Christmas Island", 1144 | "code": "CX", 1145 | "flag": "🇨🇽", 1146 | "appStore": false 1147 | }, 1148 | { 1149 | "name": "Djibouti", 1150 | "code": "DJ", 1151 | "flag": "🇩🇯", 1152 | "appStore": false 1153 | }, 1154 | { 1155 | "name": "Western Sahara", 1156 | "code": "EH", 1157 | "flag": "🇪🇭", 1158 | "appStore": false 1159 | }, 1160 | { 1161 | "name": "Eritrea", 1162 | "code": "ER", 1163 | "flag": "🇪🇷", 1164 | "appStore": false 1165 | }, 1166 | { 1167 | "name": "Ethiopia", 1168 | "code": "ET", 1169 | "flag": "🇪🇹", 1170 | "appStore": false 1171 | }, 1172 | { 1173 | "name": "Falkland Islands (Malvinas)", 1174 | "code": "FK", 1175 | "flag": "🇫🇰", 1176 | "appStore": false 1177 | }, 1178 | { 1179 | "name": "Faroe Islands", 1180 | "code": "FO", 1181 | "flag": "🇫🇴", 1182 | "appStore": false 1183 | }, 1184 | { 1185 | "name": "French Guiana", 1186 | "code": "GF", 1187 | "flag": "🇬🇫", 1188 | "appStore": false 1189 | }, 1190 | { 1191 | "name": "Guernsey", 1192 | "code": "GG", 1193 | "flag": "🇬🇬", 1194 | "appStore": false 1195 | }, 1196 | { 1197 | "name": "Gibraltar", 1198 | "code": "GI", 1199 | "flag": "🇬🇮", 1200 | "appStore": false 1201 | }, 1202 | { 1203 | "name": "Greenland", 1204 | "code": "GL", 1205 | "flag": "🇬🇱", 1206 | "appStore": false 1207 | }, 1208 | { 1209 | "name": "Guinea", 1210 | "code": "GN", 1211 | "flag": "🇬🇳", 1212 | "appStore": false 1213 | }, 1214 | { 1215 | "name": "Guadeloupe", 1216 | "code": "GP", 1217 | "flag": "🇬🇵", 1218 | "appStore": false 1219 | }, 1220 | { 1221 | "name": "Equatorial Guinea", 1222 | "code": "GQ", 1223 | "flag": "🇬🇶", 1224 | "appStore": false 1225 | }, 1226 | { 1227 | "name": "South Georgia", 1228 | "code": "GS", 1229 | "flag": "🇬🇸", 1230 | "appStore": false 1231 | }, 1232 | { 1233 | "name": "Guam", 1234 | "code": "GU", 1235 | "flag": "🇬🇺", 1236 | "appStore": false 1237 | }, 1238 | { 1239 | "name": "Heard Island and Mcdonald Islands", 1240 | "code": "HM", 1241 | "flag": "🇭🇲", 1242 | "appStore": false 1243 | }, 1244 | { 1245 | "name": "Haiti", 1246 | "code": "HT", 1247 | "flag": "🇭🇹", 1248 | "appStore": false 1249 | }, 1250 | { 1251 | "name": "Isle of Man", 1252 | "code": "IM", 1253 | "flag": "🇮🇲", 1254 | "appStore": false 1255 | }, 1256 | { 1257 | "name": "British Indian Ocean Territory", 1258 | "code": "IO", 1259 | "flag": "🇮🇴", 1260 | "appStore": false 1261 | }, 1262 | { 1263 | "name": "Iran", 1264 | "code": "IR", 1265 | "flag": "🇮🇷", 1266 | "appStore": false 1267 | }, 1268 | { 1269 | "name": "Jersey", 1270 | "code": "JE", 1271 | "flag": "🇯🇪", 1272 | "appStore": false 1273 | }, 1274 | { 1275 | "name": "Kiribati", 1276 | "code": "KI", 1277 | "flag": "🇰🇮", 1278 | "appStore": false 1279 | }, 1280 | { 1281 | "name": "Comoros", 1282 | "code": "KM", 1283 | "flag": "🇰🇲", 1284 | "appStore": false 1285 | }, 1286 | { 1287 | "name": "North Korea", 1288 | "code": "KP", 1289 | "flag": "🇰🇵", 1290 | "appStore": false 1291 | }, 1292 | { 1293 | "name": "Liechtenstein", 1294 | "code": "LI", 1295 | "flag": "🇱🇮", 1296 | "appStore": false 1297 | }, 1298 | { 1299 | "name": "Lesotho", 1300 | "code": "LS", 1301 | "flag": "🇱🇸", 1302 | "appStore": false 1303 | }, 1304 | { 1305 | "name": "Monaco", 1306 | "code": "MC", 1307 | "flag": "🇲🇨", 1308 | "appStore": false 1309 | }, 1310 | { 1311 | "name": "Saint Martin (French Part)", 1312 | "code": "MF", 1313 | "flag": "🇲🇫", 1314 | "appStore": false 1315 | }, 1316 | { 1317 | "name": "Madagascar", 1318 | "code": "MG", 1319 | "flag": "🇲🇬", 1320 | "appStore": true 1321 | }, 1322 | { 1323 | "name": "Marshall Islands", 1324 | "code": "MH", 1325 | "flag": "🇲🇭", 1326 | "appStore": false 1327 | }, 1328 | { 1329 | "name": "Northern Mariana Islands", 1330 | "code": "MP", 1331 | "flag": "🇲🇵", 1332 | "appStore": false 1333 | }, 1334 | { 1335 | "name": "Martinique", 1336 | "code": "MQ", 1337 | "flag": "🇲🇶", 1338 | "appStore": false 1339 | }, 1340 | { 1341 | "name": "New Caledonia", 1342 | "code": "NC", 1343 | "flag": "🇳🇨", 1344 | "appStore": false 1345 | }, 1346 | { 1347 | "name": "Norfolk Island", 1348 | "code": "NF", 1349 | "flag": "🇳🇫", 1350 | "appStore": false 1351 | }, 1352 | { 1353 | "name": "Nauru", 1354 | "code": "NR", 1355 | "flag": "🇳🇷", 1356 | "appStore": false 1357 | }, 1358 | { 1359 | "name": "Niue", 1360 | "code": "NU", 1361 | "flag": "🇳🇺", 1362 | "appStore": false 1363 | }, 1364 | { 1365 | "name": "French Polynesia", 1366 | "code": "PF", 1367 | "flag": "🇵🇫", 1368 | "appStore": false 1369 | }, 1370 | { 1371 | "name": "Saint Pierre and Miquelon", 1372 | "code": "PM", 1373 | "flag": "🇵🇲", 1374 | "appStore": false 1375 | }, 1376 | { 1377 | "name": "Pitcairn", 1378 | "code": "PN", 1379 | "flag": "🇵🇳", 1380 | "appStore": false 1381 | }, 1382 | { 1383 | "name": "Puerto Rico", 1384 | "code": "PR", 1385 | "flag": "🇵🇷", 1386 | "appStore": false 1387 | }, 1388 | { 1389 | "name": "Palestinian Territory", 1390 | "code": "PS", 1391 | "flag": "🇵🇸", 1392 | "appStore": false 1393 | }, 1394 | { 1395 | "name": "Réunion", 1396 | "code": "RE", 1397 | "flag": "🇷🇪", 1398 | "appStore": false 1399 | }, 1400 | { 1401 | "name": "Sudan", 1402 | "code": "SD", 1403 | "flag": "🇸🇩", 1404 | "appStore": false 1405 | }, 1406 | { 1407 | "name": "Saint Helena, Ascension and Tristan Da Cunha", 1408 | "code": "SH", 1409 | "flag": "🇸🇭", 1410 | "appStore": false 1411 | }, 1412 | { 1413 | "name": "Svalbard and Jan Mayen", 1414 | "code": "SJ", 1415 | "flag": "🇸🇯", 1416 | "appStore": false 1417 | }, 1418 | { 1419 | "name": "San Marino", 1420 | "code": "SM", 1421 | "flag": "🇸🇲", 1422 | "appStore": false 1423 | }, 1424 | { 1425 | "name": "Somalia", 1426 | "code": "SO", 1427 | "flag": "🇸🇴", 1428 | "appStore": false 1429 | }, 1430 | { 1431 | "name": "South Sudan", 1432 | "code": "SS", 1433 | "flag": "🇸🇸", 1434 | "appStore": false 1435 | }, 1436 | { 1437 | "name": "Sint Maarten (Dutch Part)", 1438 | "code": "SX", 1439 | "flag": "🇸🇽", 1440 | "appStore": false 1441 | }, 1442 | { 1443 | "name": "Syrian Arab Republic", 1444 | "code": "SY", 1445 | "flag": "🇸🇾", 1446 | "appStore": false 1447 | }, 1448 | { 1449 | "name": "French Southern Territories", 1450 | "code": "TF", 1451 | "flag": "🇹🇫", 1452 | "appStore": false 1453 | }, 1454 | { 1455 | "name": "Togo", 1456 | "code": "TG", 1457 | "flag": "🇹🇬", 1458 | "appStore": false 1459 | }, 1460 | { 1461 | "name": "Tokelau", 1462 | "code": "TK", 1463 | "flag": "🇹🇰", 1464 | "appStore": false 1465 | }, 1466 | { 1467 | "name": "Timor-Leste", 1468 | "code": "TL", 1469 | "flag": "🇹🇱", 1470 | "appStore": false 1471 | }, 1472 | { 1473 | "name": "Tuvalu", 1474 | "code": "TV", 1475 | "flag": "🇹🇻", 1476 | "appStore": false 1477 | }, 1478 | { 1479 | "name": "Vatican City", 1480 | "code": "VA", 1481 | "flag": "🇻🇦", 1482 | "appStore": false 1483 | }, 1484 | { 1485 | "name": "Virgin Islands, British", 1486 | "code": "VG", 1487 | "flag": "🇻🇬", 1488 | "appStore": false 1489 | }, 1490 | { 1491 | "name": "Wallis and Futuna", 1492 | "code": "WF", 1493 | "flag": "🇼🇫", 1494 | "appStore": false 1495 | }, 1496 | { 1497 | "name": "Samoa", 1498 | "code": "WS", 1499 | "flag": "🇼🇸", 1500 | "appStore": false 1501 | }, 1502 | { 1503 | "name": "Mayotte", 1504 | "code": "YT", 1505 | "flag": "🇾🇹", 1506 | "appStore": false 1507 | } 1508 | ] 1509 | -------------------------------------------------------------------------------- /Custom Picker/CustomPickerTextView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomPickerTextView.swift 3 | // Custom Picker 4 | // 5 | // Created by Stewart Lynch on 2020-08-19. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct CustomPickerTextView: View { 11 | @Binding var presentPicker: Bool 12 | @Binding var fieldString: String 13 | var placeholder: String 14 | @Binding var tag: Int 15 | var selectedTag: Int 16 | var body: some View { 17 | TextField(placeholder, text: $fieldString).disabled(true) 18 | .overlay( 19 | Button(action: { 20 | tag = selectedTag 21 | withAnimation { 22 | presentPicker = true 23 | } 24 | }) { 25 | Rectangle().foregroundColor((Color.clear)) 26 | } 27 | ) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Custom Picker/CustomPickerView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomPickerView.swift 3 | // Custom Picker 4 | // 5 | // Created by Stewart Lynch on 2020-08-17. 6 | // 7 | 8 | import SwiftUI 9 | 10 | protocol CustomPicker { 11 | func saveUpdates(_ newItem: String) 12 | } 13 | 14 | struct CustomPickerView: View { 15 | var items: [String] 16 | @State private var filteredItems: [String] = [] 17 | @State private var filterString: String = "" 18 | @State private var frameHeight: CGFloat = 400 19 | @FocusState private var inFocus: Bool? 20 | @Binding var pickerField: String 21 | @Binding var presentPicker: Bool 22 | var saveUpdates: ((String) -> Void)? 23 | var body: some View { 24 | let filterBinding = Binding ( 25 | get: { filterString }, 26 | set: { 27 | filterString = $0 28 | if filterString != "" { 29 | filteredItems = items.filter{$0.lowercased().contains(filterString.lowercased())} 30 | } else { 31 | filteredItems = items 32 | } 33 | setHeight() 34 | } 35 | ) 36 | return ZStack { 37 | Color.black.opacity(0.4) 38 | VStack { 39 | VStack(alignment: .leading, spacing: 5) { 40 | HStack { 41 | Button(action: { 42 | withAnimation { 43 | presentPicker = false 44 | } 45 | }) { 46 | Text("Cancel") 47 | } 48 | .padding(10) 49 | Spacer() 50 | if let saveUpdates = saveUpdates { 51 | Button(action: { 52 | if !items.contains(filterString) { 53 | saveUpdates(filterString) 54 | } 55 | pickerField = filterString 56 | withAnimation { 57 | presentPicker = false 58 | } 59 | }) { 60 | Image(systemName: "plus.circle") 61 | .frame(width: 44, height: 44) 62 | } 63 | .disabled(filterString.isEmpty) 64 | } 65 | } 66 | .background(Color(UIColor.darkGray)) 67 | .foregroundColor(.white) 68 | Text("Tap an entry to select it, or type in a new entry.") 69 | .font(.caption) 70 | .padding(.leading,10) 71 | TextField("Filter by entering text", text: filterBinding) 72 | .textFieldStyle(RoundedBorderTextFieldStyle()) 73 | .focused($inFocus, equals: true) 74 | .padding() 75 | List { 76 | ForEach(filteredItems, id: \.self) { item in 77 | Button(action: { 78 | pickerField = item 79 | withAnimation { 80 | presentPicker = false 81 | } 82 | }) { 83 | Text(item) 84 | } 85 | } 86 | } 87 | .listStyle(.plain) 88 | } 89 | .background(Color(UIColor.secondarySystemBackground)) 90 | .cornerRadius(10) 91 | .frame(maxWidth: 400) 92 | .padding(.horizontal,10) 93 | .frame(height: frameHeight) 94 | .padding(.top, 40) 95 | Spacer() 96 | } 97 | } 98 | .edgesIgnoringSafeArea(.all) 99 | .task { 100 | try? await Task.sleep(nanoseconds: 250_000_000) 101 | inFocus = true 102 | filteredItems = items 103 | setHeight() 104 | } 105 | } 106 | 107 | fileprivate func setHeight() { 108 | withAnimation { 109 | if filteredItems.count > 5 { 110 | frameHeight = 400 111 | } else if filteredItems.count == 0 { 112 | frameHeight = 130 113 | } else { 114 | frameHeight = CGFloat(filteredItems.count * 45 + 130) 115 | } 116 | } 117 | } 118 | 119 | } 120 | 121 | struct CustomPickerView_Previews: PreviewProvider { 122 | static let sampleData = ["Milk", "Apples", "Sugar", "Eggs", "Oranges", "Potatoes", "Corn", "Bread"].sorted() 123 | static var previews: some View { 124 | CustomPickerView(items: sampleData, pickerField: .constant(""), presentPicker: .constant(true)) 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Custom Picker/Custom_PickerApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Custom_PickerApp.swift 3 | // Custom Picker 4 | // 5 | // Created by Stewart Lynch on 2020-08-13. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct Custom_PickerApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Custom Picker/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UIApplicationSupportsIndirectInputEvents 29 | 30 | UILaunchScreen 31 | 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Custom Picker/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Stewart Lynch 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reusable CustomPicker for SwiftUI 2 | 3 | This is the completed playground for the YouTube video of the same name 4 | 5 | The starter project and video is available in the notes for the video. 6 | 7 | Reusable Custom Picker for SwiftUI 10 | 11 | ## Checklist for implementing CustomPicker 12 | 13 | - [ ] Conform to CustomPicker (this will require the addition of the saveUpdates function. If you are not allowing updates to the array in any of your pickers you can just leave the function block empty). 14 | 15 | ````swift 16 | struct ContentView: View, CustomPicker 17 | ```` 18 | 19 | ````swift 20 | func saveUpdates(_ newItem: String) { 21 | // Leave body empty if you are not allowing updates to the list 22 | } 23 | ```` 24 | 25 | - [ ] Add a string state variable for your each of you customPickerTextFields. this will be bound to the corresponding TextField 26 | 27 | ````swift 28 | @State private var fieldName = "" 29 | ```` 30 | 31 | - [ ] Add a property that will access provide access to the corresponding string array. 32 | 33 | ````swift 34 | // example 35 | @State private var foodArray = ["Milk", "Apples", "Sugar", "Eggs", "Oranges", "Potatoes", "Corn", "Bread"] 36 | ```` 37 | 38 | or, it could be a viewModel that has a property that you will be able to generate the array from. 39 | 40 | ````swift 41 | @StateObject private var countriesVM = CountryViewModel() 42 | ```` 43 | 44 | - [ ] Create a tag state variable that is initialized as an integer of 1 45 | 46 | ````swift 47 | @State private var tag: Int = 1 48 | ```` 49 | 50 | - [ ] Create a boolean state variable called presentPicker 51 | 52 | ````swift 53 | @State private var presentPicker = false 54 | ```` 55 | 56 | - [ ] In your content view, create your custom picker text views making sure that you assign a tag, even if there is only one picker. 57 | 58 | ````swift 59 | CustomPickerTextView(presentPicker: $presentPicker, 60 | fieldString: $food, 61 | placeholder: "Select a food item.", 62 | tag: $tag, 63 | selectedTag: 1) 64 | CustomPickerTextView(presentPicker: $presentPicker, 65 | fieldString: $country, 66 | placeholder: "Select a country.", 67 | tag: $tag, 68 | selectedTag: 2) 69 | ```` 70 | 71 | - [ ] Embed your View in a ZStack. 72 | 73 | ````swift 74 | ZStack { 75 | NavigationView{ // You may not have a NavigationView 76 | // your content 77 | } 78 | } 79 | ```` 80 | 81 | - [ ] In the font most (bottom ) view of the ZStack, use the if pesentPicker block to check which view you want to present based on the tag and present your CustomPickerView and make sure you include .zIndex(1) 82 | 83 | ````swift 84 | if presentPicker { 85 | if tag == 1 { 86 | CustomPickerView(items: foodArray.sorted(), 87 | pickerField: $food, 88 | presentPicker: $presentPicker, 89 | saveUpdates: saveUpdates) 90 | .zIndex(1) 91 | } else { 92 | CustomPickerView(items: countriesVM.countryNamesArray, 93 | pickerField: $country, 94 | presentPicker: $presentPicker) 95 | .zIndex(1.0) 96 | } 97 | } 98 | ```` 99 | 100 | 101 | 102 | - [ ] And Finally, if any of your custom picker views allow updates. Check the tag if necessary and provide the functiosn that will add the selected string to the array. 103 | 104 | ````swift 105 | func saveUpdates(_ newItem: String) { 106 | if tag == 1 { 107 | // code for updating the array for tag 1 108 | } else if tag == 2 { 109 | // code for updating the array for tag 2 110 | } 111 | // more checks if needed 112 | } 113 | ```` 114 | 115 | 116 | 117 | 118 | --------------------------------------------------------------------------------