├── .gitattributes ├── .gitignore ├── Demo.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── Demo.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── WorkspaceSettings.xcsettings ├── Demo ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── LRF │ │ ├── Contents.json │ │ ├── ic_contactno.imageset │ │ │ ├── Contents.json │ │ │ ├── icons8-phone-100.png │ │ │ ├── icons8-phone-100@2x.png │ │ │ └── icons8-phone-100@3x.png │ │ ├── ic_dob.imageset │ │ │ ├── Contents.json │ │ │ ├── icons8-birth-date-100.png │ │ │ ├── icons8-birth-date-100@2x.png │ │ │ └── icons8-birth-date-100@3x.png │ │ ├── ic_drop_down.imageset │ │ │ ├── Contents.json │ │ │ ├── ic_drop_down.png │ │ │ ├── ic_drop_down@2x.png │ │ │ └── ic_drop_down@3x.png │ │ ├── ic_email.imageset │ │ │ ├── Contents.json │ │ │ ├── icons8-important-mail-96.png │ │ │ ├── icons8-important-mail-96@2x.png │ │ │ └── icons8-important-mail-96@3x.png │ │ ├── ic_password.imageset │ │ │ ├── Contents.json │ │ │ ├── icons8-password-1-90.png │ │ │ ├── icons8-password-1-90@2x.png │ │ │ └── icons8-password-1-90@3x.png │ │ └── ic_user.imageset │ │ │ ├── Contents.json │ │ │ ├── ic_user.png │ │ │ ├── ic_user@2x.png │ │ │ └── ic_user@3x.png │ ├── Onboarding │ │ ├── Contents.json │ │ ├── First.imageset │ │ │ ├── Contents.json │ │ │ └── onboard1.png │ │ ├── Second.imageset │ │ │ ├── Contents.json │ │ │ └── Ios-13.png │ │ └── Third.imageset │ │ │ ├── 14.jpeg │ │ │ └── Contents.json │ ├── SwiftUILogo.imageset │ │ ├── Contents.json │ │ └── SwiftUiLogo.jpeg │ ├── Tabbar │ │ ├── Contents.json │ │ ├── ic_controls.imageset │ │ │ ├── Contents.json │ │ │ ├── controls.png │ │ │ ├── controls@2x.png │ │ │ └── controls@3x.png │ │ ├── ic_favourite_tabbar.imageset │ │ │ ├── Contents.json │ │ │ ├── ic_favourite.png │ │ │ ├── ic_favourite@2x.png │ │ │ └── ic_favourite@3x.png │ │ └── ic_home.imageset │ │ │ ├── Contents.json │ │ │ ├── ic_home.png │ │ │ ├── ic_home@2x.png │ │ │ └── ic_home@3x.png │ ├── birds │ │ ├── Contents.json │ │ ├── bird.imageset │ │ │ ├── 2.jpeg │ │ │ └── Contents.json │ │ ├── pink-birds.imageset │ │ │ ├── 3.jpeg │ │ │ └── Contents.json │ │ ├── prrotes.imageset │ │ │ ├── 6.jpeg │ │ │ └── Contents.json │ │ ├── sparrows.imageset │ │ │ ├── 5.jpeg │ │ │ └── Contents.json │ │ ├── white-bird.imageset │ │ │ ├── 1.jpeg │ │ │ └── Contents.json │ │ └── white-ducks.imageset │ │ │ ├── 4.jpeg │ │ │ └── Contents.json │ ├── logo.imageset │ │ ├── Contents.json │ │ └── logo.jpeg │ └── simpleLifeCycle.imageset │ │ ├── Contents.json │ │ └── simpleLifeCycle.png ├── Base.lproj │ └── LaunchScreen.storyboard ├── ContentView.swift ├── DataStore.swift ├── Details │ ├── FormView.swift │ ├── MView.swift │ ├── PickerView.swift │ ├── SegmentcontrolView.swift │ └── TextView.swift ├── Home │ ├── Collection │ │ ├── CollectionUI.swift │ │ ├── CollectionView.swift │ │ ├── CustomCell.swift │ │ └── CustomCell.xib │ ├── GridCollection.swift │ ├── HeaderCollVCell.swift │ ├── HeaderCollView.swift │ ├── HomeVC.swift │ ├── List │ │ └── ListView.swift │ ├── ProductListCollVCell.swift │ ├── ProductListCollView.swift │ ├── ProductTypeCollVCell.swift │ └── ProductTypeCollView.swift ├── HomeTopPageControll │ ├── PageVC.swift │ └── TopView.swift ├── Info.plist ├── LRF │ ├── ForgotPasswordView.swift │ ├── LoginView.swift │ └── SignUpView.swift ├── Onboarding │ ├── OnboardingView.swift │ ├── PageControl.swift │ ├── PageViewController.swift │ ├── PagesView.swift │ └── Subview.swift ├── Other │ └── OtherData.swift ├── Preview Content │ └── Preview Assets.xcassets │ │ ├── Contents.json │ │ └── TextColor.colorset │ │ └── Contents.json ├── SceneDelegate.swift ├── SignUP(Combine framework) │ ├── SignupVC.swift │ └── UserViewModel.swift ├── TabBar │ ├── CurrentOrderVC.swift │ ├── FavouritesVC.swift │ ├── NotificationVC.swift │ ├── TabBarView.swift │ └── TabbarVC.swift └── UserDefault.swift ├── LICENSE ├── Media ├── SwiftUI-Sample-App.gif └── SwiftUI-Sample-App.mp4 ├── Podfile ├── Podfile.lock ├── Pods ├── IQKeyboardManagerSwift │ ├── IQKeyboardManagerSwift │ │ ├── Categories │ │ │ ├── IQNSArray+Sort.swift │ │ │ ├── IQUIScrollView+Additions.swift │ │ │ ├── IQUITextFieldView+Additions.swift │ │ │ ├── IQUIView+Hierarchy.swift │ │ │ └── IQUIViewController+Additions.swift │ │ ├── Constants │ │ │ ├── IQKeyboardManagerConstants.swift │ │ │ └── IQKeyboardManagerConstantsInternal.swift │ │ ├── IQKeyboardManager.swift │ │ ├── IQKeyboardReturnKeyHandler.swift │ │ ├── IQTextView │ │ │ └── IQTextView.swift │ │ ├── IQToolbar │ │ │ ├── IQBarButtonItem.swift │ │ │ ├── IQInvocation.swift │ │ │ ├── IQPreviousNextView.swift │ │ │ ├── IQTitleBarButtonItem.swift │ │ │ ├── IQToolbar.swift │ │ │ └── IQUIView+IQKeyboardToolbar.swift │ │ └── Resources │ │ │ └── IQKeyboardManager.bundle │ │ │ ├── IQButtonBarArrowDown@2x.png │ │ │ ├── IQButtonBarArrowDown@3x.png │ │ │ ├── IQButtonBarArrowLeft@2x.png │ │ │ ├── IQButtonBarArrowLeft@3x.png │ │ │ ├── IQButtonBarArrowRight@2x.png │ │ │ ├── IQButtonBarArrowRight@3x.png │ │ │ ├── IQButtonBarArrowUp@2x.png │ │ │ └── IQButtonBarArrowUp@3x.png │ ├── LICENSE.md │ └── README.md ├── Manifest.lock ├── Navajo-Swift │ ├── LICENSE │ ├── README.md │ └── Source │ │ ├── AllowedCharacterRule.swift │ │ ├── BlockRule.swift │ │ ├── DictionaryWordRule.swift │ │ ├── LengthRule.swift │ │ ├── Navajo.swift │ │ ├── PasswordRule.swift │ │ ├── PasswordValidator.swift │ │ ├── PredicateRule.swift │ │ ├── RegularExpressionRule.swift │ │ └── RequiredCharacterRule.swift ├── Pods.xcodeproj │ └── project.pbxproj └── Target Support Files │ ├── IQKeyboardManagerSwift │ ├── IQKeyboardManagerSwift-Info.plist │ ├── IQKeyboardManagerSwift-dummy.m │ ├── IQKeyboardManagerSwift-prefix.pch │ ├── IQKeyboardManagerSwift-umbrella.h │ ├── IQKeyboardManagerSwift.modulemap │ └── IQKeyboardManagerSwift.xcconfig │ ├── Navajo-Swift │ ├── Navajo-Swift-Info.plist │ ├── Navajo-Swift-dummy.m │ ├── Navajo-Swift-prefix.pch │ ├── Navajo-Swift-umbrella.h │ ├── Navajo-Swift.modulemap │ └── Navajo-Swift.xcconfig │ └── Pods-Demo │ ├── Pods-Demo-Info.plist │ ├── Pods-Demo-acknowledgements.markdown │ ├── Pods-Demo-acknowledgements.plist │ ├── Pods-Demo-dummy.m │ ├── Pods-Demo-frameworks-Debug-input-files.xcfilelist │ ├── Pods-Demo-frameworks-Debug-output-files.xcfilelist │ ├── Pods-Demo-frameworks-Release-input-files.xcfilelist │ ├── Pods-Demo-frameworks-Release-output-files.xcfilelist │ ├── Pods-Demo-frameworks.sh │ ├── Pods-Demo-umbrella.h │ ├── Pods-Demo.debug.xcconfig │ ├── Pods-Demo.modulemap │ └── Pods-Demo.release.xcconfig └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | *.* linguist-language=swift 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/swift,cocoapods,objective-c 3 | # Edit at https://www.gitignore.io/?templates=swift,cocoapods,objective-c 4 | 5 | ### CocoaPods ### 6 | ## CocoaPods GitIgnore Template 7 | 8 | # CocoaPods - Only use to conserve bandwidth / Save time on Pushing 9 | # - Also handy if you have a large number of dependant pods 10 | # - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE 11 | Pods/ 12 | 13 | ### Objective-C ### 14 | # Xcode 15 | # 16 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 17 | 18 | ## Build generated 19 | build/ 20 | DerivedData/ 21 | 22 | ## Various settings 23 | *.pbxuser 24 | !default.pbxuser 25 | *.mode1v3 26 | !default.mode1v3 27 | *.mode2v3 28 | !default.mode2v3 29 | *.perspectivev3 30 | !default.perspectivev3 31 | xcuserdata/ 32 | 33 | ## Other 34 | *.moved-aside 35 | *.xccheckout 36 | *.xcscmblueprint 37 | 38 | ## Obj-C/Swift specific 39 | *.hmap 40 | *.ipa 41 | *.dSYM.zip 42 | *.dSYM 43 | 44 | # CocoaPods 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # Pods/ 49 | # Add this line if you want to avoid checking in source code from the Xcode workspace 50 | # *.xcworkspace 51 | 52 | # Carthage 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 60 | # screenshots whenever they are needed. 61 | # For more information about the recommended setup visit: 62 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 63 | 64 | fastlane/report.xml 65 | fastlane/Preview.html 66 | fastlane/screenshots/**/*.png 67 | fastlane/test_output 68 | 69 | # Code Injection 70 | # After new code Injection tools there's a generated folder /iOSInjectionProject 71 | # https://github.com/johnno1962/injectionforxcode 72 | 73 | iOSInjectionProject/ 74 | 75 | ### Objective-C Patch ### 76 | 77 | ### Swift ### 78 | # Xcode 79 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 80 | 81 | 82 | 83 | 84 | 85 | ## Playgrounds 86 | timeline.xctimeline 87 | playground.xcworkspace 88 | 89 | # Swift Package Manager 90 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 91 | # Packages/ 92 | # Package.pins 93 | # Package.resolved 94 | .build/ 95 | # Add this line if you want to avoid checking in Xcode SPM integration. 96 | # .swiftpm/xcode 97 | 98 | # CocoaPods 99 | # We recommend against adding the Pods directory to your .gitignore. However 100 | # you should judge for yourself, the pros and cons are mentioned at: 101 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 102 | # Pods/ 103 | # Add this line if you want to avoid checking in source code from the Xcode workspace 104 | # *.xcworkspace 105 | 106 | # Carthage 107 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 108 | # Carthage/Checkouts 109 | 110 | 111 | # Accio dependency management 112 | Dependencies/ 113 | .accio/ 114 | 115 | # fastlane 116 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 117 | # screenshots whenever they are needed. 118 | # For more information about the recommended setup visit: 119 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 120 | 121 | 122 | # Code Injection 123 | # After new code Injection tools there's a generated folder /iOSInjectionProject 124 | # https://github.com/johnno1962/injectionforxcode 125 | 126 | 127 | # End of https://www.gitignore.io/api/swift,cocoapods,objective-c -------------------------------------------------------------------------------- /Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Demo.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Demo 4 | // 5 | // Created by mac-00018 on 21/10/19. 6 | // Copyright © 2019 mac-00018. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | // Override point for customization after application launch. 18 | return true 19 | } 20 | 21 | // MARK: UISceneSession Lifecycle 22 | 23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 24 | // Called when a new scene session is being created. 25 | // Use this method to select a configuration to create the new scene with. 26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 27 | } 28 | 29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 30 | // Called when the user discards a scene session. 31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 33 | } 34 | 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Demo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_contactno.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icons8-phone-100.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "icons8-phone-100@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "icons8-phone-100@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_contactno.imageset/icons8-phone-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_contactno.imageset/icons8-phone-100.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_contactno.imageset/icons8-phone-100@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_contactno.imageset/icons8-phone-100@2x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_contactno.imageset/icons8-phone-100@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_contactno.imageset/icons8-phone-100@3x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_dob.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icons8-birth-date-100.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "icons8-birth-date-100@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "icons8-birth-date-100@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_dob.imageset/icons8-birth-date-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_dob.imageset/icons8-birth-date-100.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_dob.imageset/icons8-birth-date-100@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_dob.imageset/icons8-birth-date-100@2x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_dob.imageset/icons8-birth-date-100@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_dob.imageset/icons8-birth-date-100@3x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_drop_down.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ic_drop_down.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "ic_drop_down@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "ic_drop_down@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_drop_down.imageset/ic_drop_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_drop_down.imageset/ic_drop_down.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_drop_down.imageset/ic_drop_down@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_drop_down.imageset/ic_drop_down@2x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_drop_down.imageset/ic_drop_down@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_drop_down.imageset/ic_drop_down@3x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_email.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icons8-important-mail-96.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "icons8-important-mail-96@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "icons8-important-mail-96@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_email.imageset/icons8-important-mail-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_email.imageset/icons8-important-mail-96.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_email.imageset/icons8-important-mail-96@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_email.imageset/icons8-important-mail-96@2x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_email.imageset/icons8-important-mail-96@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_email.imageset/icons8-important-mail-96@3x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_password.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icons8-password-1-90.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "icons8-password-1-90@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "icons8-password-1-90@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_password.imageset/icons8-password-1-90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_password.imageset/icons8-password-1-90.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_password.imageset/icons8-password-1-90@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_password.imageset/icons8-password-1-90@2x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_password.imageset/icons8-password-1-90@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_password.imageset/icons8-password-1-90@3x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_user.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ic_user.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "ic_user@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "ic_user@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_user.imageset/ic_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_user.imageset/ic_user.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_user.imageset/ic_user@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_user.imageset/ic_user@2x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/LRF/ic_user.imageset/ic_user@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/LRF/ic_user.imageset/ic_user@3x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Onboarding/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Onboarding/First.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "onboard1.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Onboarding/First.imageset/onboard1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/Onboarding/First.imageset/onboard1.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Onboarding/Second.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "Ios-13.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Onboarding/Second.imageset/Ios-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/Onboarding/Second.imageset/Ios-13.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Onboarding/Third.imageset/14.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/Onboarding/Third.imageset/14.jpeg -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Onboarding/Third.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "14.jpeg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/SwiftUILogo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "SwiftUiLogo.jpeg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/SwiftUILogo.imageset/SwiftUiLogo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/SwiftUILogo.imageset/SwiftUiLogo.jpeg -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Tabbar/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Tabbar/ic_controls.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "controls.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "controls@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "controls@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Tabbar/ic_controls.imageset/controls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/Tabbar/ic_controls.imageset/controls.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Tabbar/ic_controls.imageset/controls@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/Tabbar/ic_controls.imageset/controls@2x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Tabbar/ic_controls.imageset/controls@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/Tabbar/ic_controls.imageset/controls@3x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Tabbar/ic_favourite_tabbar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ic_favourite.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "ic_favourite@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "ic_favourite@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Tabbar/ic_favourite_tabbar.imageset/ic_favourite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/Tabbar/ic_favourite_tabbar.imageset/ic_favourite.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Tabbar/ic_favourite_tabbar.imageset/ic_favourite@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/Tabbar/ic_favourite_tabbar.imageset/ic_favourite@2x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Tabbar/ic_favourite_tabbar.imageset/ic_favourite@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/Tabbar/ic_favourite_tabbar.imageset/ic_favourite@3x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Tabbar/ic_home.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ic_home.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "ic_home@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "ic_home@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Tabbar/ic_home.imageset/ic_home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/Tabbar/ic_home.imageset/ic_home.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Tabbar/ic_home.imageset/ic_home@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/Tabbar/ic_home.imageset/ic_home@2x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/Tabbar/ic_home.imageset/ic_home@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/Tabbar/ic_home.imageset/ic_home@3x.png -------------------------------------------------------------------------------- /Demo/Assets.xcassets/birds/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/birds/bird.imageset/2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/birds/bird.imageset/2.jpeg -------------------------------------------------------------------------------- /Demo/Assets.xcassets/birds/bird.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "2.jpeg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/birds/pink-birds.imageset/3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/birds/pink-birds.imageset/3.jpeg -------------------------------------------------------------------------------- /Demo/Assets.xcassets/birds/pink-birds.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "3.jpeg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/birds/prrotes.imageset/6.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/birds/prrotes.imageset/6.jpeg -------------------------------------------------------------------------------- /Demo/Assets.xcassets/birds/prrotes.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "6.jpeg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/birds/sparrows.imageset/5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/birds/sparrows.imageset/5.jpeg -------------------------------------------------------------------------------- /Demo/Assets.xcassets/birds/sparrows.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "5.jpeg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/birds/white-bird.imageset/1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/birds/white-bird.imageset/1.jpeg -------------------------------------------------------------------------------- /Demo/Assets.xcassets/birds/white-bird.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "1.jpeg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/birds/white-ducks.imageset/4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/birds/white-ducks.imageset/4.jpeg -------------------------------------------------------------------------------- /Demo/Assets.xcassets/birds/white-ducks.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "4.jpeg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "logo.jpeg", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/logo.imageset/logo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/logo.imageset/logo.jpeg -------------------------------------------------------------------------------- /Demo/Assets.xcassets/simpleLifeCycle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "simpleLifeCycle.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Demo/Assets.xcassets/simpleLifeCycle.imageset/simpleLifeCycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Demo/Assets.xcassets/simpleLifeCycle.imageset/simpleLifeCycle.png -------------------------------------------------------------------------------- /Demo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Demo/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // Demo 4 | // 5 | // Created by mac-00018 on 21/10/19. 6 | // Copyright © 2019 mac-00018. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | //MARK:- 12 | //MARK:- Color 13 | 14 | let lightGreyColor = Color(red: 239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0, opacity: 1.0) 15 | let lightGreenColor = Color(red: 21.0/255.0, green: 183.0/255.0, blue: 177.0/255.0, opacity: 1.0) 16 | let lightblueColor = Color(red: 85.0/255.0, green: 84.0/255.0, blue: 166.0/255.0, opacity: 1.0) 17 | struct ContentView: View { 18 | @State var alertMsg = "" 19 | 20 | var alert: Alert { 21 | Alert(title: Text(""), message: Text(alertMsg), dismissButton: .default(Text("OK"))) 22 | } 23 | 24 | var body: some View { 25 | Text("Hello") 26 | } 27 | } 28 | 29 | struct NavigationConfigurator: UIViewControllerRepresentable { 30 | 31 | var configure: (UINavigationController) -> Void = { _ in } 32 | 33 | func makeUIViewController(context: Context) -> UIViewController { 34 | 35 | UIViewController() 36 | } 37 | 38 | func updateUIViewController(_ uiViewController: UIViewController, context: Context) { 39 | 40 | if let nc = uiViewController.navigationController { 41 | self.configure(nc) 42 | } 43 | } 44 | } 45 | 46 | //MARK:- 47 | //MARK:- Rounded Image 48 | struct RoundedImage: View { 49 | 50 | var body: some View { 51 | 52 | Image("logo") 53 | .resizable() 54 | .aspectRatio(contentMode: .fill) 55 | .frame(width: 150, height: 150) 56 | .clipped() 57 | .cornerRadius(150) 58 | .padding(.bottom, 40) 59 | 60 | } 61 | 62 | } 63 | 64 | //MARK:- 65 | //MARK:- Textfields 66 | struct textFieldWithSeperator: View { 67 | 68 | var placeholder: String 69 | var image: String 70 | // var text : String 71 | 72 | @State var username: String = "" 73 | @State var name = "" 74 | @Environment(\.editMode) var mode 75 | 76 | var body: some View { 77 | 78 | VStack { 79 | 80 | HStack { 81 | Image(image) 82 | .padding(.leading, 20) 83 | 84 | TextField(placeholder, text: $username) 85 | .frame(height: 40, alignment: .center) 86 | .padding(.leading, 10) 87 | .padding(.trailing, 10) 88 | .font(.system(size: 15, weight: .regular, design: .default)) 89 | .imageScale(.small) 90 | // .disabled(mode?.wrappedValue == .inactive) 91 | // .textFieldStyle(RoundedBorderTextFieldStyle()) 92 | 93 | } 94 | seperator() 95 | } 96 | 97 | } 98 | } 99 | 100 | 101 | 102 | //MARK:- 103 | //MARK:- Seperator (Bottom line view) 104 | struct seperator: View { 105 | 106 | var body: some View { 107 | 108 | VStack { 109 | 110 | Divider().background(lightGreyColor) 111 | 112 | }.padding() 113 | .frame(height: 1, alignment: .center) 114 | } 115 | } 116 | 117 | struct buttons: View { 118 | 119 | var btnText: String 120 | 121 | var body: some View { 122 | 123 | Text(btnText) 124 | .font(.body) 125 | .foregroundColor(.black) 126 | // .frame(width: 150, height: 40) 127 | .padding() 128 | } 129 | } 130 | 131 | //MARK:- 132 | //MARK:- Button with background & shaadow 133 | struct buttonWithBackground: View { 134 | 135 | var btnText: String 136 | 137 | var body: some View { 138 | 139 | HStack { 140 | // Spacer() 141 | Text(btnText) 142 | .font(.headline) 143 | .foregroundColor(.white) 144 | .padding() 145 | .frame(width: 140, height: 50) 146 | .background(lightblueColor) 147 | .clipped() 148 | .cornerRadius(5.0) 149 | .shadow(color: lightblueColor, radius: 5, x: 0, y: 5) 150 | 151 | // Spacer() 152 | } 153 | } 154 | } 155 | 156 | 157 | //MARK:- 158 | //MARK:- Alert View 159 | struct alertView: View { 160 | 161 | 162 | @State var alertMsg = "" 163 | 164 | var alert: Alert { 165 | Alert(title: Text(""), message: Text(alertMsg), dismissButton: .default(Text("OK"))) 166 | } 167 | 168 | var body: some View { 169 | Text("Alert") 170 | } 171 | 172 | } 173 | 174 | //MARK: - Date Picker View 175 | struct DatePickerView: View { 176 | 177 | var dateFormatter: DateFormatter { 178 | let formatter = DateFormatter() 179 | formatter.dateStyle = .long 180 | return formatter 181 | } 182 | 183 | @State private var birthDate = Date() 184 | 185 | var body: some View { 186 | 187 | VStack { 188 | DatePicker(selection: $birthDate, in: ...Date(), displayedComponents: .date) { 189 | Text("Select a date") 190 | } 191 | 192 | Text("Date is \(birthDate, formatter: dateFormatter)") 193 | } 194 | 195 | } 196 | } 197 | 198 | struct ContentView_Previews: PreviewProvider { 199 | static var previews: some View { 200 | ContentView() 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /Demo/DataStore.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DataStore.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 17/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | import Combine 11 | 12 | final class DataStore: ObservableObject { 13 | 14 | let didChange = PassthroughSubject() 15 | 16 | @Published var login: Bool = false 17 | 18 | @UserDefault(key: "loggedIn", defaultValue: false) 19 | var loggedIn: Bool { 20 | didSet { 21 | didChange.send(self) 22 | self.login = self.loggedIn 23 | } 24 | } 25 | } 26 | 27 | 28 | final class DataOnboarding: ObservableObject { 29 | 30 | let didChange = PassthroughSubject() 31 | 32 | @Published var onboard: Bool = false 33 | 34 | @UserDefault(key: "onboardComlete", defaultValue: false) 35 | var onboardComlete: Bool { 36 | didSet { 37 | didChange.send(self) 38 | self.onboard = self.onboardComlete 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Demo/Details/MView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MAPView.swift 3 | // DemoSwiftUI 4 | // 5 | // Created by mac-00018 on 11/10/19. 6 | // Copyright © 2019 mac-00018. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | import CoreLocation 11 | 12 | struct Landmark: Equatable { 13 | static func ==(lhs: Landmark, rhs: Landmark ) -> Bool { 14 | lhs.id == rhs.id 15 | } 16 | 17 | let id = UUID().uuidString 18 | let name: String 19 | let location: CLLocationCoordinate2D 20 | } 21 | 22 | struct MView: View { 23 | @State var landmarks: [Landmark] = [ 24 | Landmark(name: "Sydney Harbour Bridge", location: .init(latitude: -33.852222, longitude: 151.210556)), 25 | Landmark(name: "Brooklyn Bridge", location: .init(latitude: 40.706, longitude: -73.997)), 26 | Landmark(name: "Golden Gate Bridge", location: .init(latitude: 37.819722, longitude: -122.478611)) 27 | ] 28 | 29 | @State var selectedLandmark: Landmark? = nil 30 | 31 | var body: some View { 32 | ZStack { 33 | // MapView(landmarks: $landmarks, 34 | // selectedLandmark: $selectedLandmark) 35 | // .edgesIgnoringSafeArea(.vertical) 36 | VStack { 37 | Spacer() 38 | Button(action: { 39 | self.selectNextLandmark() 40 | }) { 41 | Text("Next") 42 | .foregroundColor(.black) 43 | .padding() 44 | .background(Color.white) 45 | .cornerRadius(8) 46 | .shadow(radius: 3) 47 | .padding(.bottom) 48 | } 49 | } 50 | } 51 | } 52 | 53 | private func selectNextLandmark() { 54 | if let selectedLandmark = selectedLandmark, let currentIndex = landmarks.firstIndex(where: { $0 == selectedLandmark }), currentIndex + 1 < landmarks.endIndex { 55 | self.selectedLandmark = landmarks[currentIndex + 1] 56 | } else { 57 | selectedLandmark = landmarks.first 58 | } 59 | } 60 | } 61 | 62 | struct MView_Previews: PreviewProvider { 63 | static var previews: some View { 64 | MView() 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Demo/Details/PickerView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PickerView.swift 3 | // SwiftUIDemo 4 | // 5 | // Created by mac-00018 on 13/09/19. 6 | // Copyright © 2019 mac-00018. All rights reserved. 7 | // 8 | import SwiftUI 9 | 10 | struct PickerView: View { 11 | 12 | var strengths = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"] 13 | 14 | @State private var selectedStrength = 0 15 | @State var minimumSelectedDate = Date() 16 | @State var maximumSelectedDate = Date() 17 | @State var testDate = Date() 18 | 19 | var body: some View { 20 | 21 | NavigationView { 22 | 23 | Form { 24 | Section { 25 | Picker(selection: $selectedStrength, label: Text("Strength")) { 26 | ForEach(0 ..< strengths.count) { 27 | Text(self.strengths[$0]) 28 | 29 | } 30 | } 31 | } 32 | 33 | // for minimum date 34 | DatePicker("Minimum Date", 35 | selection: $minimumSelectedDate, 36 | in: Date()..., 37 | displayedComponents: [.date]) 38 | 39 | // for maximum date 40 | DatePicker("Maximum Date", 41 | selection: $maximumSelectedDate, 42 | in: ...Date(), 43 | displayedComponents: [.date]) 44 | 45 | // for select date 46 | DatePicker("Test Date", 47 | selection: $testDate, 48 | displayedComponents: [.date]) 49 | 50 | 51 | }.navigationBarTitle("Select Number") 52 | 53 | 54 | } 55 | 56 | } 57 | 58 | } 59 | 60 | 61 | #if DEBUG 62 | struct PickerView_Previews: PreviewProvider { 63 | static var previews: some View { 64 | PickerView() 65 | } 66 | } 67 | #endif 68 | -------------------------------------------------------------------------------- /Demo/Details/SegmentcontrolView.swift: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // SegmentcontrolView.swift 4 | // SwiftUIDemo 5 | // 6 | // Created by mac-00018 on 13/09/19. 7 | // Copyright © 2019 mac-00018. All rights reserved. 8 | // 9 | 10 | import SwiftUI 11 | 12 | struct SegmentcontrolView: View { 13 | 14 | @State private var selectorIndex = 0 15 | @State private var numbers = ["One","Two","Three"] 16 | 17 | 18 | @State private var birds = ["Peacock", "Sparrow", "Duck", "Crows", "Pigeons", "Dove"] 19 | @State private var selectedBird = 0 20 | 21 | 22 | var body: some View { 23 | VStack { 24 | // 2 25 | Picker("Numbers", selection: $selectorIndex) { 26 | ForEach(0 ..< numbers.count) { index in 27 | Text(self.numbers[index]).tag(index) 28 | } 29 | }.pickerStyle(SegmentedPickerStyle()) 30 | 31 | // 3. 32 | Text("Selected value is: \(numbers[selectorIndex])").padding() 33 | 34 | 35 | Picker("Your Fav Bird", selection: $selectedBird) { 36 | ForEach(0 ..< birds.count) { birdsName in 37 | Text(self.birds[birdsName]).tag(birdsName) 38 | 39 | } 40 | }.pickerStyle(SegmentedPickerStyle()) 41 | 42 | Text("Your Fav. Bird name is: \(birds[selectedBird])").padding() 43 | }.padding() 44 | } 45 | } 46 | 47 | struct MaterialSegmentControl : View { 48 | @State private var MaterialType = 0 49 | 50 | var body: some View { 51 | 52 | NavigationView { 53 | 54 | VStack { 55 | // SegmentedControl(selection: $MaterialType) { 56 | // Text("Style").tag(0) 57 | // Text("Text").tag(1) 58 | // Text("Arrange").tag(2) 59 | // } 60 | 61 | if MaterialType == 0 { 62 | List { 63 | Text("Hi") 64 | Text("\(MaterialType)") 65 | } 66 | } else if MaterialType == 1 { 67 | List { 68 | Text("Beep") 69 | Text("\(MaterialType)") 70 | } 71 | } else { 72 | List { 73 | Text("Boop") 74 | Text("\(MaterialType)") 75 | } 76 | } 77 | } 78 | } 79 | } 80 | } 81 | 82 | #if DEBUG 83 | struct SegmentcontrolView_Previews: PreviewProvider { 84 | static var previews: some View { 85 | SegmentcontrolView() 86 | } 87 | } 88 | #endif 89 | -------------------------------------------------------------------------------- /Demo/Details/TextView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextView.swift 3 | // SwiftUIDemo 4 | // 5 | // Created by mac-00018 on 16/09/19. 6 | // Copyright © 2019 mac-00018. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct TextView: View { 12 | @State private var slider: Float = 100.0 13 | 14 | var body: some View { 15 | 16 | VStack { 17 | 18 | // VStack { 19 | // GeometryReader { geometry in 20 | // HStack(alignment: .center, spacing: 0) { 21 | // ForEach(0..<7) { _ in 22 | // Text("Mon").frame(width: geometry.size.width / 7, height: 30).border(Color.blue) 23 | // } 24 | // } 25 | // }.frame(width: CGFloat(slider), height: 40) 26 | // Text("\(slider)") 27 | // Slider(value: self.$slider, from: 100.0, through: 400.0, by: 1.0) 28 | //// Slider(value: self.$slider, in: 100.0, step: 1.0, onEditingChanged: true) 29 | // Spacer() 30 | // } 31 | 32 | ScrollView { 33 | VStack { 34 | Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") 35 | .fixedSize(horizontal: false, vertical: true) 36 | } 37 | } 38 | 39 | Text("Hello World!") 40 | .fixedSize(horizontal: false, vertical: true) 41 | 42 | Text ("Dynamic Text") 43 | .font(.largeTitle) 44 | .fontWeight(.bold) 45 | Text ("Hello!!, How are you?") 46 | .kerning(10) 47 | 48 | Text ("Text for Color Expample") 49 | .foregroundColor(.white) 50 | .background(Color.black) 51 | 52 | Text("Text Style") 53 | .bold() 54 | .italic() 55 | 56 | Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") 57 | // .lineLimit(2) 58 | .lineLimit(nil) 59 | .lineSpacing(10) 60 | .multilineTextAlignment(.center) 61 | 62 | 63 | 64 | } 65 | } 66 | } 67 | 68 | #if DEBUG 69 | struct TextView_Previews: PreviewProvider { 70 | static var previews: some View { 71 | TextView() 72 | } 73 | } 74 | #endif 75 | -------------------------------------------------------------------------------- /Demo/Home/Collection/CollectionUI.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionUI.swift 3 | // CollectionViewSwiftUI 4 | // 5 | // Created by mac-00013 on 05/10/19. 6 | // Copyright © 2019 swift. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct CollectionUI: UIViewRepresentable { 12 | 13 | var arrData: Binding<[String]> 14 | 15 | func makeCoordinator() -> CollectionUI.Coordinator { 16 | Coordinator(data: []) 17 | } 18 | 19 | class Coordinator: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { 20 | var data: [String] = [] 21 | 22 | init(data: [String]) { 23 | 24 | for index in (0...10) { 25 | self.data.append("\(index)") 26 | } 27 | } 28 | 29 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 30 | 10 31 | } 32 | 33 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 34 | 35 | if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as? CustomCell { 36 | cell.lblNum.text = "\(indexPath.item)" 37 | return cell 38 | } 39 | 40 | return UICollectionViewCell() 41 | } 42 | 43 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 44 | CGSize(width: collectionView.frame.width / 3 , height: collectionView.frame.width / 3) 45 | } 46 | 47 | // func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 48 | // switch indexPath.row { 49 | // case 0: 50 | // 51 | // NavigationLink(destination: SegmentcontrolView()) { 52 | // SegmentcontrolView() 53 | // } 54 | // break 55 | // 56 | // case 1: 57 | // NavigationLink(destination: LoginView()) { 58 | // LoginView() 59 | // } 60 | // break 61 | // 62 | // default: break 63 | // 64 | // } 65 | // } 66 | 67 | } 68 | 69 | // func makeUIViewController(context: UIViewControllerRepresentableContext) -> UICollectionView { 70 | // let layout = UICollectionViewFlowLayout() 71 | // layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize 72 | // layout.scrollDirection = .vertical 73 | // let cv = UICollectionView(frame: .zero, collectionViewLayout: layout) 74 | // cv.dataSource = context.coordinator 75 | // cv.delegate = context.coordinator 76 | // cv.register(GenericCell.self, forCellWithReuseIdentifier: "cell") 77 | // 78 | // cv.backgroundColor = .white 79 | // layout.minimumInteritemSpacing = 0 80 | // layout.minimumLineSpacing = 0 81 | // return cv 82 | // } 83 | 84 | func makeUIView(context: Context) -> UICollectionView { 85 | 86 | let layout = UICollectionViewFlowLayout() 87 | layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize 88 | layout.scrollDirection = .vertical 89 | let cv = UICollectionView(frame: .zero, collectionViewLayout: layout) 90 | cv.dataSource = context.coordinator 91 | cv.delegate = context.coordinator 92 | 93 | cv.register(UINib(nibName: "CustomCell", bundle: nil), forCellWithReuseIdentifier: "CustomCell") 94 | 95 | cv.backgroundColor = .white 96 | layout.minimumInteritemSpacing = 0 97 | layout.minimumLineSpacing = 0 98 | return cv 99 | } 100 | 101 | 102 | func updateUIView(_ uiView: UICollectionView, context: Context) { 103 | 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /Demo/Home/Collection/CollectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionView.swift 3 | // DemoSwiftUI 4 | // 5 | // Created by mac-00018 on 11/10/19. 6 | // Copyright © 2019 mac-00018. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct CollectionView: View { 12 | 13 | @State var arrData: [String] = [] 14 | @State var isOpen: Bool = false 15 | 16 | var body: some View { 17 | 18 | CollectionUI(arrData: self.$arrData) 19 | .edgesIgnoringSafeArea(.all) 20 | 21 | } 22 | 23 | func openMenu() { 24 | self.isOpen.toggle() 25 | } 26 | 27 | } 28 | 29 | struct CollectionView_Previews: PreviewProvider { 30 | static var previews: some View { 31 | CollectionView() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Demo/Home/Collection/CustomCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomCell.swift 3 | // CollectionViewSwiftUI 4 | // 5 | // Created by mac-00013 on 05/10/19. 6 | // Copyright © 2019 swift. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CustomCell: UICollectionViewCell { 12 | 13 | @IBOutlet weak var lblNum: UILabel! 14 | 15 | override func awakeFromNib() { 16 | super.awakeFromNib() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Demo/Home/Collection/CustomCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Demo/Home/GridCollection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GridCollection.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 19/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | 12 | /// A container that presents rows of data arranged in multiple columns. 13 | @available(iOS 13.0, OSX 10.15, *) 14 | public struct GridCollection: View 15 | where Data : RandomAccessCollection, Content : View, Data.Element : Identifiable { 16 | private struct GridCollectionIndex : Identifiable { var id: Int } 17 | 18 | // MARK: - STORED PROPERTIES 19 | 20 | private let columns: Int 21 | private let columnsInLandscape: Int 22 | private let vSpacing: CGFloat 23 | private let hSpacing: CGFloat 24 | private let vPadding: CGFloat 25 | private let hPadding: CGFloat 26 | 27 | private let data: [Data.Element] 28 | private let content: (Data.Element) -> Content 29 | 30 | // MARK: - INITIALIZERS 31 | 32 | /// Creates a GridCollection that computes its cells on demand from an underlying 33 | /// collection of identified data. 34 | /// 35 | /// - Parameters: 36 | /// - data: A collection of identified data. 37 | /// - columns: Target number of columns for this grid, in Portrait device orientation 38 | /// - columnsInLandscape: Target number of columns for this grid, in Landscape device orientation; If not provided, `columns` value will be used. 39 | /// - vSpacing: Vertical spacing: The distance between each row in grid. If not provided, the default value will be used. 40 | /// - hSpacing: Horizontal spacing: The distance between each cell in grid's row. If not provided, the default value will be used. 41 | /// - vPadding: Vertical padding: The distance between top/bottom edge of the grid and the parent view. If not provided, the default value will be used. 42 | /// - hPadding: Horizontal padding: The distance between leading/trailing edge of the grid and the parent view. If not provided, the default value will be used. 43 | /// - content: A closure returning the content of the individual cell 44 | public init(_ data: Data, 45 | columns: Int, 46 | columnsInLandscape: Int? = nil, 47 | vSpacing: CGFloat = 10, 48 | hSpacing: CGFloat = 10, 49 | vPadding: CGFloat = 10, 50 | hPadding: CGFloat = 10, 51 | content: @escaping (Data.Element) -> Content) { 52 | self.data = data.map { $0 } 53 | self.content = content 54 | self.columns = max(1, columns) 55 | self.columnsInLandscape = columnsInLandscape ?? max(1, columns) 56 | self.vSpacing = vSpacing 57 | self.hSpacing = hSpacing 58 | self.vPadding = vPadding 59 | self.hPadding = hPadding 60 | } 61 | 62 | // MARK: - COMPUTED PROPERTIES 63 | 64 | private var rows: Int { 65 | data.count / self.cols 66 | } 67 | 68 | private var cols: Int { 69 | #if os(tvOS) 70 | return columnsInLandscape 71 | #else 72 | return UIDevice.current.orientation.isLandscape ? columnsInLandscape : columns 73 | #endif 74 | } 75 | 76 | /// Declares the content and behavior of this view. 77 | public var body : some View { 78 | 79 | GeometryReader { geometry in 80 | 81 | ScrollView(showsIndicators: false) { 82 | 83 | VStack(spacing: self.vSpacing) { 84 | 85 | ForEach((0.. 0) { 92 | self.rowAtIndex(self.cols * self.rows, 93 | geometry: geometry, 94 | isLastRow: true) 95 | } 96 | } 97 | } 98 | .padding(.horizontal, self.hPadding) 99 | .padding(.vertical, self.vPadding) 100 | } 101 | } 102 | 103 | // MARK: - Row at Index FUNCTIONS 104 | 105 | private func rowAtIndex(_ index: Int, 106 | geometry: GeometryProxy, 107 | isLastRow: Bool = false) -> some View { 108 | 109 | HStack(spacing: self.hSpacing) { 110 | 111 | ForEach((0..<(isLastRow ? data.count % cols : cols)) 112 | .map { GridCollectionIndex(id: $0) }) { column in 113 | self.content(self.data[index + column.id]) 114 | .frame(width: self.contentWidthFor(geometry)) 115 | } 116 | 117 | if isLastRow { Spacer() } 118 | } 119 | } 120 | 121 | // MARK: - HELPER FUNCTIONS 122 | 123 | private func contentWidthFor(_ geometry: GeometryProxy) -> CGFloat { 124 | 125 | let hSpacings = hSpacing * (CGFloat(self.cols) - 1) 126 | let width = geometry.size.width - hSpacings - hPadding * 2 127 | return width / CGFloat(self.cols) 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /Demo/Home/HeaderCollVCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HeaderCollVCell.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 18/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct HeaderCollVCell: View { 12 | 13 | var image : String 14 | 15 | var body: some View { 16 | 17 | Image(image) 18 | .resizable() 19 | .aspectRatio(contentMode: .fill) 20 | .frame(width: (UIScreen.main.bounds.width * 380) / 414, height: (UIScreen.main.bounds.width * 210) / 414) 21 | .cornerRadius(10) 22 | } 23 | } 24 | 25 | struct HeaderCollVCell_Previews: PreviewProvider { 26 | static var previews: some View { 27 | HeaderCollVCell(image: "") 28 | .previewLayout(.fixed(width: (UIScreen.main.bounds.width * 384) / 414, height: (UIScreen.main.bounds.width * 210) / 414)) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Demo/Home/HeaderCollView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HeaderCollView.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 18/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct HeaderCollView: View { 12 | 13 | @State var currentPageIndex: Int = 0 14 | 15 | var body: some View { 16 | 17 | VStack { 18 | 19 | ScrollView(.horizontal, showsIndicators: false) { 20 | 21 | HStack { 22 | 23 | ForEach((1...10).reversed(), id: \.self) { _ in 24 | HeaderCollVCell(image: "") 25 | .padding([.trailing]) 26 | } 27 | } 28 | } 29 | 30 | PageControl(numberOfPages: 10, currentPageIndex: $currentPageIndex) 31 | } 32 | } 33 | } 34 | 35 | struct HeaderCollView_Previews: PreviewProvider { 36 | static var previews: some View { 37 | HeaderCollView() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Demo/Home/HomeVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeVC.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 16/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct Product : Identifiable { 12 | var id = UUID() 13 | var name: String 14 | var imageName: String 15 | } 16 | 17 | let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first 18 | let statusbarHeight = window?.windowScene?.statusBarManager?.statusBarFrame.size.height ?? 0 19 | 20 | struct HomeVC: View { 21 | 22 | init() { 23 | UITableView.appearance().backgroundColor = .clear 24 | UITableViewCell.appearance().backgroundColor = .clear 25 | } 26 | 27 | let arrProduct = [ 28 | Product(name: "First Product", imageName: "prrotes"), 29 | Product(name: "Second Product", imageName: "pink-birds"), 30 | Product(name: "Third Product", imageName: "sparrows"), 31 | Product(name: "Fourth Product", imageName: "white-bird"), 32 | Product(name: "Fifth Product", imageName: "white-ducks"), 33 | Product(name: "Sixth Product", imageName: "bird"), 34 | Product(name: "Seventh Product", imageName: "prrotes"), 35 | Product(name: "Eight Product", imageName: "prrotes"), 36 | Product(name: "Nineth Product", imageName: "bird") 37 | ] 38 | 39 | var body: some View { 40 | 41 | List { 42 | 43 | // HeaderCollView() 44 | TopView() 45 | 46 | VStack(alignment: .leading) { 47 | Group { 48 | Text("Shop by Category") 49 | 50 | ProductTypeCollView() 51 | } 52 | } 53 | 54 | ProductListCollView(arrProduct: arrProduct) 55 | .frame(height: ((((UIScreen.main.bounds.width * 210) / 414) * (CGFloat(self.arrProduct.count % 2 == 0 ? Int(self.arrProduct.count / 2) : Int(self.arrProduct.count / 2) + 1))) + CGFloat(Int(self.arrProduct.count / 2) * 20))) 56 | } 57 | .edgesIgnoringSafeArea(.top) 58 | .listStyle(GroupedListStyle()) 59 | } 60 | } 61 | 62 | struct HomeVC_Previews: PreviewProvider { 63 | static var previews: some View { 64 | HomeVC() 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Demo/Home/List/ListView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ListView.swift 3 | // DemoSwiftUI 4 | // 5 | // Created by mac-00018 on 11/10/19. 6 | // Copyright © 2019 mac-00018. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct ListData { 12 | var title: String = "" 13 | } 14 | 15 | //MARK:- 16 | //MARK:- List Data 17 | struct ListView: View { 18 | 19 | var data = [ 20 | ListData(title: "Segment Control"), 21 | ListData(title: "Combine Framework Demo"), 22 | ListData(title: "Picker"), 23 | ] 24 | @EnvironmentObject var settings: UserSettings 25 | 26 | var body: some View { 27 | 28 | VStack { 29 | 30 | List { 31 | 32 | ForEach(data, id:\.title) { list in 33 | NavigationLink(destination: RedirectionFromList(data: list)) { 34 | RowData(list: list) 35 | } 36 | } 37 | } 38 | .padding(.top) 39 | .listStyle(GroupedListStyle()) 40 | 41 | 42 | Button(action: { 43 | // For use with property wrapper 44 | UserDefaults.standard.set(false, forKey: "Loggedin") 45 | UserDefaults.standard.synchronize() 46 | self.settings.loggedIn = false 47 | // ========== 48 | 49 | // For use with property wrapper 50 | // self.dataStore.loggedIn = false 51 | // ========== 52 | }) { 53 | buttonWithBackground(btnText: "LOGOUT") 54 | }.padding(.bottom) 55 | 56 | } 57 | } 58 | 59 | 60 | func adjustUITextViewHeight(arg : UIView) { 61 | arg.translatesAutoresizingMaskIntoConstraints = true 62 | arg.sizeToFit() 63 | // arg.isScrollEnabled = false 64 | } 65 | 66 | } 67 | 68 | 69 | //MARK:- 70 | //MARK:- List Row Data 71 | struct RowData: View { 72 | 73 | var list: ListData 74 | 75 | var body: some View { 76 | 77 | VStack(alignment: .leading) { 78 | 79 | HStack(alignment: .top) { 80 | 81 | VStack(alignment: .leading) { 82 | 83 | Text(list.title) 84 | .font(.system(Font.TextStyle.body, design: Font.Design.monospaced)) 85 | .foregroundColor(Color.blue) 86 | 87 | VStack { 88 | DetailsView(listdata: list) 89 | } 90 | } 91 | } 92 | } 93 | } 94 | } 95 | 96 | //MARK:- 97 | //AMRK:- Detail View 98 | struct DetailsView: View { 99 | var listdata: ListData 100 | var uiControls: [Any] = [LoginView(), ForgotPasswordView()] 101 | 102 | var body: some View { 103 | VStack { 104 | // Text(listdata.title) 105 | // .font(.title) 106 | 107 | ForEach(0.. AnyView { 116 | switch types[index].self { 117 | case is LoginView.Type: return AnyView( LoginView() ) 118 | case is ForgotPasswordView.Type: return AnyView( ForgotPasswordView() ) 119 | default: return AnyView(EmptyView()) 120 | } 121 | } 122 | } 123 | 124 | struct RedirectionFromList: View { 125 | 126 | var data: ListData 127 | 128 | var body: some View { 129 | switch data.title { 130 | case "Segment Control": 131 | return AnyView(SegmentcontrolView()) 132 | case "Combine Framework Demo": 133 | return AnyView(SignupVC()) 134 | case "Picker": 135 | return AnyView(PickerView()) 136 | default: 137 | return AnyView(SegmentcontrolView()) 138 | } 139 | } 140 | } 141 | 142 | struct ListView_Previews: PreviewProvider { 143 | static var previews: some View { 144 | ListView() 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /Demo/Home/ProductListCollVCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductListCollVCell.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 19/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct ProductListCollVCell: View { 12 | 13 | var product: Product 14 | 15 | var body: some View { 16 | 17 | NavigationLink(destination: ProductListRedirection(product: product)) { 18 | 19 | VStack { 20 | 21 | Image(product.imageName) 22 | .resizable() 23 | .frame(width: (UIScreen.main.bounds.width * 190) / 414, height: (UIScreen.main.bounds.width * 134) / 414) 24 | .aspectRatio(contentMode: .fill) 25 | 26 | Text("Color Birds") 27 | .lineLimit(2) 28 | .padding([.leading, .trailing], 5) 29 | .foregroundColor(Color("TextColor")) 30 | 31 | 32 | Spacer() 33 | } 34 | // .background(Color.white) 35 | .border(Color.gray) 36 | .cornerRadius(10) 37 | .shadow(radius: 2) 38 | } 39 | .buttonStyle(PlainButtonStyle()) 40 | } 41 | } 42 | 43 | struct ProductListCollVCell_Previews: PreviewProvider { 44 | static var previews: some View { 45 | ProductListCollVCell(product: Product(name: "First Product", imageName: "bird")) 46 | .previewLayout(.fixed(width: (UIScreen.main.bounds.width * 200) / 414, height: (UIScreen.main.bounds.width * 200) / 414)) 47 | } 48 | } 49 | 50 | struct ProductListRedirection: View { 51 | 52 | var product: Product 53 | 54 | var body: some View { 55 | 56 | switch product.name { 57 | case "First Product": 58 | return AnyView(CurrentOrderVC()) 59 | case "Second Product": 60 | return AnyView(NotificationVC()) 61 | case "Third Product": 62 | return AnyView(FavouritesVC()) 63 | default: 64 | return AnyView(Text(product.name)) 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Demo/Home/ProductListCollView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductListCollView.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 19/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct ProductListCollView: View { 12 | 13 | let arrProduct: [Product] 14 | 15 | var body: some View { 16 | 17 | GridCollection(arrProduct, columns: 2, vSpacing: 20, hSpacing: 10, vPadding: 0, hPadding: 0) { 18 | ProductListCollVCell(product: $0) 19 | } 20 | } 21 | } 22 | 23 | struct ProductListCollView_Previews: PreviewProvider { 24 | static var previews: some View { 25 | ProductListCollView(arrProduct: [Product(name: "First Product", imageName: "bird"), 26 | Product(name: "Second Product", imageName: "bird")]) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Demo/Home/ProductTypeCollVCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductTypeCollVCell.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 19/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct ProductTypeCollVCell: View { 12 | 13 | var body: some View { 14 | 15 | Image("bird") 16 | .resizable() 17 | .aspectRatio(contentMode: .fill) 18 | .frame(width: (UIScreen.main.bounds.width * 105) / 414, height: (UIScreen.main.bounds.width * 105) / 414) 19 | .cornerRadius(10) 20 | } 21 | } 22 | 23 | struct ProductTypeCollVCell_Previews: PreviewProvider { 24 | static var previews: some View { 25 | ProductTypeCollVCell() 26 | .previewLayout(.fixed(width: (UIScreen.main.bounds.width * 105) / 414, height: (UIScreen.main.bounds.width * 105) / 414)) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Demo/Home/ProductTypeCollView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProductTypeCollView.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 19/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct ProductTypeCollView: View { 12 | var body: some View { 13 | 14 | ScrollView(.horizontal, showsIndicators: false) { 15 | 16 | HStack { 17 | 18 | ForEach((1...10).reversed(), id: \.self) { _ in 19 | ProductTypeCollVCell() 20 | } 21 | } 22 | } 23 | } 24 | } 25 | 26 | struct ProductTypeCollView_Previews: PreviewProvider { 27 | static var previews: some View { 28 | ProductTypeCollView() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Demo/HomeTopPageControll/PageVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PageViewController.swift 3 | // App Onboarding 4 | // 5 | // Created by Andreas Schultz on 10.08.19. 6 | // Copyright © 2019 Andreas Schultz. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import SwiftUI 12 | 13 | struct PageVC: UIViewControllerRepresentable { 14 | 15 | @Binding var currentPageIndex: Int 16 | 17 | var viewControllers: [UIViewController] 18 | 19 | class Coordinator: NSObject, UIPageViewControllerDataSource, UIPageViewControllerDelegate { 20 | 21 | var parent: PageVC 22 | 23 | init(_ pageViewController: PageVC) { 24 | self.parent = pageViewController 25 | } 26 | 27 | func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { 28 | 29 | //retrieves the index of the currently displayed view controller 30 | guard let index = parent.viewControllers.firstIndex(of: viewController) else { 31 | return nil 32 | } 33 | 34 | //shows the last view controller when the user swipes back from the first view controller 35 | if index == 0 { 36 | return parent.viewControllers.last 37 | } 38 | 39 | //show the view controller before the currently displayed view controller 40 | return parent.viewControllers[index - 1] 41 | } 42 | 43 | func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { 44 | 45 | //retrieves the index of the currently displayed view controller 46 | guard let index = parent.viewControllers.firstIndex(of: viewController) else { 47 | return nil 48 | } 49 | 50 | //shows the first view controller when the user swipes further from the last view controller 51 | if index + 1 == parent.viewControllers.count { 52 | return parent.viewControllers.first 53 | } 54 | 55 | //show the view controller after the currently displayed view controller 56 | return parent.viewControllers[index + 1] 57 | } 58 | 59 | func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { 60 | 61 | if completed, let visibleViewController = pageViewController.viewControllers?.first, let index = parent.viewControllers.firstIndex(of: visibleViewController) { 62 | parent.currentPageIndex = index 63 | } 64 | } 65 | } 66 | 67 | func makeCoordinator() -> Coordinator { 68 | Coordinator(self) 69 | } 70 | 71 | func makeUIViewController(context: Context) -> UIPageViewController { 72 | 73 | let pageViewController = UIPageViewController( 74 | transitionStyle: .scroll, 75 | navigationOrientation: .horizontal 76 | ) 77 | 78 | pageViewController.dataSource = context.coordinator 79 | pageViewController.delegate = context.coordinator 80 | 81 | return pageViewController 82 | } 83 | 84 | func updateUIViewController(_ pageViewController: UIPageViewController, context: Context) { 85 | 86 | pageViewController.setViewControllers( 87 | [viewControllers[currentPageIndex]], 88 | direction: .forward, 89 | animated: true 90 | ) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Demo/HomeTopPageControll/TopView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingView.swift 3 | // App Onboarding 4 | // 5 | // Created by Andreas Schultz on 10.08.19. 6 | // Copyright © 2019 Andreas Schultz. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct TopView: View { 12 | 13 | var subview = [ 14 | UIHostingController(rootView: HeaderCollVCell(image: "sparrows")), 15 | UIHostingController(rootView: HeaderCollVCell(image: "pink-birds")), 16 | UIHostingController(rootView: HeaderCollVCell(image: "white-ducks")) 17 | ] 18 | 19 | @State var currentPage = 0 20 | 21 | var body: some View { 22 | 23 | VStack { 24 | 25 | PageVC(currentPageIndex: $currentPage,viewControllers: subview) 26 | .frame(height: (UIScreen.main.bounds.width * 250) / 414) 27 | 28 | PageControl(numberOfPages: subview.count, currentPageIndex: $currentPage) 29 | } 30 | } 31 | } 32 | 33 | #if DEBUG 34 | struct TopView_Previews: PreviewProvider { 35 | static var previews: some View { 36 | TopView() 37 | } 38 | } 39 | #endif 40 | -------------------------------------------------------------------------------- /Demo/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 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | 37 | 38 | 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UISupportedInterfaceOrientations 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UISupportedInterfaceOrientations~ipad 53 | 54 | UIInterfaceOrientationPortrait 55 | UIInterfaceOrientationPortraitUpsideDown 56 | UIInterfaceOrientationLandscapeLeft 57 | UIInterfaceOrientationLandscapeRight 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Demo/LRF/ForgotPasswordView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ForgotPasswordView.swift 3 | // DemoSwiftUI 4 | // 5 | // Created by mac-00018 on 10/10/19. 6 | // Copyright © 2019 mac-00018. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct ForgotPasswordView: View { 12 | 13 | @State var email: String = "" 14 | @State var showAlert = false 15 | @State var alertMsg = "" 16 | 17 | var alert: Alert { 18 | Alert(title: Text(""), message: Text(alertMsg), dismissButton: .default(Text("OK"))) 19 | } 20 | 21 | @Environment(\.presentationMode) var presentationMode: Binding 22 | 23 | var body: some View { 24 | 25 | NavigationView { 26 | 27 | ScrollView { 28 | 29 | VStack { 30 | 31 | Spacer(minLength: 80) 32 | 33 | Text("Write your email address in the text box and we will send you a verification code to reset your password.") 34 | .font(.body) 35 | .padding() 36 | .fixedSize(horizontal: false, vertical: true) 37 | .multilineTextAlignment(.center) 38 | 39 | VStack { 40 | 41 | HStack { 42 | Image("ic_email") 43 | .padding(.leading, 20) 44 | 45 | 46 | TextField("Email", text: $email) 47 | .frame(height: 40, alignment: .center) 48 | .padding(.leading, 10) 49 | .padding(.trailing, 10) 50 | .font(.system(size: 15, weight: .regular, design: .default)) 51 | .imageScale(.small) 52 | .keyboardType(.emailAddress) 53 | .autocapitalization(UITextAutocapitalizationType.none) 54 | } 55 | 56 | seperator() 57 | } 58 | 59 | Spacer(minLength: 20) 60 | 61 | Button(action: { 62 | 63 | if self.isValidInputs() { 64 | self.presentationMode.wrappedValue.dismiss() 65 | } 66 | 67 | }) { 68 | 69 | buttonWithBackground(btnText: "SUBMIT") 70 | } 71 | 72 | } 73 | } 74 | }.alert(isPresented: $showAlert, content: { self.alert }) 75 | } 76 | 77 | func isValidInputs() -> Bool { 78 | 79 | if self.email == "" { 80 | self.alertMsg = "Email can't be blank." 81 | self.showAlert.toggle() 82 | return false 83 | 84 | } else if !self.email.isValidEmail { 85 | self.alertMsg = "Email is not valid." 86 | self.showAlert.toggle() 87 | return false 88 | } 89 | 90 | return true 91 | } 92 | } 93 | 94 | struct ModalView: View { 95 | 96 | var body: some View { 97 | Group { 98 | Text("Modal view") 99 | 100 | } 101 | } 102 | } 103 | 104 | struct ForgotPasswordView_Previews: PreviewProvider { 105 | static var previews: some View { 106 | ForgotPasswordView() 107 | 108 | } 109 | } 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /Demo/Onboarding/OnboardingView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OnboardingView.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 18/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct OnboardingView: View { 12 | 13 | var subViews = [ 14 | UIHostingController(rootView: Subview(imageString: "First")), 15 | UIHostingController(rootView: Subview(imageString: "Second")), 16 | UIHostingController(rootView: Subview(imageString: "Third")) 17 | ] 18 | 19 | var titles = ["First", "Second", "Third"] 20 | 21 | var captions = ["This is first screen.", "This is second screen.", "This is third screen."] 22 | 23 | @State var currentPageIndex = 0 24 | @EnvironmentObject var dataOnboard: DataOnboarding 25 | @EnvironmentObject var userOnboard: UserOnboard 26 | 27 | var body: some View { 28 | 29 | VStack(alignment: .leading) { 30 | 31 | PageViewController(currentPageIndex: $currentPageIndex,viewControllers: subViews) 32 | .frame(height: (UIScreen.main.bounds.width * 500) / 414) 33 | 34 | Spacer() 35 | 36 | Group { 37 | 38 | Text(titles[currentPageIndex]) 39 | .font(.title) 40 | 41 | Text(captions[currentPageIndex]) 42 | .font(.subheadline) 43 | .foregroundColor(.gray) 44 | .frame(width: 300, height: 50, alignment: .leading) 45 | .lineLimit(nil) 46 | }.padding([.leading, .trailing]) 47 | 48 | HStack { 49 | 50 | PageControl(numberOfPages: subViews.count, currentPageIndex: $currentPageIndex) 51 | 52 | Spacer() 53 | 54 | Button(action: { 55 | 56 | if self.currentPageIndex + 1 == self.subViews.count { 57 | // self.currentPageIndex = 0 58 | 59 | //if using with proprty wrapper 60 | // self.dataOnboard.onboardComlete = true 61 | 62 | //if using with out property wrapper 63 | self.userOnboard.onboardComplete = true 64 | } else { 65 | self.currentPageIndex += 1 66 | } 67 | }) { 68 | Image(systemName: "arrow.right") 69 | .resizable() 70 | .foregroundColor(.white) 71 | .frame(width: 30, height: 30) 72 | .padding() 73 | .background(lightblueColor) 74 | .clipShape(Circle()) 75 | } 76 | }.padding() 77 | } 78 | } 79 | } 80 | 81 | struct OnboardingView_Previews: PreviewProvider { 82 | static var previews: some View { 83 | OnboardingView() 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Demo/Onboarding/PageControl.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PageControl.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 18/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import SwiftUI 12 | 13 | struct PageControl: UIViewRepresentable { 14 | 15 | var numberOfPages: Int 16 | 17 | @Binding var currentPageIndex: Int 18 | 19 | func makeUIView(context: UIViewRepresentableContext) -> UIPageControl { 20 | 21 | let control = UIPageControl() 22 | control.numberOfPages = numberOfPages 23 | control.currentPageIndicatorTintColor = UIColor.init(displayP3Red: 85.0/255.0, green: 84.0/255.0, blue: 166.0/255.0, alpha: 1.0) 24 | control.pageIndicatorTintColor = UIColor.lightGray 25 | 26 | return control 27 | } 28 | 29 | func updateUIView(_ uiView: UIPageControl, context: UIViewRepresentableContext) { 30 | 31 | uiView.currentPage = currentPageIndex 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Demo/Onboarding/PageViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PageViewController.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 18/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SwiftUI 11 | import UIKit 12 | 13 | struct PageViewController: UIViewControllerRepresentable { 14 | 15 | @Binding var currentPageIndex: Int 16 | 17 | var viewControllers: [UIViewController] 18 | 19 | class Coordinator: NSObject, UIPageViewControllerDataSource, UIPageViewControllerDelegate { 20 | 21 | var parent: PageViewController 22 | 23 | init(_ pageViewController: PageViewController) { 24 | self.parent = pageViewController 25 | } 26 | 27 | func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { 28 | 29 | //retrieves the index of the currently displayed view controller 30 | guard let index = parent.viewControllers.firstIndex(of: viewController) else { 31 | return nil 32 | } 33 | 34 | //shows the last view controller when the user swipes back from the first view controller 35 | if index == 0 { 36 | return parent.viewControllers.last 37 | } 38 | 39 | //show the view controller before the currently displayed view controller 40 | return parent.viewControllers[index - 1] 41 | } 42 | 43 | func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { 44 | 45 | //retrieves the index of the currently displayed view controller 46 | guard let index = parent.viewControllers.firstIndex(of: viewController) else { 47 | return nil 48 | } 49 | 50 | //shows the first view controller when the user swipes further from the last view controller 51 | if index + 1 == parent.viewControllers.count { 52 | return parent.viewControllers.first 53 | } 54 | 55 | //show the view controller after the currently displayed view controller 56 | return parent.viewControllers[index + 1] 57 | } 58 | 59 | func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { 60 | 61 | if completed, let visibleViewController = pageViewController.viewControllers?.first, let index = parent.viewControllers.firstIndex(of: visibleViewController) { 62 | parent.currentPageIndex = index 63 | } 64 | } 65 | } 66 | 67 | func makeCoordinator() -> Coordinator { 68 | Coordinator(self) 69 | } 70 | 71 | func makeUIViewController(context: Context) -> UIPageViewController { 72 | 73 | let pageViewController = UIPageViewController( 74 | transitionStyle: .scroll, 75 | navigationOrientation: .horizontal 76 | ) 77 | 78 | pageViewController.dataSource = context.coordinator 79 | pageViewController.delegate = context.coordinator 80 | 81 | return pageViewController 82 | } 83 | 84 | func updateUIViewController(_ pageViewController: UIPageViewController, context: Context) { 85 | 86 | pageViewController.setViewControllers( 87 | [viewControllers[currentPageIndex]], 88 | direction: .forward, 89 | animated: true 90 | ) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /Demo/Onboarding/PagesView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PagesView.swift 3 | // Demo 4 | // 5 | // Created by mac-00018 on 21/10/19. 6 | // Copyright © 2019 mac-00018. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | import Foundation 11 | import Combine 12 | 13 | struct PagesView : View { 14 | let limit: Double = 15 15 | let step: Double = 0.3 16 | 17 | @State var pages: [Page] = (0...3).map { i in 18 | Page(title: MockData.title, imageName: MockData.imageNames[i], content: MockData.contentStrings[i]) 19 | } 20 | 21 | @State var currentIndex = 0 22 | @State var nextIndex = 1 23 | 24 | @State var progress: Double = 0 25 | @State var isAnimating = false 26 | 27 | static let timerSpeed: Double = 0.01 28 | @State var timer = Timer.publish(every: timerSpeed, on: .current, in: .common).autoconnect() 29 | 30 | @State private var shape = AnyView(Circle().foregroundColor(.blue).frame(width: 60.0, height: 60.0, alignment: .center)) 31 | 32 | var body: some View { 33 | 34 | ZStack { 35 | 36 | Button(action: { 37 | self.isAnimating.toggle() 38 | self.timer = Timer.publish(every: Self.timerSpeed, on: .current, in: .common).autoconnect() 39 | }) { self.shape 40 | }.offset(y: 300) 41 | 42 | PageView(page: pages[currentIndex]) 43 | .offset(x: -CGFloat(pow(2, self.progress))) 44 | PageView(page: pages[nextIndex]) 45 | .offset(x: CGFloat(pow(2, (self.limit - self.progress)))) 46 | }.edgesIgnoringSafeArea(.vertical) 47 | .onReceive(self.timer) { _ in 48 | if !self.isAnimating { 49 | return 50 | } 51 | self.refreshAnimatingViews() 52 | } 53 | } 54 | 55 | func refreshAnimatingViews() { 56 | progress += step 57 | if progress > 2*limit { 58 | isAnimating = false 59 | progress = 0 60 | currentIndex = nextIndex 61 | if nextIndex + 1 < pages.count { 62 | nextIndex += 1 63 | } else { 64 | nextIndex = 0 65 | } 66 | } 67 | } 68 | } 69 | 70 | struct Page { 71 | var title: String 72 | var imageName: String 73 | var content: String 74 | let imageWidth: CGFloat = 150 75 | } 76 | 77 | struct PageView: View { 78 | var page: Page 79 | 80 | var body: some View { 81 | VStack(alignment: .center, spacing: 15) { 82 | Text(page.title).font(Font.system(size: 40)).fontWeight(.bold).lineLimit(nil) 83 | Image(page.imageName) 84 | .resizable() 85 | .frame(width: page.imageWidth, height: page.imageWidth) 86 | .cornerRadius(page.imageWidth/2) 87 | .clipped() 88 | Text(page.content).font(.body).lineLimit(nil) 89 | }.padding(60) 90 | } 91 | } 92 | 93 | struct MockData { 94 | static let title = "Eating grapes 101" 95 | static let contentStrings = [ 96 | "Step 1. Break off a branch holding a few grapes and lay it on your plate.", 97 | "Step 2. Put a grape in your mouth whole.", 98 | "Step 3. Deposit the seeds into your thumb and first two fingers.", 99 | "Step 4. Place the seeds on your plate." 100 | ] 101 | static let imageNames = [ 102 | "screen 1", 103 | "screen 2", 104 | "screen 3", 105 | "screen 4" 106 | ] 107 | } 108 | 109 | 110 | struct PagesView_Previews: PreviewProvider { 111 | static var previews: some View { 112 | PagesView() 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /Demo/Onboarding/Subview.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Subview.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 18/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct Subview: View { 12 | 13 | var imageString: String 14 | 15 | var body: some View { 16 | 17 | Image(imageString) 18 | .resizable() 19 | .aspectRatio(contentMode: .fill) 20 | .frame(width: UIScreen.main.bounds.width, height: (UIScreen.main.bounds.width * 500) / 414) 21 | .clipped() 22 | } 23 | } 24 | 25 | struct Subview_Previews: PreviewProvider { 26 | static var previews: some View { 27 | Subview(imageString: "2") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Demo/Other/OtherData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OtherData.swift 3 | // CollectionViewSwiftUI 4 | // 5 | // Created by mac-00013 on 09/10/19. 6 | // Copyright © 2019 swift. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SwiftUI 11 | import UIKit 12 | 13 | let CScreenSizeBounds = UIScreen.main.bounds 14 | let CScreenWidth = CScreenSizeBounds.width 15 | let CScreenHeight = CScreenSizeBounds.height 16 | 17 | func resignKeyboard() { 18 | UIApplication.shared.endEditing() 19 | } 20 | 21 | extension UIApplication { 22 | func endEditing() { 23 | sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) 24 | } 25 | } 26 | 27 | extension String { 28 | 29 | var trim: String { 30 | return self.trimmingCharacters(in: .whitespacesAndNewlines) 31 | } 32 | 33 | var isBlank: Bool { 34 | return self.trim.isEmpty 35 | } 36 | 37 | var isAlphanumeric: Bool { 38 | if self.count < 8 { 39 | return true 40 | } 41 | return !isBlank && rangeOfCharacter(from: .alphanumerics) != nil 42 | // let regex = "^[a-zA-Z0-9]$" 43 | // let predicate = NSPredicate(format:"SELF MATCHES %@", regex) 44 | // return predicate.evaluate(with:self) 45 | } 46 | 47 | var isValidEmail: Bool { 48 | 49 | let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9-]+\\.[A-Za-z]{2,4}" 50 | let predicate = NSPredicate(format:"SELF MATCHES %@", emailRegEx) 51 | return predicate.evaluate(with:self) 52 | } 53 | 54 | var isValidPhoneNo: Bool { 55 | 56 | let phoneCharacters = CharacterSet(charactersIn: "+0123456789").inverted 57 | let arrCharacters = self.components(separatedBy: phoneCharacters) 58 | return self == arrCharacters.joined(separator: "") 59 | } 60 | 61 | var isValidPassword: Bool { 62 | let passwordRegex = "^(?=.*[a-z])(?=.*[@$!%*#?&])[0-9a-zA-Z@$!%*#?&]{8,}" 63 | let predicate = NSPredicate(format:"SELF MATCHES %@", passwordRegex) 64 | return predicate.evaluate(with:self) 65 | } 66 | 67 | var isValidPhone: Bool { 68 | let phoneRegex = "^[0-9+]{0,1}+[0-9]{4,15}$" 69 | let phoneTest = NSPredicate(format: "SELF MATCHES %@", phoneRegex) 70 | return phoneTest.evaluate(with: self) 71 | } 72 | 73 | var isValidURL: Bool { 74 | let urlRegEx = "((https|http)://)((\\w|-)+)(([.]|[/])((\\w|-)+))+" 75 | return NSPredicate(format: "SELF MATCHES %@", urlRegEx).evaluate(with: self) 76 | } 77 | 78 | var isValidBidValue: Bool { 79 | 80 | guard let doubleValue = Double(self) else { return false} 81 | if doubleValue < 0{ 82 | return false 83 | } 84 | return true 85 | } 86 | 87 | var verifyURL: Bool { 88 | if let url = URL(string: self) { 89 | return UIApplication.shared.canOpenURL(url) 90 | } 91 | return false 92 | } 93 | } 94 | 95 | class KeyboardResponder: ObservableObject { 96 | private var notificationCenter: NotificationCenter 97 | @Published private(set) var currentHeight: CGFloat = 0 98 | 99 | init(center: NotificationCenter = .default) { 100 | notificationCenter = center 101 | notificationCenter.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil) 102 | notificationCenter.addObserver(self, selector: #selector(keyBoardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil) 103 | } 104 | 105 | deinit { 106 | notificationCenter.removeObserver(self) 107 | } 108 | 109 | @objc func keyBoardWillShow(notification: Notification) { 110 | if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { 111 | currentHeight = max(keyboardSize.height, 340.0) 112 | } 113 | } 114 | 115 | @objc func keyBoardWillHide(notification: Notification) { 116 | currentHeight = 0 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /Demo/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/Preview Content/Preview Assets.xcassets/TextColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0.000", 13 | "alpha" : "1.000", 14 | "blue" : "0.000", 15 | "green" : "0.000" 16 | } 17 | } 18 | }, 19 | { 20 | "idiom" : "universal", 21 | "appearances" : [ 22 | { 23 | "appearance" : "luminosity", 24 | "value" : "dark" 25 | } 26 | ], 27 | "color" : { 28 | "color-space" : "srgb", 29 | "components" : { 30 | "red" : "1.000", 31 | "alpha" : "1.000", 32 | "blue" : "1.000", 33 | "green" : "1.000" 34 | } 35 | } 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /Demo/SignUP(Combine framework)/SignupVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SignupVC.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 22/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct SignupVC: View { 12 | 13 | @ObservedObject private var userViewModel = UserViewModel() 14 | @State var presentAlert = false 15 | 16 | var body: some View { 17 | 18 | Form { 19 | 20 | Section(footer: Text(userViewModel.usernameMessage).foregroundColor(.red)) { 21 | TextField("Username", text: $userViewModel.userName) 22 | .autocapitalization(.none) 23 | } 24 | 25 | Section(footer: Text(userViewModel.passwordMessage).foregroundColor(.red)) { 26 | 27 | SecureField("Password", text: $userViewModel.password) 28 | SecureField("Confirm Password", text: $userViewModel.confirmPassword) 29 | } 30 | 31 | Section { 32 | 33 | Button(action: { 34 | self.signUp() 35 | }) { 36 | Text("Sign up") 37 | } 38 | .disabled(!userViewModel.isValid) 39 | } 40 | } 41 | .sheet(isPresented: $presentAlert) { 42 | WelcomeView() 43 | } 44 | } 45 | 46 | func signUp() { 47 | self.presentAlert = true 48 | } 49 | } 50 | 51 | struct SignupVC_Previews: PreviewProvider { 52 | static var previews: some View { 53 | SignupVC() 54 | } 55 | } 56 | 57 | struct WelcomeView: View { 58 | var body: some View { 59 | Text("Welcome! Great to have you on board!") 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /Demo/SignUP(Combine framework)/UserViewModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserViewModel.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 22/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Combine 11 | import Navajo_Swift 12 | 13 | class UserViewModel: ObservableObject { 14 | 15 | // Input 16 | @Published var userName = "" 17 | @Published var password = "" 18 | @Published var confirmPassword = "" 19 | 20 | // Output 21 | @Published var isValid = false 22 | @Published var usernameMessage = "" 23 | @Published var passwordMessage = "" 24 | 25 | private var cancellableSet: Set = [] 26 | 27 | private var isUsernameValidPublisher: AnyPublisher { 28 | 29 | $userName 30 | .debounce(for: 0.8, scheduler: RunLoop.main) 31 | .removeDuplicates() 32 | .map { input in 33 | return input.count >= 3 34 | } 35 | .eraseToAnyPublisher() 36 | } 37 | 38 | private var isPasswordEmptyPublisher: AnyPublisher { 39 | 40 | $password 41 | .debounce(for: 0.8, scheduler: RunLoop.main) 42 | .removeDuplicates() 43 | .map { password in 44 | return password == "" 45 | } 46 | .eraseToAnyPublisher() 47 | } 48 | 49 | private var arePasswordEqualPublisher: AnyPublisher { 50 | 51 | Publishers.CombineLatest($password, $confirmPassword) 52 | .debounce(for: 0.2, scheduler: RunLoop.main) 53 | .map { password, confirmpassword in 54 | return password == confirmpassword 55 | } 56 | .eraseToAnyPublisher() 57 | } 58 | 59 | private var passwordStrengthPublisher: AnyPublisher { 60 | 61 | $password 62 | .debounce(for: 0.2, scheduler: RunLoop.main) 63 | .removeDuplicates() 64 | .map { input in 65 | return Navajo.strength(ofPassword: input) 66 | } 67 | .eraseToAnyPublisher() 68 | } 69 | 70 | private var isPasswordStrongEnoughPublisher: AnyPublisher { 71 | 72 | passwordStrengthPublisher 73 | .map { strenght in 74 | 75 | switch strenght { 76 | case . reasonable, .strong, .veryStrong: 77 | return true 78 | default: 79 | return false 80 | } 81 | } 82 | .eraseToAnyPublisher() 83 | } 84 | 85 | enum PasswordCheck { 86 | 87 | case valid 88 | case empty 89 | case noMatch 90 | case notStrongEnough 91 | } 92 | 93 | private var isPasswordValidPublisher: AnyPublisher { 94 | 95 | Publishers.CombineLatest3(isPasswordEmptyPublisher, arePasswordEqualPublisher, isPasswordStrongEnoughPublisher) 96 | .map { passwordIsEmpty, passwordsAreEqual, passwordIsStrongEnough in 97 | 98 | if passwordIsEmpty { 99 | return .empty 100 | } else if !passwordsAreEqual { 101 | return .noMatch 102 | } else if !passwordIsStrongEnough { 103 | return .notStrongEnough 104 | } else { 105 | return .valid 106 | } 107 | } 108 | .eraseToAnyPublisher() 109 | } 110 | 111 | private var isFormValidPublisher: AnyPublisher { 112 | 113 | Publishers.CombineLatest(isUsernameValidPublisher, isPasswordValidPublisher) 114 | .map { userNameIsValid, passwordIsValid in 115 | return userNameIsValid && (passwordIsValid == .valid) 116 | } 117 | .eraseToAnyPublisher() 118 | } 119 | 120 | init() { 121 | 122 | isUsernameValidPublisher 123 | .receive(on: RunLoop.main) 124 | .map { valid in 125 | valid ? "" : "User name must at least have 3 characters" 126 | } 127 | .assign(to: \.usernameMessage, on: self) 128 | .store(in: &cancellableSet) 129 | 130 | isPasswordValidPublisher 131 | .receive(on: RunLoop.main) 132 | .map { passwordCheck in 133 | 134 | switch passwordCheck { 135 | case .empty: 136 | return "Password must not be empty" 137 | case .noMatch: 138 | return "Passwords don't match" 139 | case .notStrongEnough: 140 | return "Password not strong enough" 141 | default: 142 | return "" 143 | } 144 | } 145 | .assign(to: \.passwordMessage, on: self) 146 | .store(in: &cancellableSet) 147 | 148 | isFormValidPublisher 149 | .receive(on: RunLoop.main) 150 | .assign(to: \.isValid, on: self) 151 | .store(in: &cancellableSet) 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /Demo/TabBar/CurrentOrderVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CurrentOrderVC.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 16/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct CurrentOrderVC: View { 12 | var body: some View { 13 | Text("Bird Details") 14 | } 15 | } 16 | 17 | struct CurrentOrderVC_Previews: PreviewProvider { 18 | static var previews: some View { 19 | CurrentOrderVC() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Demo/TabBar/FavouritesVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FavouritesVC.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 16/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct FavouritesVC: View { 12 | var body: some View { 13 | Text("FavouritesVC") 14 | } 15 | } 16 | 17 | struct FavouritesVC_Previews: PreviewProvider { 18 | static var previews: some View { 19 | FavouritesVC() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Demo/TabBar/NotificationVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NotificationVC.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 16/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct NotificationVC: View { 12 | var body: some View { 13 | Text("Bird Details") 14 | } 15 | } 16 | 17 | struct NotificationVC_Previews: PreviewProvider { 18 | static var previews: some View { 19 | NotificationVC() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Demo/TabBar/TabBarView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabBarView.swift 3 | // SwiftUIDemo 4 | // 5 | // Created by mac-00018 on 16/09/19. 6 | // Copyright © 2019 mac-00018. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct TabBarView: View { 12 | 13 | var body: some View { 14 | 15 | TabView { 16 | 17 | ListView() 18 | .tabItem ( { VStack { 19 | Image("ic_email") 20 | Text("List View") 21 | } 22 | }).tag(0) 23 | 24 | CollectionView() 25 | .tabItem ( { VStack { 26 | Image("ic_email") 27 | Text("Collection View") 28 | } 29 | }).tag(1) 30 | } 31 | } 32 | 33 | } 34 | 35 | #if DEBUG 36 | struct TabBarView_Previews: PreviewProvider { 37 | static var previews: some View { 38 | TabBarView() 39 | } 40 | } 41 | #endif 42 | -------------------------------------------------------------------------------- /Demo/TabBar/TabbarVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabbarVC.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 16/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import SwiftUI 10 | 11 | struct TabbarVC: View { 12 | 13 | 14 | 15 | @State private var selectedView = 0 16 | 17 | init() { 18 | UINavigationBar.appearance().setBackgroundImage(UIImage(), for: UIBarMetrics.default) 19 | UINavigationBar.appearance().shadowImage = UIImage() 20 | UINavigationBar.appearance().isTranslucent = true 21 | UINavigationBar.appearance().tintColor = .black 22 | UINavigationBar.appearance().backgroundColor = .clear 23 | } 24 | 25 | var body: some View { 26 | 27 | TabView(selection: $selectedView) { 28 | 29 | NavigationView { 30 | HomeVC() 31 | } 32 | .tabItem { 33 | Image.init("ic_home", tintColor: .clear) 34 | Text("HOME") 35 | }.tag(0) 36 | 37 | NavigationView { 38 | ListView() 39 | .navigationBarTitle("", displayMode: .inline) 40 | } 41 | .tabItem { 42 | Image.init("ic_controls", tintColor: .clear) 43 | Text("CONTROLS") 44 | }.tag(1) 45 | } 46 | .accentColor(lightblueColor) 47 | } 48 | } 49 | 50 | struct TabbarVC_Previews: PreviewProvider { 51 | static var previews: some View { 52 | TabbarVC() 53 | } 54 | } 55 | 56 | extension Image { 57 | init(_ named: String, tintColor: UIColor) { 58 | let uiImage = UIImage(named: named) ?? UIImage() 59 | let tintedImage = uiImage.withTintColor(tintColor, 60 | renderingMode: .alwaysTemplate) 61 | self = Image(uiImage: tintedImage) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Demo/UserDefault.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserDefault.swift 3 | // SwiftUIWorkingDemo 4 | // 5 | // Created by mac-00015 on 17/10/19. 6 | // Copyright © 2019 mac-00015. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | @propertyWrapper 12 | struct UserDefault { 13 | 14 | let key: String 15 | let defaultValue: T 16 | 17 | var wrappedValue: T { 18 | 19 | get { 20 | return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue 21 | } set { 22 | UserDefaults.standard.set(newValue, forKey: key) 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Mindinventory 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. -------------------------------------------------------------------------------- /Media/SwiftUI-Sample-App.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Media/SwiftUI-Sample-App.gif -------------------------------------------------------------------------------- /Media/SwiftUI-Sample-App.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Media/SwiftUI-Sample-App.mp4 -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'Demo' do 5 | # Comment the next line if you don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for Demo 9 | pod 'Navajo-Swift' 10 | pod 'IQKeyboardManagerSwift' 11 | 12 | end 13 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - IQKeyboardManagerSwift (6.5.1) 3 | - Navajo-Swift (2.1.0) 4 | 5 | DEPENDENCIES: 6 | - IQKeyboardManagerSwift 7 | - Navajo-Swift 8 | 9 | SPEC REPOS: 10 | trunk: 11 | - IQKeyboardManagerSwift 12 | - Navajo-Swift 13 | 14 | SPEC CHECKSUMS: 15 | IQKeyboardManagerSwift: 9ac7524fad9f9fe9a3b98c927e7772471ca546d2 16 | Navajo-Swift: 57b93e73efbfbf452433efbff04402de56beff51 17 | 18 | PODFILE CHECKSUM: 9f292b1ecdd42fdfcf067ceaa892e13832228435 19 | 20 | COCOAPODS: 1.8.1 21 | -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQNSArray+Sort.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IQNSArray+Sort.swift 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | import Foundation 25 | import UIKit 26 | 27 | /** 28 | UIView.subviews sorting category. 29 | */ 30 | internal extension Array where Element: UIView { 31 | 32 | ///-------------- 33 | /// MARK: Sorting 34 | ///-------------- 35 | 36 | /** 37 | Returns the array by sorting the UIView's by their tag property. 38 | */ 39 | func sortedArrayByTag() -> [Element] { 40 | 41 | return sorted(by: { (obj1: Element, obj2: Element) -> Bool in 42 | 43 | return (obj1.tag < obj2.tag) 44 | }) 45 | } 46 | 47 | /** 48 | Returns the array by sorting the UIView's by their tag property. 49 | */ 50 | func sortedArrayByPosition() -> [Element] { 51 | 52 | return sorted(by: { (obj1: Element, obj2: Element) -> Bool in 53 | if obj1.frame.minY != obj2.frame.minY { 54 | return obj1.frame.minY < obj2.frame.minY 55 | } else { 56 | return obj1.frame.minX < obj2.frame.minX 57 | } 58 | }) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIScrollView+Additions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IQUIScrollView+Additions.swift 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | import Foundation 25 | import UIKit 26 | 27 | private var kIQShouldIgnoreScrollingAdjustment = "kIQShouldIgnoreScrollingAdjustment" 28 | private var kIQShouldRestoreScrollViewContentOffset = "kIQShouldRestoreScrollViewContentOffset" 29 | 30 | @objc public extension UIScrollView { 31 | 32 | /** 33 | If YES, then scrollview will ignore scrolling (simply not scroll it) for adjusting textfield position. Default is NO. 34 | */ 35 | @objc var shouldIgnoreScrollingAdjustment: Bool { 36 | get { 37 | 38 | if let aValue = objc_getAssociatedObject(self, &kIQShouldIgnoreScrollingAdjustment) as? Bool { 39 | return aValue 40 | } else { 41 | return false 42 | } 43 | } 44 | set(newValue) { 45 | objc_setAssociatedObject(self, &kIQShouldIgnoreScrollingAdjustment, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) 46 | } 47 | } 48 | 49 | /** 50 | To set customized distance from keyboard for textField/textView. Can't be less than zero 51 | */ 52 | @objc var shouldRestoreScrollViewContentOffset: Bool { 53 | get { 54 | 55 | if let aValue = objc_getAssociatedObject(self, &kIQShouldRestoreScrollViewContentOffset) as? Bool { 56 | return aValue 57 | } else { 58 | return false 59 | } 60 | } 61 | set(newValue) { 62 | objc_setAssociatedObject(self, &kIQShouldRestoreScrollViewContentOffset, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) 63 | } 64 | } 65 | } 66 | 67 | internal extension UITableView { 68 | 69 | func previousIndexPath(of indexPath: IndexPath) -> IndexPath? { 70 | var previousRow = indexPath.row - 1 71 | var previousSection = indexPath.section 72 | 73 | //Fixing indexPath 74 | if previousRow < 0 { 75 | previousSection -= 1 76 | 77 | if previousSection >= 0 { 78 | previousRow = self.numberOfRows(inSection: previousSection) - 1 79 | } 80 | } 81 | 82 | if previousRow >= 0 && previousSection >= 0 { 83 | return IndexPath(row: previousRow, section: previousSection) 84 | } else { 85 | return nil 86 | } 87 | } 88 | } 89 | 90 | internal extension UICollectionView { 91 | 92 | func previousIndexPath(of indexPath: IndexPath) -> IndexPath? { 93 | var previousRow = indexPath.row - 1 94 | var previousSection = indexPath.section 95 | 96 | //Fixing indexPath 97 | if previousRow < 0 { 98 | previousSection -= 1 99 | 100 | if previousSection >= 0 { 101 | previousRow = self.numberOfItems(inSection: previousSection) - 1 102 | } 103 | } 104 | 105 | if previousRow >= 0 && previousSection >= 0 { 106 | return IndexPath(item: previousRow, section: previousSection) 107 | } else { 108 | return nil 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUITextFieldView+Additions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IQUITextFieldView+Additions.swift 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | import Foundation 25 | import UIKit 26 | 27 | /** 28 | Uses default keyboard distance for textField. 29 | */ 30 | public let kIQUseDefaultKeyboardDistance = CGFloat.greatestFiniteMagnitude 31 | 32 | private var kIQKeyboardDistanceFromTextField = "kIQKeyboardDistanceFromTextField" 33 | //private var kIQKeyboardEnableMode = "kIQKeyboardEnableMode" 34 | private var kIQShouldResignOnTouchOutsideMode = "kIQShouldResignOnTouchOutsideMode" 35 | private var kIQIgnoreSwitchingByNextPrevious = "kIQIgnoreSwitchingByNextPrevious" 36 | 37 | /** 38 | UIView category for managing UITextField/UITextView 39 | */ 40 | @objc public extension UIView { 41 | 42 | /** 43 | To set customized distance from keyboard for textField/textView. Can't be less than zero 44 | */ 45 | @objc var keyboardDistanceFromTextField: CGFloat { 46 | get { 47 | 48 | if let aValue = objc_getAssociatedObject(self, &kIQKeyboardDistanceFromTextField) as? CGFloat { 49 | return aValue 50 | } else { 51 | return kIQUseDefaultKeyboardDistance 52 | } 53 | } 54 | set(newValue) { 55 | objc_setAssociatedObject(self, &kIQKeyboardDistanceFromTextField, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) 56 | } 57 | } 58 | 59 | /** 60 | If shouldIgnoreSwitchingByNextPrevious is true then library will ignore this textField/textView while moving to other textField/textView using keyboard toolbar next previous buttons. Default is false 61 | */ 62 | @objc var ignoreSwitchingByNextPrevious: Bool { 63 | get { 64 | 65 | if let aValue = objc_getAssociatedObject(self, &kIQIgnoreSwitchingByNextPrevious) as? Bool { 66 | return aValue 67 | } else { 68 | return false 69 | } 70 | } 71 | set(newValue) { 72 | objc_setAssociatedObject(self, &kIQIgnoreSwitchingByNextPrevious, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) 73 | } 74 | } 75 | 76 | // /** 77 | // Override Enable/disable managing distance between keyboard and textField behaviour for this particular textField. 78 | // */ 79 | // @objc public var enableMode: IQEnableMode { 80 | // get { 81 | // 82 | // if let savedMode = objc_getAssociatedObject(self, &kIQKeyboardEnableMode) as? IQEnableMode { 83 | // return savedMode 84 | // } else { 85 | // return .default 86 | // } 87 | // } 88 | // set(newValue) { 89 | // objc_setAssociatedObject(self, &kIQKeyboardEnableMode, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) 90 | // } 91 | // } 92 | 93 | /** 94 | Override resigns Keyboard on touching outside of UITextField/View behaviour for this particular textField. 95 | */ 96 | @objc var shouldResignOnTouchOutsideMode: IQEnableMode { 97 | get { 98 | 99 | if let savedMode = objc_getAssociatedObject(self, &kIQShouldResignOnTouchOutsideMode) as? IQEnableMode { 100 | return savedMode 101 | } else { 102 | return .default 103 | } 104 | } 105 | set(newValue) { 106 | objc_setAssociatedObject(self, &kIQShouldResignOnTouchOutsideMode, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIViewController+Additions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IQUIViewController+Additions.swift 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | import UIKit 25 | 26 | private var kIQLayoutGuideConstraint = "kIQLayoutGuideConstraint" 27 | 28 | @objc public extension UIViewController { 29 | 30 | /** 31 | To set customized distance from keyboard for textField/textView. Can't be less than zero 32 | 33 | @deprecated Due to change in core-logic of handling distance between textField and keyboard distance, this layout contraint tweak is no longer needed and things will just work out of the box regardless of constraint pinned with safeArea/layoutGuide/superview 34 | */ 35 | @available(*, deprecated, message: "Due to change in core-logic of handling distance between textField and keyboard distance, this layout contraint tweak is no longer needed and things will just work out of the box regardless of constraint pinned with safeArea/layoutGuide/superview.") 36 | @IBOutlet @objc var IQLayoutGuideConstraint: NSLayoutConstraint? { 37 | get { 38 | 39 | return objc_getAssociatedObject(self, &kIQLayoutGuideConstraint) as? NSLayoutConstraint 40 | } 41 | 42 | set(newValue) { 43 | objc_setAssociatedObject(self, &kIQLayoutGuideConstraint, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IQKeyboardManagerConstants.swift 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | import Foundation 25 | 26 | ///----------------------------------- 27 | /// MARK: IQAutoToolbarManageBehaviour 28 | ///----------------------------------- 29 | 30 | /** 31 | `IQAutoToolbarBySubviews` 32 | Creates Toolbar according to subview's hirarchy of Textfield's in view. 33 | 34 | `IQAutoToolbarByTag` 35 | Creates Toolbar according to tag property of TextField's. 36 | 37 | `IQAutoToolbarByPosition` 38 | Creates Toolbar according to the y,x position of textField in it's superview coordinate. 39 | */ 40 | @objc public enum IQAutoToolbarManageBehaviour: Int { 41 | case bySubviews 42 | case byTag 43 | case byPosition 44 | } 45 | 46 | /** 47 | `IQPreviousNextDisplayModeDefault` 48 | Show NextPrevious when there are more than 1 textField otherwise hide. 49 | 50 | `IQPreviousNextDisplayModeAlwaysHide` 51 | Do not show NextPrevious buttons in any case. 52 | 53 | `IQPreviousNextDisplayModeAlwaysShow` 54 | Always show nextPrevious buttons, if there are more than 1 textField then both buttons will be visible but will be shown as disabled. 55 | */ 56 | @objc public enum IQPreviousNextDisplayMode: Int { 57 | case `default` 58 | case alwaysHide 59 | case alwaysShow 60 | } 61 | 62 | /** 63 | `IQEnableModeDefault` 64 | Pick default settings. 65 | 66 | `IQEnableModeEnabled` 67 | setting is enabled. 68 | 69 | `IQEnableModeDisabled` 70 | setting is disabled. 71 | */ 72 | @objc public enum IQEnableMode: Int { 73 | case `default` 74 | case enabled 75 | case disabled 76 | } 77 | 78 | /* 79 | /---------------------------------------------------------------------------------------------------\ 80 | \---------------------------------------------------------------------------------------------------/ 81 | | iOS Notification Mechanism | 82 | /---------------------------------------------------------------------------------------------------\ 83 | \---------------------------------------------------------------------------------------------------/ 84 | 85 | ------------------------------------------------------------ 86 | When UITextField become first responder 87 | ------------------------------------------------------------ 88 | - UITextFieldTextDidBeginEditingNotification (UITextField) 89 | - UIKeyboardWillShowNotification 90 | - UIKeyboardDidShowNotification 91 | 92 | ------------------------------------------------------------ 93 | When UITextView become first responder 94 | ------------------------------------------------------------ 95 | - UIKeyboardWillShowNotification 96 | - UITextViewTextDidBeginEditingNotification (UITextView) 97 | - UIKeyboardDidShowNotification 98 | 99 | ------------------------------------------------------------ 100 | When switching focus from UITextField to another UITextField 101 | ------------------------------------------------------------ 102 | - UITextFieldTextDidEndEditingNotification (UITextField1) 103 | - UITextFieldTextDidBeginEditingNotification (UITextField2) 104 | - UIKeyboardWillShowNotification 105 | - UIKeyboardDidShowNotification 106 | 107 | ------------------------------------------------------------ 108 | When switching focus from UITextView to another UITextView 109 | ------------------------------------------------------------ 110 | - UITextViewTextDidEndEditingNotification: (UITextView1) 111 | - UIKeyboardWillShowNotification 112 | - UITextViewTextDidBeginEditingNotification: (UITextView2) 113 | - UIKeyboardDidShowNotification 114 | 115 | ------------------------------------------------------------ 116 | When switching focus from UITextField to UITextView 117 | ------------------------------------------------------------ 118 | - UITextFieldTextDidEndEditingNotification (UITextField) 119 | - UIKeyboardWillShowNotification 120 | - UITextViewTextDidBeginEditingNotification (UITextView) 121 | - UIKeyboardDidShowNotification 122 | 123 | ------------------------------------------------------------ 124 | When switching focus from UITextView to UITextField 125 | ------------------------------------------------------------ 126 | - UITextViewTextDidEndEditingNotification (UITextView) 127 | - UITextFieldTextDidBeginEditingNotification (UITextField) 128 | - UIKeyboardWillShowNotification 129 | - UIKeyboardDidShowNotification 130 | 131 | ------------------------------------------------------------ 132 | When opening/closing UIKeyboard Predictive bar 133 | ------------------------------------------------------------ 134 | - UIKeyboardWillShowNotification 135 | - UIKeyboardDidShowNotification 136 | 137 | ------------------------------------------------------------ 138 | On orientation change 139 | ------------------------------------------------------------ 140 | - UIApplicationWillChangeStatusBarOrientationNotification 141 | - UIKeyboardWillHideNotification 142 | - UIKeyboardDidHideNotification 143 | - UIApplicationDidChangeStatusBarOrientationNotification 144 | - UIKeyboardWillShowNotification 145 | - UIKeyboardDidShowNotification 146 | - UIKeyboardWillShowNotification 147 | - UIKeyboardDidShowNotification 148 | 149 | */ 150 | -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstantsInternal.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IQKeyboardManagerConstantsInternal.swift 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | import Foundation 25 | -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IQBarButtonItem.swift 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | import UIKit 25 | import Foundation 26 | 27 | open class IQBarButtonItem: UIBarButtonItem { 28 | 29 | private static var _classInitialize: Void = classInitialize() 30 | 31 | @objc public override init() { 32 | _ = IQBarButtonItem._classInitialize 33 | super.init() 34 | } 35 | 36 | @objc public required init?(coder aDecoder: NSCoder) { 37 | _ = IQBarButtonItem._classInitialize 38 | super.init(coder: aDecoder) 39 | } 40 | 41 | private class func classInitialize() { 42 | 43 | let appearanceProxy = self.appearance() 44 | 45 | #if swift(>=4.2) 46 | let states: [UIControl.State] 47 | #else 48 | let states: [UIControlState] 49 | #endif 50 | 51 | states = [.normal, .highlighted, .disabled, .selected, .application, .reserved] 52 | 53 | for state in states { 54 | 55 | appearanceProxy.setBackgroundImage(nil, for: state, barMetrics: .default) 56 | appearanceProxy.setBackgroundImage(nil, for: state, style: .done, barMetrics: .default) 57 | appearanceProxy.setBackgroundImage(nil, for: state, style: .plain, barMetrics: .default) 58 | appearanceProxy.setBackButtonBackgroundImage(nil, for: state, barMetrics: .default) 59 | } 60 | 61 | appearanceProxy.setTitlePositionAdjustment(UIOffset(), for: .default) 62 | appearanceProxy.setBackgroundVerticalPositionAdjustment(0, for: .default) 63 | appearanceProxy.setBackButtonBackgroundVerticalPositionAdjustment(0, for: .default) 64 | } 65 | 66 | @objc override open var tintColor: UIColor? { 67 | didSet { 68 | 69 | #if swift(>=4.2) 70 | var textAttributes = [NSAttributedString.Key: Any]() 71 | let foregroundColorKey = NSAttributedString.Key.foregroundColor 72 | #elseif swift(>=4) 73 | var textAttributes = [NSAttributedStringKey: Any]() 74 | let foregroundColorKey = NSAttributedStringKey.foregroundColor 75 | #else 76 | var textAttributes = [String: Any]() 77 | let foregroundColorKey = NSForegroundColorAttributeName 78 | #endif 79 | 80 | textAttributes[foregroundColorKey] = tintColor 81 | 82 | #if swift(>=4) 83 | 84 | if let attributes = titleTextAttributes(for: .normal) { 85 | 86 | for (key, value) in attributes { 87 | #if swift(>=4.2) 88 | textAttributes[key] = value 89 | #else 90 | textAttributes[NSAttributedStringKey.init(key)] = value 91 | #endif 92 | } 93 | } 94 | 95 | #else 96 | 97 | if let attributes = titleTextAttributes(for: .normal) { 98 | textAttributes = attributes 99 | } 100 | #endif 101 | 102 | setTitleTextAttributes(textAttributes, for: .normal) 103 | } 104 | } 105 | 106 | /** 107 | Boolean to know if it's a system item or custom item, we are having a limitation that we cannot override a designated initializer, so we are manually setting this property once in initialization 108 | */ 109 | @objc internal var isSystemItem = false 110 | 111 | /** 112 | Additional target & action to do get callback action. Note that setting custom target & selector doesn't affect native functionality, this is just an additional target to get a callback. 113 | 114 | @param target Target object. 115 | @param action Target Selector. 116 | */ 117 | @objc open func setTarget(_ target: AnyObject?, action: Selector?) { 118 | if let target = target, let action = action { 119 | invocation = IQInvocation(target, action) 120 | } else { 121 | invocation = nil 122 | } 123 | } 124 | 125 | /** 126 | Customized Invocation to be called when button is pressed. invocation is internally created using setTarget:action: method. 127 | */ 128 | @objc open var invocation: IQInvocation? 129 | 130 | deinit { 131 | target = nil 132 | invocation = nil 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IQInvocation.swift 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | import UIKit 25 | 26 | @objc public class IQInvocation: NSObject { 27 | @objc public weak var target: AnyObject? 28 | @objc public var action: Selector 29 | 30 | @objc public init(_ target: AnyObject, _ action: Selector) { 31 | self.target = target 32 | self.action = action 33 | } 34 | 35 | @objc public func invoke(from: Any) { 36 | if let target = target { 37 | UIApplication.shared.sendAction(action, to: target, from: from, for: UIEvent()) 38 | } 39 | } 40 | 41 | deinit { 42 | target = nil 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IQPreviousNextView.swift 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | import UIKit 25 | 26 | @objc public class IQPreviousNextView: UIView { 27 | 28 | } 29 | 30 | //#if swift(>=5.1) 31 | //import SwiftUI 32 | // 33 | //struct IQPreviousNextViewSwiftUI: UIViewRepresentable { 34 | // func makeUIView(context: Context) -> IQPreviousNextView { 35 | // IQPreviousNextView(frame: .zero) 36 | // } 37 | // 38 | // func updateUIView(_ view: IQPreviousNextView, context: Context) { 39 | // } 40 | //} 41 | // 42 | //struct IQTextViewSwiftUI_Preview: PreviewProvider { 43 | // static var previews: some View { 44 | // IQPreviousNextViewSwiftUI() 45 | // } 46 | //} 47 | // 48 | //#endif 49 | 50 | -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowDown@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowDown@2x.png -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowDown@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowDown@3x.png -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@2x.png -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@3x.png -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@2x.png -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@3x.png -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowUp@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowUp@2x.png -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowUp@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/SwiftUI-App/960e869a83d69c80cfce410d4ea91bd8a63209bb/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Resources/IQKeyboardManager.bundle/IQButtonBarArrowUp@3x.png -------------------------------------------------------------------------------- /Pods/IQKeyboardManagerSwift/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-2017 Iftekhar Qurashi 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 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - IQKeyboardManagerSwift (6.5.1) 3 | - Navajo-Swift (2.1.0) 4 | 5 | DEPENDENCIES: 6 | - IQKeyboardManagerSwift 7 | - Navajo-Swift 8 | 9 | SPEC REPOS: 10 | trunk: 11 | - IQKeyboardManagerSwift 12 | - Navajo-Swift 13 | 14 | SPEC CHECKSUMS: 15 | IQKeyboardManagerSwift: 9ac7524fad9f9fe9a3b98c927e7772471ca546d2 16 | Navajo-Swift: 57b93e73efbfbf452433efbff04402de56beff51 17 | 18 | PODFILE CHECKSUM: 9f292b1ecdd42fdfcf067ceaa892e13832228435 19 | 20 | COCOAPODS: 1.8.1 21 | -------------------------------------------------------------------------------- /Pods/Navajo-Swift/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-2016 Jason Nam (http://www.jasonnam.com) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pods/Navajo-Swift/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Navajo-Swift 4 | 5 | **Password Validator & Strength Evaluator** 6 | 7 | > Navajo is named in honor of the famed [code talkers of the Second World War](http://en.wikipedia.org/wiki/Code_talker#Navajo_code_talkers). 8 | 9 | ## Original Project 10 | 11 | [Navajo](https://github.com/mattt/Navajo) by Mattt Thompson 12 | 13 | > This project is not compatible with the original project. 14 | 15 | ## Installation 16 | 17 | [![Platform](https://img.shields.io/cocoapods/p/Navajo-Swift.svg?style=flat)](https://apple.com) 18 | [![Swift 4.0](https://img.shields.io/badge/Swift-4.0-orange.svg?style=flat)](https://developer.apple.com/swift) 19 | [![Travis-CI](https://travis-ci.org/jasonnam/Navajo-Swift.svg?branch=master)](https://travis-ci.org/jasonnam/Navajo-Swift) 20 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 21 | [![Version](https://img.shields.io/cocoapods/v/Navajo-Swift.svg?style=flat)](https://cocoapods.org/pods/Navajo-Swift) 22 | 23 | ### Carthage 24 | 25 | ```ogdl 26 | github "jasonnam/Navajo-Swift" 27 | ``` 28 | 29 | ### CocoaPods 30 | 31 | ```ruby 32 | use_frameworks! 33 | pod 'Navajo-Swift' 34 | ``` 35 | 36 | ```swift 37 | import Navajo_Swift 38 | ``` 39 | 40 | ### Manual 41 | 42 | Just copy the files in Source folder into your project. 43 | 44 | ## Usage 45 | 46 | ### Evaluating Password Strength 47 | 48 | > Password strength is evaluated in terms of [information entropy](http://en.wikipedia.org/wiki/Entropy_%28information_theory%29). 49 | 50 | ```swift 51 | let password = passwordField.text ?? "" 52 | let strength = Navajo.strength(ofPassword: password) 53 | 54 | strengthLabel.text = Navajo.localizedString(forStrength: strength) 55 | ``` 56 | 57 | ### Validating Password 58 | 59 | ```swift 60 | let lengthRule = LengthRule(min: 6, max: 24) 61 | let uppercaseRule = RequiredCharacterRule(preset: .LowercaseCharacter) 62 | 63 | validator = PasswordValidator(rules: [lengthRule, uppercaseRule]) 64 | 65 | if let failingRules = validator.validate(password) { 66 | validationLabel.textColor = .red 67 | validationLabel.text = failingRules.map({ return $0.localizedErrorDescription }).joined(separator: "\n") 68 | } else { 69 | validationLabel.textColor = .green 70 | validationLabel.text = "Valid" 71 | } 72 | ``` 73 | 74 | #### Available Validation Rules 75 | 76 | - Allowed Characters 77 | - Required Characters (custom, lowercase, uppercase, decimal, symbol) 78 | - Non-Dictionary Word 79 | - Minimum / Maximum Length 80 | - Predicate Match 81 | - Regular Expression Match 82 | - Block Evaluation 83 | 84 | If you are using the Predicate and Regex rules, remember that when password is matching to them it is considered to be invalid. For example, we can check if users are using for example "password123" as their password by following rule object. 85 | 86 | ```swift 87 | let rule = PredicateRule(predicate: NSPredicate(format: "SELF BEGINSWITH %@", "PASSWORD")) 88 | ``` 89 | 90 | For the block rule, it is considered to be invalid when the block returns true. 91 | 92 | ### Localization 93 | 94 | Keys for the localizable strings 95 | [Localization Tutorial](http://rshankar.com/internationalization-and-localization-of-apps-in-xcode-6-and-swift/) or check the demo app in the repository. 96 | 97 | #### Password Strength 98 | 99 | - NAVAJO_VERY_WEAK 100 | - NAVAJO_WEAK 101 | - NAVAJO_REASONABLE 102 | - NAVAJO_STRONG 103 | - NAVAJO_VERY_STRONG 104 | 105 | #### Password Validation 106 | 107 | - NAVAJO_ALLOWED_CHARACTER_ERROR 108 | - NAVAJO_REQUIRED_CHARACTER_REQUIRED_ERROR 109 | - NAVAJO_REQUIRED_CHARACTER_LOWERCASE_ERROR 110 | - NAVAJO_REQUIRED_CHARACTER_UPPERCASE_ERROR 111 | - NAVAJO_REQUIRED_CHARACTER_DECIMAL_DIGIT_ERROR 112 | - NAVAJO_REQUIRED_CHARACTER_SYMBOL_ERROR 113 | - NAVAJO_DICTIONARYWORD_ERROR 114 | - NAVAJO_LENGTH_ERROR 115 | - NAVAJO_PREDICATE_ERROR 116 | - NAVAJO_REGEX_ERROR 117 | - NAVAJO_BLOCK_ERROR 118 | 119 | ## Contact 120 | 121 | Any feedback and pull requests are welcome :) 122 | 123 | Jason Nam
[Website](http://jasonnam.com)
[Email](mailto:contact@jasonnam.com) 124 | 125 | ## License 126 | 127 | Navajo-Swift is available under the MIT license. See the LICENSE file for more info. 128 | -------------------------------------------------------------------------------- /Pods/Navajo-Swift/Source/AllowedCharacterRule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AllowedCharacterRule.swift 3 | // Navajo 4 | // 5 | // Copyright (c) 2015-2017 Jason Nam (http://jasonnam.com) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | import Foundation 27 | 28 | /// AllowedCharacterRule checks if the password only has allowed characters. 29 | open class AllowedCharacterRule: PasswordRule { 30 | 31 | open var disallowedCharacters: CharacterSet? 32 | 33 | /// Initialize with an NSCharacterSet object. 34 | public convenience init(allowedCharacters: CharacterSet) { 35 | self.init() 36 | disallowedCharacters = allowedCharacters.inverted 37 | } 38 | 39 | /// Evaluate password. Return false if it is passed and true if failed. 40 | open func evaluate(_ password: String) -> Bool { 41 | guard let disallowedCharacters = disallowedCharacters else { 42 | return false 43 | } 44 | return password.rangeOfCharacter(from: disallowedCharacters) != nil 45 | } 46 | 47 | /// Error description. 48 | /// Localization Key - "NAVAJO_ALLOWED_CHARACTER_ERROR" 49 | open var localizedErrorDescription: String { 50 | return NSLocalizedString("NAVAJO_ALLOWED_CHARACTER_ERROR", tableName: nil, bundle: Bundle.main, value: "Must not include disallowed character", comment: "Navajo - Allowed character rule") 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Pods/Navajo-Swift/Source/BlockRule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlockRule.swift 3 | // Navajo 4 | // 5 | // Copyright (c) 2015-2017 Jason Nam (http://jasonnam.com) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | import Foundation 27 | 28 | /// BlockRule checks password with a block which gets a string and returns a bool value. 29 | open class BlockRule: PasswordRule { 30 | 31 | open var evaluation: ((String) -> Bool)? 32 | 33 | /// Initialize with a Block. 34 | public convenience init(evaluation: @escaping (String) -> Bool) { 35 | self.init() 36 | self.evaluation = evaluation 37 | } 38 | 39 | /// Evaluate password. Return false if it is passed and true if failed. 40 | open func evaluate(_ password: String) -> Bool { 41 | guard let evaluation = evaluation else { 42 | return false 43 | } 44 | 45 | return evaluation(password) 46 | } 47 | 48 | /// Error description. 49 | /// Localization Key - "NAVAJO_BLOCK_ERROR" 50 | open var localizedErrorDescription: String { 51 | return NSLocalizedString("NAVAJO_BLOCK_ERROR", tableName: nil, bundle: Bundle.main, value: "Must not satisfy precondition", comment: "Navajo - Block rule") 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Pods/Navajo-Swift/Source/DictionaryWordRule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DictionaryWordRule.swift 3 | // Navajo 4 | // 5 | // Copyright (c) 2015-2017 Jason Nam (http://jasonnam.com) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #if os(OSX) 27 | import Cocoa 28 | #else 29 | import UIKit 30 | #endif 31 | 32 | /// DictionaryWordRule checks if the password can be found on the OSX or iOS dictionary. 33 | open class DictionaryWordRule: PasswordRule { 34 | 35 | private let nonLowercaseCharacterSet = CharacterSet.lowercaseLetters.inverted 36 | 37 | /// Evaluate password. Return false if it is passed and true if failed. 38 | open func evaluate(_ password: String) -> Bool { 39 | #if os(OSX) 40 | return DCSGetTermRangeInString(nil, password as CFString, 0).location != kCFNotFound 41 | #else 42 | return UIReferenceLibraryViewController.dictionaryHasDefinition(forTerm: password.lowercased().trimmingCharacters(in: nonLowercaseCharacterSet)) 43 | #endif 44 | } 45 | 46 | /// Error description. 47 | /// Localization Key - "NAVAJO_DICTIONARYWORD_ERROR" 48 | open var localizedErrorDescription: String { 49 | return NSLocalizedString("NAVAJO_DICTIONARYWORD_ERROR", tableName: nil, bundle: Bundle.main, value: "Must not be dictionary word", comment: "Navajo - Dictionary word rule") 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Pods/Navajo-Swift/Source/LengthRule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LengthRule.swift 3 | // Navajo 4 | // 5 | // Copyright (c) 2015-2017 Jason Nam (http://jasonnam.com) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | import Foundation 27 | 28 | /// LengthRule checks the length of password. 29 | open class LengthRule: PasswordRule { 30 | 31 | open var range: NSRange? 32 | 33 | /// Initialize with minimum and maximum values. 34 | public convenience init(min: Int, max: Int) { 35 | self.init() 36 | range = NSMakeRange(min, max - min + 1) 37 | } 38 | 39 | /// Evaluate password. Return false if it is passed and true if failed. 40 | open func evaluate(_ password: String) -> Bool { 41 | guard let range = range else { 42 | return false 43 | } 44 | 45 | return !NSLocationInRange(password.count, range) 46 | } 47 | 48 | /// Error description. 49 | /// Localization Key - "NAVAJO_LENGTH_ERROR" 50 | open var localizedErrorDescription: String { 51 | var rangeDescription = "nil" 52 | 53 | if let range = range { 54 | rangeDescription = String(range.lowerBound) + " - " + String(range.upperBound - 1) 55 | } 56 | 57 | return NSLocalizedString("NAVAJO_LENGTH_ERROR", tableName: nil, bundle: Bundle.main, value: "Must be within range ", comment: "Navajo - Length rule") + rangeDescription 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Pods/Navajo-Swift/Source/PasswordRule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PasswordRule.swift 3 | // Navajo 4 | // 5 | // Copyright (c) 2015-2017 Jason Nam (http://jasonnam.com) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | import Foundation 27 | 28 | /// By adopting PasswordRule protocol you can build your own rules. 29 | public protocol PasswordRule { 30 | 31 | /// Evaluating the password 32 | /// 33 | /// - parameter password: Password string to be evaluated 34 | /// 35 | /// - returns: true is considered to be failed and false is passed. 36 | func evaluate(_ password: String) -> Bool 37 | 38 | /// Error description 39 | var localizedErrorDescription: String { get } 40 | } 41 | -------------------------------------------------------------------------------- /Pods/Navajo-Swift/Source/PasswordValidator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NJOPasswordValidator.swift 3 | // Navajo 4 | // 5 | // Copyright (c) 2015-2017 Jason Nam (http://jasonnam.com) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | import Foundation 27 | 28 | /// PasswordValidator validates passwords with custom rules. 29 | open class PasswordValidator { 30 | 31 | open var rules: [PasswordRule] = [] 32 | 33 | /// PasswordValidator object which checks if the length of password is between 6 and 24. 34 | public static var standard: PasswordValidator { 35 | return PasswordValidator(rules: [standardLengthRule]) 36 | } 37 | 38 | /// Length rule having minimum of 6 and maximum of 24. 39 | public static var standardLengthRule: LengthRule { 40 | return LengthRule(min: 6, max: 24) 41 | } 42 | 43 | /// Initialize PasswordValidator with an array of PasswordRule. 44 | /// 45 | /// - parameter rules: Password rule(s) 46 | /// 47 | /// - returns: Password validator 48 | public convenience init(rules: [PasswordRule]) { 49 | self.init() 50 | self.rules = rules 51 | } 52 | 53 | /// Executes validation with a password and returns failing rules. 54 | /// 55 | /// - parameter password: Password string to be validated 56 | /// 57 | /// - returns: Failing rules. nil if all of the rules are passed. 58 | open func validate(_ password: String) -> [PasswordRule]? { 59 | var failingRules: [PasswordRule] = [] 60 | 61 | for rule in rules { 62 | if rule.evaluate(password) { 63 | failingRules.insert(rule, at: failingRules.count) 64 | } 65 | } 66 | 67 | if failingRules.count > 0 { 68 | return failingRules 69 | } else { 70 | return nil 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Pods/Navajo-Swift/Source/PredicateRule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PredicateRule.swift 3 | // Navajo 4 | // 5 | // Copyright (c) 2015-2017 Jason Nam (http://jasonnam.com) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | import Foundation 27 | 28 | /// PredicateRule checks password with a NSPredicate object. 29 | open class PredicateRule: PasswordRule { 30 | 31 | open var predicate: NSPredicate? = nil 32 | 33 | /// Initialize with an NSPredicate object. 34 | public convenience init(predicate: NSPredicate) { 35 | self.init() 36 | self.predicate = predicate 37 | } 38 | 39 | /// Evaluate password. Return false if it is passed and true if failed. 40 | open func evaluate(_ password: String) -> Bool { 41 | guard let predicate = predicate else { 42 | return false 43 | } 44 | 45 | return predicate.evaluate(with: password) 46 | } 47 | 48 | /// Error description. 49 | /// Localization Key - "NAVAJO_PREDICATE_ERROR" 50 | open var localizedErrorDescription: String { 51 | return NSLocalizedString("NAVAJO_PREDICATE_ERROR", tableName: nil, bundle: Bundle.main, value: "Must not match predicate", comment: "Navajo - Predicate rule") 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Pods/Navajo-Swift/Source/RegularExpressionRule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RegularExpressionRule.swift 3 | // Navajo 4 | // 5 | // Copyright (c) 2015-2017 Jason Nam (http://jasonnam.com) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | import Foundation 27 | 28 | /// RegularExpressionRule checks password with a NSRegularExpression object. 29 | open class RegularExpressionRule: PasswordRule { 30 | 31 | open var regularExpression: NSRegularExpression? 32 | 33 | /// Initialize with an NSRegularExpression object. 34 | public convenience init(regularExpression: NSRegularExpression) { 35 | self.init() 36 | self.regularExpression = regularExpression 37 | } 38 | 39 | /// Evaluate password. Return false if it is passed and true if failed. 40 | open func evaluate(_ password: String) -> Bool { 41 | guard let regularExpression = regularExpression else { 42 | return false 43 | } 44 | 45 | return regularExpression.numberOfMatches(in: password, options: [], range: NSMakeRange(0, password.count)) > 0 46 | } 47 | 48 | /// Error description. 49 | /// Localization Key - "NAVAJO_REGEX_ERROR" 50 | open var localizedErrorDescription: String { 51 | return NSLocalizedString("NAVAJO_REGEX_ERROR", tableName: nil, bundle: Bundle.main, value: "Must not match regular expression", comment: "Navajo - Regex rule") 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Pods/Navajo-Swift/Source/RequiredCharacterRule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RequiredCharacterRule.swift 3 | // Navajo 4 | // 5 | // Copyright (c) 2015-2017 Jason Nam (http://jasonnam.com) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | import Foundation 27 | 28 | /// RequiredCharacterRulePreset makes initializing NJORequiredCharacterRule easy. 29 | public enum RequiredCharacterRulePreset { 30 | /// Password should contain at least one lowercase character. 31 | case lowercaseCharacter 32 | /// Password should contain at least one uppercase character. 33 | case uppercaseCharacter 34 | /// Password should contain at least one decimal digit character. 35 | case decimalDigitCharacter 36 | /// Password should contain at least one symbol character. 37 | case symbolCharacter 38 | } 39 | 40 | /// RequiredCharacterRule checks if the password contains at least one required character. 41 | open class RequiredCharacterRule: PasswordRule { 42 | 43 | private var requiredCharacterSetToCompare: CharacterSet? 44 | 45 | open var requiredCharacterSet: CharacterSet? { 46 | didSet { 47 | setRequiredCharacterSet(fromCharacterSet: requiredCharacterSet) 48 | } 49 | } 50 | 51 | open var preset: RequiredCharacterRulePreset? { 52 | didSet { 53 | setRequiredCharacterSet(fromPreset: preset) 54 | } 55 | } 56 | 57 | /// Initialize with an CharacterSet object. 58 | public convenience init(requiredCharacterSet: CharacterSet) { 59 | self.init() 60 | self.requiredCharacterSet = requiredCharacterSet 61 | setRequiredCharacterSet(fromCharacterSet: requiredCharacterSet) 62 | } 63 | 64 | /// Initialize with an RequiredCharacterRulePreset. 65 | public convenience init(preset: RequiredCharacterRulePreset) { 66 | self.init() 67 | self.preset = preset 68 | setRequiredCharacterSet(fromPreset: preset) 69 | } 70 | 71 | private func setRequiredCharacterSet(fromCharacterSet characterSet: CharacterSet?) { 72 | guard let requiredCharacterSet = requiredCharacterSet else { 73 | return 74 | } 75 | 76 | preset = nil 77 | requiredCharacterSetToCompare = requiredCharacterSet 78 | } 79 | 80 | private func setRequiredCharacterSet(fromPreset preset: RequiredCharacterRulePreset?) { 81 | guard let preset = preset else { 82 | return 83 | } 84 | 85 | requiredCharacterSet = nil 86 | switch preset { 87 | case .lowercaseCharacter: 88 | requiredCharacterSetToCompare = CharacterSet.lowercaseLetters 89 | case .uppercaseCharacter: 90 | requiredCharacterSetToCompare = CharacterSet.uppercaseLetters 91 | case .decimalDigitCharacter: 92 | requiredCharacterSetToCompare = CharacterSet.decimalDigits 93 | case .symbolCharacter: 94 | var symbolCharacterSet = CharacterSet.symbols 95 | symbolCharacterSet.formUnion(CharacterSet.punctuationCharacters) 96 | requiredCharacterSetToCompare = symbolCharacterSet 97 | } 98 | } 99 | 100 | /// Evaluate password. Return false if it is passed and true if failed. 101 | open func evaluate(_ password: String) -> Bool { 102 | guard let requiredCharacterSetToCompare = requiredCharacterSetToCompare else { 103 | return false 104 | } 105 | return password.rangeOfCharacter(from: requiredCharacterSetToCompare) == nil 106 | } 107 | 108 | /// Error description. 109 | /// Localization keys 110 | /// - Lowercase error "NAVAJO_REQUIRED_CHARACTER_LOWERCASE_ERROR" 111 | /// - Uppercase error "NAVAJO_REQUIRED_CHARACTER_UPPERCASE_ERROR" 112 | /// - Decimal digit error "NAVAJO_REQUIRED_CHARACTER_DECIMAL_DIGIT_ERROR" 113 | /// - Symbol error "NAVAJO_REQUIRED_CHARACTER_SYMBOL_ERROR" 114 | /// - Default error "NAVAJO_REQUIRED_CHARACTER_REQUIRED_ERROR" 115 | open var localizedErrorDescription: String { 116 | guard let preset = preset else { 117 | return NSLocalizedString("NAVAJO_REQUIRED_CHARACTER_REQUIRED_ERROR", tableName: nil, bundle: Bundle.main, value: "Must include required characters", comment: "Navajo - Required character rule") 118 | } 119 | 120 | switch preset { 121 | case .lowercaseCharacter: 122 | return NSLocalizedString("NAVAJO_REQUIRED_CHARACTER_LOWERCASE_ERROR", tableName: nil, bundle: Bundle.main, value: "Must include lowercase characters", comment: "Navajo - Required lowercase character rule") 123 | case .uppercaseCharacter: 124 | return NSLocalizedString("NAVAJO_REQUIRED_CHARACTER_UPPERCASE_ERROR", tableName: nil, bundle: Bundle.main, value: "Must include uppercase characters", comment: "Navajo - Required uppercase character rule") 125 | case .decimalDigitCharacter: 126 | return NSLocalizedString("NAVAJO_REQUIRED_CHARACTER_DECIMAL_DIGIT_ERROR", tableName: nil, bundle: Bundle.main, value: "Must include decimal digit characters", comment: "Navajo - Required decimal digit character rule") 127 | case .symbolCharacter: 128 | return NSLocalizedString("NAVAJO_REQUIRED_CHARACTER_SYMBOL_ERROR", tableName: nil, bundle: Bundle.main, value: "Must include symbol characters", comment: "Navajo - Required symbol character rule") 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 6.5.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_IQKeyboardManagerSwift : NSObject 3 | @end 4 | @implementation PodsDummy_IQKeyboardManagerSwift 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double IQKeyboardManagerSwiftVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char IQKeyboardManagerSwiftVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.modulemap: -------------------------------------------------------------------------------- 1 | framework module IQKeyboardManagerSwift { 2 | umbrella header "IQKeyboardManagerSwift-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "Foundation" -framework "QuartzCore" -framework "UIKit" 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/IQKeyboardManagerSwift 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Navajo-Swift/Navajo-Swift-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 2.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Navajo-Swift/Navajo-Swift-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Navajo_Swift : NSObject 3 | @end 4 | @implementation PodsDummy_Navajo_Swift 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Navajo-Swift/Navajo-Swift-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Navajo-Swift/Navajo-Swift-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Navajo_SwiftVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Navajo_SwiftVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Navajo-Swift/Navajo-Swift.modulemap: -------------------------------------------------------------------------------- 1 | framework module Navajo_Swift { 2 | umbrella header "Navajo-Swift-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Navajo-Swift/Navajo-Swift.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Navajo-Swift 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Navajo-Swift 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Demo/Pods-Demo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Demo/Pods-Demo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## IQKeyboardManagerSwift 5 | 6 | MIT License 7 | 8 | Copyright (c) 2013-2017 Iftekhar Qurashi 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | 29 | ## Navajo-Swift 30 | 31 | Copyright (c) 2015-2016 Jason Nam (http://www.jasonnam.com) 32 | 33 | Permission is hereby granted, free of charge, to any person obtaining a copy 34 | of this software and associated documentation files (the "Software"), to deal 35 | in the Software without restriction, including without limitation the rights 36 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 37 | copies of the Software, and to permit persons to whom the Software is 38 | furnished to do so, subject to the following conditions: 39 | 40 | The above copyright notice and this permission notice shall be included in 41 | all copies or substantial portions of the Software. 42 | 43 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 44 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 45 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 46 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 47 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 48 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 49 | THE SOFTWARE. 50 | 51 | Generated by CocoaPods - https://cocoapods.org 52 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Demo/Pods-Demo-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | MIT License 18 | 19 | Copyright (c) 2013-2017 Iftekhar Qurashi 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | License 40 | MIT 41 | Title 42 | IQKeyboardManagerSwift 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | Copyright (c) 2015-2016 Jason Nam (http://www.jasonnam.com) 49 | 50 | Permission is hereby granted, free of charge, to any person obtaining a copy 51 | of this software and associated documentation files (the "Software"), to deal 52 | in the Software without restriction, including without limitation the rights 53 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 54 | copies of the Software, and to permit persons to whom the Software is 55 | furnished to do so, subject to the following conditions: 56 | 57 | The above copyright notice and this permission notice shall be included in 58 | all copies or substantial portions of the Software. 59 | 60 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 61 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 62 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 63 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 64 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 65 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 66 | THE SOFTWARE. 67 | 68 | License 69 | MIT 70 | Title 71 | Navajo-Swift 72 | Type 73 | PSGroupSpecifier 74 | 75 | 76 | FooterText 77 | Generated by CocoaPods - https://cocoapods.org 78 | Title 79 | 80 | Type 81 | PSGroupSpecifier 82 | 83 | 84 | StringsTable 85 | Acknowledgements 86 | Title 87 | Acknowledgements 88 | 89 | 90 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Demo/Pods-Demo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Demo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Demo 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Demo/Pods-Demo-frameworks-Debug-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-Demo/Pods-Demo-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework 3 | ${BUILT_PRODUCTS_DIR}/Navajo-Swift/Navajo_Swift.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Demo/Pods-Demo-frameworks-Debug-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework 2 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Navajo_Swift.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Demo/Pods-Demo-frameworks-Release-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-Demo/Pods-Demo-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework 3 | ${BUILT_PRODUCTS_DIR}/Navajo-Swift/Navajo_Swift.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Demo/Pods-Demo-frameworks-Release-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework 2 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Navajo_Swift.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Demo/Pods-Demo-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_DemoVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_DemoVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Demo/Pods-Demo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/Navajo-Swift" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Navajo-Swift/Navajo_Swift.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "Navajo_Swift" -framework "QuartzCore" -framework "UIKit" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Demo/Pods-Demo.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Demo { 2 | umbrella header "Pods-Demo-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-Demo/Pods-Demo.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/Navajo-Swift" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Navajo-Swift/Navajo_Swift.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "Navajo_Swift" -framework "QuartzCore" -framework "UIKit" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SwiftUI-Sample-App 2 | This swiftUI Demo is very simple & easy to understand. This swiftUI demo includes On-boarding screens, login screen, forgot password screen, sign up screen, home & logout.You can read more from [Medium](https://medium.com/mindful-engineering/getting-started-with-swiftui-c5b985a0211b) 3 | 4 | ![video](/Media/SwiftUI-Sample-App.gif) 5 | 6 | # Description 7 | 8 | In the onboard view, we used the page control with view controller and also put the next button to jump the LoginUI. 9 | 10 | In the login view, user need to enter the credentials (Email & Password) and after completion of validation it successfully logged in it will save in user defaults. 11 | 12 | In the Forgot password view, user need to enter Email and after completion of validation of email it will successfully dismiss. 13 | 14 | In the Sign Up view, user need to enter user data (First Name, Last Name, Email, Contact No, Date of Birth, Password & Confirm Password ) and after completion of validation it will successfully dismiss. 15 | 16 | In the Home view, user will get 2 tabs like (Home & Favourites). 17 | In the Home tab, user will get scrollable list & collection. 18 | In the favourites tab, user will get segments, login using combine framework, picker & user can also logout. 19 | 20 | # Table of Contents 21 | 22 | - OnBoarding UI - Created onboarding UI, using view controllers & page control 23 | - Login UI - It will validate login credentials, after successfully login it will save data in user defaults. 24 | - Forgot Password UI - presented forgot password UI, using presentation mode and also validate an email. 25 | - Sign UP UI - It will also validate with all user data, 26 | - Tab bar (Home & favourites ) 27 | - Logout 28 | 29 | # UI controls 30 | - Page controller (using view controllers) 31 | - Picker 32 | - Scrollview 33 | - Navigation View 34 | - VStack, HStack, Zstack 35 | - List 36 | - Collection 37 | - Tabbar 38 | - Image 39 | - Text 40 | - Alert 41 | - TextField 42 | - SecureTextField 43 | - Buttons (Action & Navigation) 44 | 45 | 46 | # By Apple 47 | 48 | Xcode 11.1 49 | iOS 13 50 | iPadOs 13 51 | 52 | # Documentation 53 | SwiftUI - https://developer.apple.com/xcode/swiftui/ 54 | 55 | # Tutorials 56 | - Ray wenderlich 57 | - Hacking with Swift 58 | 59 | # LICENSE! 60 | 61 | SwiftUI-Sample-App is [MIT-licensed](/LICENSE). 62 | 63 | # Conclusion 64 | While there’s still a ton of information left to be discovered about SwiftUI.I hope this article has cleared up some of the major question marks. I’ll keep digging, and will report all of my new findings as soon as possible. 65 | 66 | --------------------------------------------------------------------------------