├── .gitignore ├── GenerateDynamicCustomForm.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcuserdata │ └── mind-288.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── GenerateDynamicCustomForm.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ └── WorkspaceSettings.xcsettings ├── GenerateDynamicCustomForm ├── AppDelegate │ ├── AppDelegate.swift │ └── SceneDelegate.swift ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── ic_add.imageset │ │ ├── Contents.json │ │ └── ic_add.png │ ├── ic_banner.imageset │ │ ├── Contents.json │ │ └── ic_banner.jpg │ ├── ic_check.imageset │ │ ├── Contents.json │ │ └── ic_check copy.png │ ├── ic_eye_close.imageset │ │ ├── Contents.json │ │ └── ic_eye_close.png │ ├── ic_eye_open.imageset │ │ ├── Contents.json │ │ └── ic_eye_open.png │ ├── ic_remove4.imageset │ │ ├── Contents.json │ │ └── ic_remove4.png │ ├── ic_uncheck.imageset │ │ ├── Contents.json │ │ └── ic_uncheck copy.png │ └── ic_user3.imageset │ │ ├── Contents.json │ │ └── ic_user3.png ├── Classes │ ├── Form │ │ ├── FormVC.swift │ │ ├── MultiSelectionView │ │ │ ├── MultiSelectionVC.swift │ │ │ └── TableMultiSelection │ │ │ │ └── TableViewCells │ │ │ │ ├── SelectionCell.swift │ │ │ │ ├── SelectionCell.xib │ │ │ │ └── TblMultiSelection.swift │ │ └── TableFormView │ │ │ ├── FooterView │ │ │ ├── FooterView.swift │ │ │ └── FooterView.xib │ │ │ ├── TableViewCells │ │ │ ├── CheckBoxCell.swift │ │ │ ├── CheckBoxCell.xib │ │ │ ├── CollectionMultiplePhotoView │ │ │ │ ├── CollMultiplePhotos.swift │ │ │ │ └── CollPhotoCell │ │ │ │ │ ├── MultiPhotoCollCell.swift │ │ │ │ │ └── MultiPhotoCollCell.xib │ │ │ ├── InfoCell.swift │ │ │ ├── InfoCell.xib │ │ │ ├── MobileNumberCell.swift │ │ │ ├── MobileNumberCell.xib │ │ │ ├── MultiPhotoCell.swift │ │ │ ├── MultiPhotoCell.xib │ │ │ ├── ProfileCell.swift │ │ │ ├── ProfileCell.xib │ │ │ ├── SwitchCell.swift │ │ │ ├── SwitchCell.xib │ │ │ ├── TextViewCell.swift │ │ │ └── TextViewCell.xib │ │ │ └── TblFormView.swift │ ├── Home │ │ └── HomeVC.swift │ └── List │ │ ├── ListVC.swift │ │ └── TableView │ │ ├── ListCell.swift │ │ ├── ListCell.xib │ │ └── TblUserList.swift ├── Info.plist ├── Model │ └── Model.swift ├── Storyboard │ └── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard └── Support │ ├── Constants.swift │ ├── ExtensionUITextField.swift │ ├── ExtensionUITextView.swift │ ├── ExtensionsUIView.swift │ ├── MediaManager.swift │ ├── TabelView+CollectionViewExtension.swift │ ├── UIButton+Extension.swift │ └── UIViewController+Alert.swift ├── LICENSE ├── Media ├── form.gif └── mi.png ├── 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 │ ├── LICENSE.md │ └── README.md ├── Manifest.lock ├── Pods.xcodeproj │ └── project.pbxproj └── Target Support Files │ ├── IQKeyboardManagerSwift │ ├── IQKeyboardManagerSwift-Info.plist │ ├── IQKeyboardManagerSwift-dummy.m │ ├── IQKeyboardManagerSwift-prefix.pch │ ├── IQKeyboardManagerSwift-umbrella.h │ ├── IQKeyboardManagerSwift.debug.xcconfig │ ├── IQKeyboardManagerSwift.modulemap │ └── IQKeyboardManagerSwift.release.xcconfig │ └── Pods-GenerateDynamicCustomForm │ ├── Pods-GenerateDynamicCustomForm-Info.plist │ ├── Pods-GenerateDynamicCustomForm-acknowledgements.markdown │ ├── Pods-GenerateDynamicCustomForm-acknowledgements.plist │ ├── Pods-GenerateDynamicCustomForm-dummy.m │ ├── Pods-GenerateDynamicCustomForm-frameworks-Debug-input-files.xcfilelist │ ├── Pods-GenerateDynamicCustomForm-frameworks-Debug-output-files.xcfilelist │ ├── Pods-GenerateDynamicCustomForm-frameworks-Release-input-files.xcfilelist │ ├── Pods-GenerateDynamicCustomForm-frameworks-Release-output-files.xcfilelist │ ├── Pods-GenerateDynamicCustomForm-frameworks.sh │ ├── Pods-GenerateDynamicCustomForm-umbrella.h │ ├── Pods-GenerateDynamicCustomForm.debug.xcconfig │ ├── Pods-GenerateDynamicCustomForm.modulemap │ └── Pods-GenerateDynamicCustomForm.release.xcconfig └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm.xcodeproj/xcuserdata/mind-288.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | GenerateDynamicCustomForm.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 2 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/AppDelegate/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CommonLRF 4 | // 5 | // Created by mac-00015 on 03/03/21. 6 | // 7 | 8 | import UIKit 9 | import IQKeyboardManagerSwift 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | // Override point for customization after application launch. 18 | 19 | IQKeyboardManager.shared.enable = true 20 | 21 | return true 22 | } 23 | 24 | func applicationWillResignActive(_ application: UIApplication) { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | func applicationDidEnterBackground(_ application: UIApplication) { 30 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 31 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 32 | } 33 | 34 | func applicationWillEnterForeground(_ application: UIApplication) { 35 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 36 | } 37 | 38 | func applicationDidBecomeActive(_ application: UIApplication) { 39 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 40 | } 41 | 42 | func applicationWillTerminate(_ application: UIApplication) { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/AppDelegate/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // Press ME! 4 | // 5 | // Created by mac-00022 on 12/7/20. 6 | // 7 | 8 | import UIKit 9 | 10 | @available(iOS 13.0, *) 11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 12 | 13 | var window: UIWindow? 14 | 15 | 16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 20 | guard let _ = (scene as? UIWindowScene) else { return } 21 | } 22 | 23 | func sceneDidDisconnect(_ scene: UIScene) { 24 | // Called as the scene is being released by the system. 25 | // This occurs shortly after the scene enters the background, or when its session is discarded. 26 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 27 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 28 | } 29 | 30 | func sceneDidBecomeActive(_ scene: UIScene) { 31 | // Called when the scene has moved from an inactive state to an active state. 32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 33 | } 34 | 35 | func sceneWillResignActive(_ scene: UIScene) { 36 | // Called when the scene will move from an active state to an inactive state. 37 | // This may occur due to temporary interruptions (ex. an incoming phone call). 38 | } 39 | 40 | func sceneWillEnterForeground(_ scene: UIScene) { 41 | // Called as the scene transitions from the background to the foreground. 42 | // Use this method to undo the changes made on entering the background. 43 | } 44 | 45 | func sceneDidEnterBackground(_ scene: UIScene) { 46 | // Called as the scene transitions from the foreground to the background. 47 | // Use this method to save data, release shared resources, and store enough scene-specific state information 48 | // to restore the scene back to its current state. 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_add.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_add.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_add.imageset/ic_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/GenerateDynamicCustomForm/0c53e6087c718f9663dc6884dbb0f758d15d3177/GenerateDynamicCustomForm/Assets.xcassets/ic_add.imageset/ic_add.png -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_banner.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_banner.jpg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_banner.imageset/ic_banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/GenerateDynamicCustomForm/0c53e6087c718f9663dc6884dbb0f758d15d3177/GenerateDynamicCustomForm/Assets.xcassets/ic_banner.imageset/ic_banner.jpg -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_check.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_check copy.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_check.imageset/ic_check copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/GenerateDynamicCustomForm/0c53e6087c718f9663dc6884dbb0f758d15d3177/GenerateDynamicCustomForm/Assets.xcassets/ic_check.imageset/ic_check copy.png -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_eye_close.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_eye_close.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_eye_close.imageset/ic_eye_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/GenerateDynamicCustomForm/0c53e6087c718f9663dc6884dbb0f758d15d3177/GenerateDynamicCustomForm/Assets.xcassets/ic_eye_close.imageset/ic_eye_close.png -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_eye_open.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_eye_open.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_eye_open.imageset/ic_eye_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/GenerateDynamicCustomForm/0c53e6087c718f9663dc6884dbb0f758d15d3177/GenerateDynamicCustomForm/Assets.xcassets/ic_eye_open.imageset/ic_eye_open.png -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_remove4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_remove4.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_remove4.imageset/ic_remove4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/GenerateDynamicCustomForm/0c53e6087c718f9663dc6884dbb0f758d15d3177/GenerateDynamicCustomForm/Assets.xcassets/ic_remove4.imageset/ic_remove4.png -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_uncheck.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_uncheck copy.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_uncheck.imageset/ic_uncheck copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/GenerateDynamicCustomForm/0c53e6087c718f9663dc6884dbb0f758d15d3177/GenerateDynamicCustomForm/Assets.xcassets/ic_uncheck.imageset/ic_uncheck copy.png -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_user3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "ic_user3.png", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Assets.xcassets/ic_user3.imageset/ic_user3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/GenerateDynamicCustomForm/0c53e6087c718f9663dc6884dbb0f758d15d3177/GenerateDynamicCustomForm/Assets.xcassets/ic_user3.imageset/ic_user3.png -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/FormVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // CommonLRF 4 | // 5 | // Created by mac-00015 on 03/03/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class FormVC: UIViewController { 11 | 12 | @IBOutlet weak private var tblFormView: TblFormView! 13 | 14 | var txtFieldData = [[FormModel]]() 15 | var userImage = [ProfileImageModel]() 16 | var userisChecked = [CheckBoxModel]() 17 | var userSwitchValue = [SwitchModel]() 18 | var userMultiPhoto = [MultiPhotoModel]() 19 | 20 | var isFromHome = false 21 | var isFromEdit = false 22 | var index = 0 23 | 24 | private var country = "" 25 | private var hobbies = [String]() 26 | 27 | override func viewDidLoad() { 28 | super.viewDidLoad() 29 | 30 | initialize() 31 | } 32 | 33 | deinit { 34 | print("FormVC is deinitialized") 35 | } 36 | } 37 | 38 | //MARK:- Initialize 39 | //MARK:- 40 | 41 | extension FormVC { 42 | 43 | private func initialize() { 44 | 45 | title = "Form" 46 | navigationController?.navigationBar.topItem?.title = "" 47 | 48 | if isFromEdit { 49 | 50 | tblFormView.userData = txtFieldData 51 | tblFormView.txtFieldModel = txtFieldData[index] 52 | tblFormView.userImage = userImage 53 | tblFormView.userisChecked = userisChecked 54 | tblFormView.userSwitchValue = userSwitchValue 55 | tblFormView.userMultiPhoto = userMultiPhoto 56 | tblFormView.index = index 57 | 58 | } else { 59 | 60 | if isFromHome { 61 | 62 | tblFormView.userData = txtFieldData 63 | tblFormView.userImage = userImage 64 | tblFormView.userisChecked = userisChecked 65 | tblFormView.userSwitchValue = userSwitchValue 66 | tblFormView.userMultiPhoto = userMultiPhoto 67 | } 68 | 69 | tblFormView.txtFieldModel = [ 70 | 71 | FormModel(controlType: .profileImage), // Profile Image 72 | 73 | FormModel(controlType: .textField, txtFieldType: .normal, value: "", placeHolder: placeHolderName, placeHolder2: "John Doe", placeHolderColor: .darkGray, leftImgView: "ic_user", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Name 74 | 75 | FormModel(controlType: .textField, txtFieldType: .normal, value: "", placeHolder: placeHolderEmail, placeHolder2: "name@example.com", placeHolderColor: .darkGray, leftImgView: "ic_email", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .emailAddress, isValid: true), // Email 76 | 77 | FormModel(controlType: .textField, txtFieldType: .password, value: "", placeHolder: placeHolderPassword, placeHolder2: "*******", placeHolderColor: .darkGray, leftImgView: "ic_password", rightImgView: nil, isEnabled: true, isSecure: true, keyboardType: .default, isValid: true), // Password 78 | 79 | FormModel(controlType: .textField, txtFieldType: .mobileNumber(false), value: "", placeHolder: placeHolderMobNo, placeHolder2: "1234567890", placeHolderColor: .darkGray, leftImgView: nil, rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .phonePad, isValid: true), // Mobile number 80 | 81 | FormModel(controlType: .textView, value: "", placeHolder: placeHolderAddress, placeHolder2: "21, Satelite Shopping Centre.", placeHolderColor: .darkGray, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Address (TextView) 82 | 83 | FormModel(controlType: .textField, txtFieldType: .dob, value: "", placeHolder: placeHolderDob, placeHolder2: "DD/MM/YYYY", placeHolderColor: .darkGray, leftImgView: "ic_calender", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Date of Birth (Date Picker) 84 | 85 | FormModel(controlType: .textField, txtFieldType: .actionSheet, value: "", placeHolder: placeHolderGender, placeHolder2: "Select Male or Female", placeHolderColor: .darkGray, leftImgView: "ic_gender", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Gender (Action Sheet) 86 | 87 | FormModel(controlType: .textField, txtFieldType: .selection(false), value: "", placeHolder: placeHolderCountry, placeHolder2: "Select Conutry", placeHolderColor: .darkGray, leftImgView: "ic_flag", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Countries India or Other 88 | 89 | FormModel(controlType: .textField, txtFieldType: .selection(true), value: "", placeHolder: placeHolderHobbies, placeHolder2: "Select Hobbies", placeHolderColor: .darkGray, leftImgView: "ic_food", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Hobbies (Multiple Selection View) 90 | 91 | FormModel(controlType: .textField,txtFieldType: .picker, value: "", placeHolder: placeHolderDept, placeHolder2: "Select Department", placeHolderColor: .darkGray, leftImgView: "ic_dept", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Department (Picker) 92 | 93 | FormModel(controlType: .multiPhoto), // Multiple Photos 94 | 95 | FormModel(controlType: .switchType), // Notifications (Switch) 96 | 97 | FormModel(controlType: .checkBox) // Terms and Conditions (CheckBox) 98 | ] 99 | } 100 | 101 | tblFormView.userDataHandler = { [weak self] (userData, userImage, userIsChecked, userSwitchValue, userMultiPhoto) in 102 | 103 | guard let `self` = self else { return } 104 | 105 | if let homeVC = self.navigationController?.viewControllers.first as? HomeVC { 106 | 107 | homeVC.userData = userData 108 | homeVC.userImage = userImage 109 | homeVC.userisChecked = userIsChecked 110 | homeVC.userSwitchValue = userSwitchValue 111 | homeVC.userMultiPhoto = userMultiPhoto 112 | } 113 | } 114 | 115 | tblFormView.isFromEdit = isFromEdit 116 | tblFormView.pickerData = ["iOS", "Android", "Web", "Design", "Sales", "HR"] 117 | tblFormView.cntryCode = ["+91","+1 340","+299","+39","+44","+598","+64"] 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/MultiSelectionView/MultiSelectionVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MultiSelectionVC.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/12/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class MultiSelectionVC: UIViewController { 11 | 12 | @IBOutlet weak private var btnDone: UIButton! 13 | @IBOutlet weak private var vwBackground: UIView! 14 | @IBOutlet weak private var tblMultiSelection: TblMultiSelection! 15 | 16 | private var isMultipleSelection = false 17 | private var country = "" 18 | private var hobbies = [String]() 19 | 20 | static var hobbiesDataHandler: ((_ hobbiesdata: [String]) -> Void)? 21 | static var countryDataHandler: ((_ countrydata: String) -> Void)? 22 | 23 | override func viewDidLoad() { 24 | super.viewDidLoad() 25 | 26 | initialize() 27 | } 28 | 29 | deinit { 30 | print("MultiSelectionVC is deinitialized") 31 | } 32 | } 33 | 34 | //MARK:- Initialize 35 | //MARK:- 36 | extension MultiSelectionVC { 37 | 38 | private func initialize() { 39 | 40 | view.backgroundColor = UIColor.black.withAlphaComponent(0.50) 41 | btnDone.shadow(color: .black, shadowOffset: CGSize(width: 5.0, height: 5.0), shadowRadius: 10.0, shadowOpacity: 0.5) 42 | tblMultiSelection.hobbies = ["Movies", "Cricket", "Music", "Food", "Dance", "Game", "Travel"] 43 | tblMultiSelection.countries = ["India", "Other"] 44 | tblMultiSelection.isMultipleSelection = isMultipleSelection 45 | 46 | tblMultiSelection.countryDataHandler = { [weak self] value in 47 | 48 | guard let `self` = self else { return } 49 | self.country = value 50 | } 51 | 52 | tblMultiSelection.hobbiesDataHandler = { [weak self] value in 53 | 54 | guard let `self` = self else { return } 55 | self.hobbies = value 56 | } 57 | } 58 | 59 | static func showPopup(parentVC: UIViewController, isMultiple: Bool) { 60 | 61 | if let popUPMutliSelection = CMainStoryboard.instantiateViewController(withIdentifier: MultiSelectionVC.storyboardID) as? MultiSelectionVC { 62 | 63 | popUPMutliSelection.isMultipleSelection = isMultiple 64 | popUPMutliSelection.modalPresentationStyle = .custom 65 | popUPMutliSelection.modalTransitionStyle = .crossDissolve 66 | parentVC.present(popUPMutliSelection, animated: true) 67 | } 68 | } 69 | } 70 | 71 | //MARK:- Action 72 | //MARK:- 73 | extension MultiSelectionVC { 74 | 75 | @IBAction func onDone(_ sender: UIButton) { 76 | 77 | tblMultiSelection.getMultiSelectedData() 78 | 79 | if isMultipleSelection { 80 | MultiSelectionVC.hobbiesDataHandler?(hobbies) 81 | } else { 82 | MultiSelectionVC.countryDataHandler?(country) 83 | } 84 | self.dismiss(animated: true, completion: nil) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/MultiSelectionView/TableMultiSelection/TableViewCells/SelectionCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SelectionCell.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/12/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class SelectionCell: UITableViewCell { 11 | 12 | @IBOutlet weak private var lblSelection: UILabel! 13 | 14 | override func awakeFromNib() { 15 | super.awakeFromNib() 16 | 17 | } 18 | } 19 | 20 | //MARK:- ConfigureCell 21 | //MARK:- 22 | extension SelectionCell { 23 | 24 | func configureCell(data: String, isMulti: Bool, index: Int) { 25 | 26 | lblSelection.text = data 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/MultiSelectionView/TableMultiSelection/TableViewCells/SelectionCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/MultiSelectionView/TableMultiSelection/TableViewCells/TblMultiSelection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TblMultiSelection.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/12/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class TblMultiSelection: UITableView { 11 | 12 | var hobbies = [String]() 13 | var countries = [String]() 14 | var hobbiesData = [String]() 15 | var country = "" 16 | var isMultipleSelection = false 17 | 18 | private var selectedIndex = -1 19 | 20 | var hobbiesDataHandler: ((_ hobbiesdata: [String]) -> Void)? 21 | var countryDataHandler: ((_ countrydata: String) -> Void)? 22 | 23 | override func awakeFromNib() { 24 | super.awakeFromNib() 25 | 26 | initialize() 27 | } 28 | 29 | deinit { 30 | print("TblMultiSelection is deinitialized") 31 | } 32 | } 33 | 34 | //MARK:- Initialize 35 | //MARK:- 36 | extension TblMultiSelection { 37 | 38 | private func initialize() { 39 | 40 | dataSource = self 41 | delegate = self 42 | register(SelectionCell.nib, forCellReuseIdentifier: SelectionCell.identifier) 43 | } 44 | } 45 | 46 | //MARK:- UITableView Datasource and Delegate 47 | //MARK:- 48 | extension TblMultiSelection: UITableViewDataSource, UITableViewDelegate { 49 | 50 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 51 | 52 | allowsMultipleSelection = isMultipleSelection 53 | return isMultipleSelection ? hobbies.count : countries.count 54 | } 55 | 56 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 57 | 58 | if let selectionCell = tableView.dequeueReusableCell(withIdentifier: SelectionCell.identifier) as? SelectionCell { 59 | 60 | if !isMultipleSelection { 61 | 62 | if indexPath.row == selectedIndex { 63 | selectionCell.accessoryType = .checkmark 64 | } else { 65 | selectionCell.accessoryType = .none 66 | } 67 | 68 | } else { 69 | 70 | if let _ = tableView.indexPathsForSelectedRows?.firstIndex(of: indexPath) { 71 | selectionCell.accessoryType = .checkmark 72 | } else { 73 | selectionCell.accessoryType = .none 74 | } 75 | } 76 | 77 | selectionCell.configureCell(data: isMultipleSelection ? hobbies[indexPath.row] : countries[indexPath.row], isMulti: isMultipleSelection, index: indexPath.row) 78 | 79 | return selectionCell 80 | } 81 | return UITableViewCell() 82 | } 83 | 84 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 85 | 86 | guard let cell = cellForRow(at: indexPath) else { return } 87 | 88 | cell.accessoryType = .checkmark 89 | 90 | if !isMultipleSelection { 91 | 92 | selectedIndex = indexPath.row 93 | let country = countries[selectedIndex] 94 | print(country) 95 | countryDataHandler?(country) 96 | } 97 | } 98 | 99 | func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { 100 | 101 | guard let cell = cellForRow(at: indexPath) else { return } 102 | cell.accessoryType = .none 103 | } 104 | } 105 | 106 | //MARK:- Get Selected Hobbies 107 | //MARK:- 108 | 109 | extension TblMultiSelection { 110 | 111 | func getMultiSelectedData() { 112 | 113 | if isMultipleSelection { 114 | 115 | guard let selectedIndexPath = indexPathsForSelectedRows else { return } 116 | 117 | for indexpath in selectedIndexPath { 118 | hobbiesData.append(hobbies[indexpath.row]) 119 | } 120 | hobbiesDataHandler?(hobbiesData) 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/FooterView/FooterView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FooterView.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/9/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class FooterView: UITableViewHeaderFooterView { 11 | 12 | @IBOutlet weak var btnSubmit: UIButton! 13 | } 14 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/FooterView/FooterView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/TableViewCells/CheckBoxCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CheckBoxCell.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/5/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class CheckBoxCell: UITableViewCell { 11 | 12 | @IBOutlet weak private var btnCheck: UIButton! 13 | 14 | var checkBoxCheckedHandler: ((_ checked: Bool) -> Void)? 15 | 16 | deinit { 17 | print("CheckBoxCell is deinitialized") 18 | } 19 | } 20 | 21 | //MARK:- Initialize 22 | //MARK:- 23 | extension CheckBoxCell { 24 | 25 | func configureCell(isChecked: Bool) { 26 | 27 | btnCheck.isSelected = isChecked 28 | btnCheck.setImage(UIImage(named: "ic_check"), for: .normal) 29 | 30 | } 31 | } 32 | 33 | //MARK:- Action 34 | //MARK:- 35 | extension CheckBoxCell { 36 | 37 | @IBAction private func onCheck(_ sender: UIButton) { 38 | 39 | if sender.isSelected { 40 | 41 | btnCheck.setImage(UIImage(named: "ic_uncheck"), for: .normal) 42 | sender.isSelected.toggle() 43 | if checkBoxCheckedHandler != nil { 44 | checkBoxCheckedHandler?(false) 45 | } 46 | 47 | } else { 48 | 49 | btnCheck.setImage(UIImage(named: "ic_check"), for: .normal) 50 | sender.isSelected.toggle() 51 | if checkBoxCheckedHandler != nil { 52 | checkBoxCheckedHandler?(true) 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/TableViewCells/CheckBoxCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/TableViewCells/CollectionMultiplePhotoView/CollMultiplePhotos.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollMultiplePhotos.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/16/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class CollMultiplePhotos: UICollectionView { 11 | 12 | var multiImages = [UIImage]() { 13 | didSet { 14 | reloadData() 15 | } 16 | } 17 | 18 | // Completion Handler For UIImage's Value Changed 19 | var multiImgRemovalHandler: ((_ images: [UIImage]) -> Void)? 20 | 21 | override func awakeFromNib() { 22 | super.awakeFromNib() 23 | 24 | initialize() 25 | } 26 | } 27 | 28 | //MARK:- Initialize 29 | //MARK:- 30 | extension CollMultiplePhotos { 31 | 32 | private func initialize() { 33 | 34 | dataSource = self 35 | delegate = self 36 | register(MultiPhotoCollCell.nib, forCellWithReuseIdentifier: MultiPhotoCollCell.identifier) 37 | } 38 | } 39 | 40 | //MARK:- Initialize 41 | //MARK:- 42 | extension CollMultiplePhotos: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { 43 | 44 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 45 | 46 | return multiImages.count 47 | } 48 | 49 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 50 | 51 | if let multiPhotoCollCell = collectionView.dequeueReusableCell(withReuseIdentifier: MultiPhotoCollCell.identifier, for: indexPath) as? MultiPhotoCollCell { 52 | 53 | multiPhotoCollCell.configureCell(image: multiImages[indexPath.row]) 54 | 55 | multiPhotoCollCell.btnRemove.touchUpInside { [weak self] sender in 56 | 57 | guard let `self` = self else { return } 58 | self.multiImages.remove(at: indexPath.row) 59 | self.reloadData() 60 | self.multiImgRemovalHandler?(self.multiImages) 61 | } 62 | 63 | return multiPhotoCollCell 64 | } 65 | return UICollectionViewCell() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/TableViewCells/CollectionMultiplePhotoView/CollPhotoCell/MultiPhotoCollCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MultiPhotoCollCell.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/16/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class MultiPhotoCollCell: UICollectionViewCell { 11 | 12 | @IBOutlet weak var btnRemove: UIButton! 13 | @IBOutlet weak private var imgPhotos: UIImageView! 14 | 15 | override func awakeFromNib() { 16 | super.awakeFromNib() 17 | 18 | initialize() 19 | } 20 | } 21 | 22 | //MARK:- Configure Cell 23 | //MARK:- 24 | extension MultiPhotoCollCell { 25 | 26 | private func initialize() { 27 | 28 | CGCDMainThread.async { [weak self] in 29 | 30 | guard let `self` = self else { return } 31 | self.btnRemove.roundView() 32 | } 33 | } 34 | 35 | func configureCell(image: UIImage?) { 36 | 37 | imgPhotos.image = image 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/TableViewCells/CollectionMultiplePhotoView/CollPhotoCell/MultiPhotoCollCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/TableViewCells/InfoCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InfoCell.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/5/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class InfoCell: UITableViewCell { 11 | 12 | @IBOutlet weak private var vwLine: UIView! 13 | @IBOutlet weak private var lblPlaceHolder: UILabel! 14 | @IBOutlet weak private var btnSelection: UIButton! 15 | @IBOutlet weak private var btnPassword: UIButton! 16 | @IBOutlet weak private var txtField: UITextField! 17 | 18 | var isValidate: Bool? 19 | var plcHolder = "" 20 | 21 | override func awakeFromNib() { 22 | super.awakeFromNib() 23 | 24 | } 25 | 26 | var controlType = TextFieldType.normal 27 | 28 | // Completion Handler For TextField's Value Changed 29 | var txtFieldValueHandler: ((_ txtField: UITextField) -> Void)? 30 | var txtFieldValidateHandler: ((_ isValid: Bool) -> Void)? 31 | 32 | deinit { 33 | print("InfoCell is deinitialized") 34 | } 35 | } 36 | 37 | //MARK:- Configure Cell 38 | //MARK:- 39 | extension InfoCell { 40 | 41 | // Configure Cell According to TextField Type 42 | func configureCell(data: FormModel, pickerData: [String]) { 43 | 44 | controlType = data.txtFieldType ?? .normal 45 | plcHolder = data.placeHolder ?? "" 46 | btnPassword.isHidden = true 47 | btnSelection.isHidden = true 48 | txtField.placeholder = data.placeHolder2 49 | txtField.keyboardType = data.keyboardType ?? .default 50 | txtField.isSecureTextEntry = data.isSecure ?? false 51 | txtField.inputView = nil 52 | //txtField.setupLeftImageView(img: UIImage(named: data.leftImgView ?? "")) 53 | 54 | if data.isValid ?? true { 55 | 56 | txtField.text = data.value 57 | lblPlaceHolder.text = data.placeHolder 58 | lblPlaceHolder.textColor = data.placeHolderColor 59 | 60 | } else { 61 | 62 | if txtField.keyboardType == .emailAddress { 63 | 64 | txtField.text = "" 65 | self.lblPlaceHolder.text = "Please Enter Valid Email*" 66 | self.lblPlaceHolder.textColor = UIColor.red 67 | 68 | } else { 69 | self.lblPlaceHolder.text = "Please Enter \(plcHolder)" 70 | self.lblPlaceHolder.textColor = UIColor.red 71 | } 72 | } 73 | 74 | switch data.txtFieldType { 75 | 76 | case .password: 77 | 78 | btnPassword.isHidden = false 79 | 80 | case .dob: 81 | 82 | if #available(iOS 13.4, *) { 83 | txtField.setDatePickerStyle() 84 | } 85 | 86 | txtField.setDatePickerMode(mode: .date) 87 | txtField.setMaximumDate(maxDate: Date()) 88 | 89 | txtField.setDatePickerWithDateFormate(dateFormate: "dd/MM/yyyy", defaultDate: Date(), isPrefilledDate: true, selectedDateHandler: { date in 90 | }) 91 | 92 | case .picker: 93 | 94 | txtField.setPickerData(arrPickerData: pickerData, pickerDataHandler: { [weak self] (select, index, component) in 95 | guard let `self` = self else { return } 96 | self.txtField.text = select as? String 97 | }) 98 | 99 | case .actionSheet, .selection(_): 100 | 101 | btnSelection.isHidden = false 102 | 103 | default: 104 | break 105 | } 106 | } 107 | } 108 | 109 | //MARK:- Action 110 | //MARK:- 111 | extension InfoCell { 112 | 113 | @IBAction func onTxtFieldValueChanged(_ sender: UITextField) { 114 | 115 | if txtField.text == "" && txtField.keyboardType != .emailAddress { 116 | 117 | lblPlaceHolder.text = "Please Enter \(plcHolder)" 118 | lblPlaceHolder.textColor = UIColor.red 119 | isValidate = false 120 | txtFieldValidateHandler?(isValidate ?? false) 121 | txtField.shake() 122 | 123 | } else { 124 | 125 | if txtField.keyboardType == .emailAddress { 126 | 127 | guard let txtEmail = txtField.text else { return } 128 | 129 | if txtEmail.isValidEmail == false { 130 | 131 | txtField.text = "" 132 | lblPlaceHolder.text = "Please Enter Valid Email*" 133 | lblPlaceHolder.textColor = UIColor.red 134 | isValidate = false 135 | txtFieldValidateHandler?(isValidate ?? false) 136 | txtField.shake() 137 | 138 | } else { 139 | 140 | lblPlaceHolder.text = plcHolder 141 | lblPlaceHolder.textColor = UIColor.darkGray 142 | if txtFieldValueHandler != nil { 143 | txtFieldValueHandler?(txtField) 144 | } 145 | isValidate = true 146 | txtFieldValidateHandler?(isValidate ?? true) 147 | } 148 | 149 | } else { 150 | 151 | isValidate = true 152 | lblPlaceHolder.text = plcHolder 153 | lblPlaceHolder.textColor = UIColor.darkGray 154 | if txtFieldValueHandler != nil { 155 | txtFieldValueHandler?(txtField) 156 | } 157 | txtFieldValidateHandler?(isValidate ?? true) 158 | } 159 | } 160 | } 161 | 162 | @IBAction private func onPassword(_ sender: UIButton) { 163 | 164 | if !sender.isSelected { 165 | 166 | btnPassword.setImage(UIImage(named: "ic_eye_open"), for: .normal) 167 | txtField.isSecureTextEntry = false 168 | sender.isSelected.toggle() 169 | 170 | } else { 171 | 172 | btnPassword.setImage(UIImage(named: "ic_eye_close"), for: .normal) 173 | txtField.isSecureTextEntry = true 174 | sender.isSelected.toggle() 175 | } 176 | } 177 | 178 | @IBAction func onSelection(_ sender: UIButton) { 179 | 180 | switch controlType { 181 | 182 | case .actionSheet: 183 | 184 | self.parentContainerViewController()?.alertView(title: "Select Gender", message: "", style: .actionSheet, actions: [.Custom(title: "Male"), .Custom(title: "Female"), .Cancel], handler: { [weak self] action in 185 | 186 | guard let `self` = self else { return } 187 | 188 | if action.title != "Cancel" { 189 | 190 | self.txtField.text = action.title 191 | 192 | if self.txtFieldValueHandler != nil { 193 | self.txtFieldValueHandler?(self.txtField) 194 | } 195 | } 196 | }) 197 | 198 | case .selection(let selection): 199 | 200 | MultiSelectionVC.showPopup(parentVC: self.parentContainerViewController() ?? UIViewController(), isMultiple: selection ?? false) 201 | 202 | guard let multi = selection else { return } 203 | 204 | if multi { 205 | 206 | MultiSelectionVC.hobbiesDataHandler = { [weak self] hobbies in 207 | 208 | guard let `self` = self else { return } 209 | self.txtField.text = hobbies.joined(separator: ", ") 210 | 211 | if self.txtFieldValueHandler != nil { 212 | self.txtFieldValueHandler?(self.txtField) 213 | } 214 | } 215 | } else { 216 | 217 | MultiSelectionVC.countryDataHandler = { [weak self] country in 218 | 219 | guard let `self` = self else { return } 220 | self.txtField.text = country 221 | 222 | if self.txtFieldValueHandler != nil { 223 | self.txtFieldValueHandler?(self.txtField) 224 | } 225 | } 226 | } 227 | 228 | default: 229 | break 230 | } 231 | } 232 | } 233 | 234 | //MARK:- Check Valid Email Address 235 | //MARK:- 236 | 237 | extension String { 238 | 239 | var isValidEmail: Bool { 240 | 241 | let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}" 242 | 243 | let predicate = NSPredicate( 244 | format:"SELF MATCHES %@", 245 | emailRegEx 246 | ) 247 | 248 | return predicate.evaluate(with:self) 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/TableViewCells/MobileNumberCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MobileNumberCell.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/8/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class MobileNumberCell: UITableViewCell { 11 | 12 | @IBOutlet weak private var vwMobNoLine: UIView! 13 | @IBOutlet weak private var vwcntryLine: UIView! 14 | @IBOutlet weak private var lblPlaceHolder: UILabel! 15 | @IBOutlet weak private var txtCntryCode: UITextField! 16 | @IBOutlet weak private var txtMobNO: UITextField! 17 | 18 | // Completion Handler For TextField's Value Changed 19 | var CntryCodeHandler: ((_ txtField: UITextField) -> Void)? 20 | var txtMobNoHandler: ((_ txtField: UITextField) -> Void)? 21 | var txtMobNoValidateHandler: ((_ isValid: Bool) -> Void)? 22 | 23 | var cntryCode: String? 24 | var isValidate: Bool? 25 | 26 | override func awakeFromNib() { 27 | super.awakeFromNib() 28 | 29 | } 30 | 31 | deinit { 32 | print("MobileNumberCell is deinitialized") 33 | } 34 | } 35 | 36 | //MARK:- Configure Cell 37 | //MARK:- 38 | extension MobileNumberCell { 39 | 40 | func configureCell(data: FormModel, code: [String], flag: Bool) { 41 | 42 | if data.isValid ?? true { 43 | lblPlaceHolder.text = data.placeHolder 44 | lblPlaceHolder.textColor = data.placeHolderColor 45 | 46 | } else { 47 | lblPlaceHolder.text = "Please Enter Mobile Number *" 48 | lblPlaceHolder.textColor = UIColor.red 49 | } 50 | 51 | txtMobNO.placeholder = data.placeHolder2 52 | txtMobNO.text = data.value 53 | txtCntryCode.text = cntryCode ?? "+91" 54 | txtMobNO.keyboardType = data.keyboardType ?? .default 55 | 56 | txtCntryCode.setPickerData(arrPickerData: code, pickerDataHandler: { (select, index, component) in 57 | }) 58 | 59 | if flag == true { 60 | 61 | txtCntryCode.textAlignment = .right 62 | txtCntryCode.setupLeftImageView(img: UIImage(named: "ic_india")) 63 | } 64 | } 65 | } 66 | 67 | //MARK:- Action 68 | //MARK:- 69 | extension MobileNumberCell { 70 | 71 | @IBAction func onMobNoValueChanged(_ sender: UITextField) { 72 | 73 | if txtMobNO.text == "" { 74 | 75 | lblPlaceHolder.text = "Please Enter Mobile Number *" 76 | lblPlaceHolder.textColor = UIColor.red 77 | isValidate = false 78 | txtMobNoValidateHandler?(isValidate ?? false) 79 | txtMobNO.shake() 80 | 81 | } else if txtMobNO.text?.count != 10 { 82 | 83 | lblPlaceHolder.text = "Please Enter Valid Mobile Number *" 84 | lblPlaceHolder.textColor = UIColor.red 85 | isValidate = false 86 | txtMobNoValidateHandler?(isValidate ?? false) 87 | txtMobNO.shake() 88 | 89 | } else { 90 | 91 | isValidate = true 92 | lblPlaceHolder.text = placeHolderMobNo 93 | lblPlaceHolder.textColor = UIColor.darkGray 94 | 95 | if txtMobNoHandler != nil { 96 | txtMobNoHandler?(txtMobNO) 97 | } 98 | 99 | txtMobNoValidateHandler?(isValidate ?? true) 100 | } 101 | } 102 | 103 | @IBAction func onCntryCodeValueChanged(_ sender: UITextField) { 104 | 105 | if CntryCodeHandler != nil { 106 | CntryCodeHandler?(txtCntryCode) 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/TableViewCells/MultiPhotoCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MultiPhotoCell.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/15/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class MultiPhotoCell: UITableViewCell { 11 | 12 | @IBOutlet weak private var btnAdd: UIButton! 13 | @IBOutlet weak private var lblPhotosCount: UILabel! 14 | @IBOutlet weak private var collMultiplePhoto: CollMultiplePhotos! 15 | 16 | // Completion Handler For UIImage's Value Changed 17 | var multiImgHandler: ((_ images: [UIImage]) -> Void)? 18 | 19 | private var images = [UIImage]() 20 | 21 | override func awakeFromNib() { 22 | super.awakeFromNib() 23 | 24 | initializeCollView(multiImg: images) 25 | 26 | CGCDMainThread.async { [weak self] in 27 | 28 | guard let `self` = self else { return } 29 | 30 | self.btnAdd.roundView() 31 | self.btnAdd.shadow(color: .black, shadowOffset: .zero, shadowRadius: 8.0, shadowOpacity: 0.5) 32 | } 33 | } 34 | } 35 | 36 | //MARK:- Configure 37 | //MARK:- 38 | extension MultiPhotoCell { 39 | 40 | func configureCell(images: [UIImage]) { 41 | 42 | lblPhotosCount.text = "\(images.count) Photos Selected" 43 | 44 | CGCDMainThread.async { [weak self] in 45 | 46 | guard let `self` = self else { return } 47 | self.lblPhotosCount.textColor = UIColor.darkGray 48 | } 49 | 50 | initializeCollView(multiImg: images) 51 | } 52 | } 53 | 54 | //MARK:- Action 55 | //MARK:- 56 | extension MultiPhotoCell { 57 | 58 | @IBAction private func onAdd(_ sender: UIButton) { 59 | 60 | MediaManager.shared.presentImagePickerController(mediaType: [.photoLibrary("Photos"), .camera("Camera")], commpletion: { [weak self] 61 | (image, info) in 62 | 63 | guard let `self` = self else { return } 64 | 65 | if image == nil { 66 | 67 | } else { 68 | self.images.append(image ?? UIImage()) 69 | self.lblPhotosCount.text = "\(self.images.count) Photos Selected" 70 | self.lblPhotosCount.textColor = .darkGray 71 | self.initializeCollView(multiImg: self.images) 72 | self.multiImgHandler?(self.images) 73 | } 74 | }) 75 | } 76 | } 77 | 78 | //MARK:- CollectionView MultiplePhoto 79 | //MARK:- 80 | extension MultiPhotoCell { 81 | 82 | private func initializeCollView(multiImg: [UIImage]) { 83 | 84 | collMultiplePhoto.multiImages = multiImg 85 | 86 | collMultiplePhoto.multiImgRemovalHandler = { [weak self] images in 87 | 88 | guard let `self` = self else { return } 89 | self.images = images 90 | self.lblPhotosCount.text = "\(self.images.count) Photos Selected" 91 | self.multiImgHandler?(self.images) 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/TableViewCells/ProfileCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProfileCell.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/5/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class ProfileCell: UITableViewCell { 11 | 12 | @IBOutlet weak private var btnBanner: UIButton! 13 | @IBOutlet weak private var btnProfile: UIButton! 14 | @IBOutlet weak private var imgBanner: UIImageView! 15 | @IBOutlet weak private var imgUser: UIImageView! 16 | 17 | private var img = UIImage() 18 | 19 | // Completion Handler For UIImage's Value Changed 20 | var imgUserHandler: ((_ image: UIImage) -> Void)? 21 | var imgBannerHandler: ((_ image: UIImage) -> Void)? 22 | 23 | override func awakeFromNib() { 24 | super.awakeFromNib() 25 | 26 | initialize() 27 | } 28 | 29 | deinit { 30 | print("ProfileCell is deinitialized") 31 | } 32 | } 33 | 34 | //MARK:- Initialize 35 | //MARK:- 36 | extension ProfileCell { 37 | 38 | private func initialize() { 39 | 40 | CGCDMainThread.async { [weak self] in 41 | 42 | guard let `self` = self else { return } 43 | self.btnProfile.roundView() 44 | self.btnBanner.roundView() 45 | self.imgUser.roundView() 46 | } 47 | } 48 | 49 | func configureCell(user: UIImage?, banner: UIImage?) { 50 | 51 | imgUser.image = user ?? UIImage(named: "ic_user3") 52 | imgBanner.image = banner ?? UIImage(named: "ic_banner") 53 | } 54 | } 55 | 56 | //MARK:- Action 57 | //MARK:- 58 | extension ProfileCell { 59 | 60 | @IBAction func onAdd(_ sender: UIButton) { 61 | 62 | if sender.tag == 1 { // For Profile Image 63 | 64 | img = imgUser.image ?? UIImage() 65 | 66 | MediaManager.shared.presentImagePickerController(mediaType: [.photoLibrary("Photos"), .camera("Camera")], commpletion: { [weak self] 67 | (image, info) in 68 | 69 | guard let `self` = self else { return } 70 | 71 | if image == nil { 72 | self.imgUser.image = self.img 73 | self.imgUserHandler?(self.img) 74 | } else { 75 | self.imgUser.image = image 76 | self.imgUserHandler?(image ?? UIImage()) 77 | } 78 | }) 79 | 80 | } else { // For Profile Banner 81 | 82 | img = imgBanner.image ?? UIImage() 83 | 84 | MediaManager.shared.presentImagePickerController(mediaType: [.photoLibrary("Photos"), .camera("Camera")], commpletion: { [weak self] 85 | (image, info) in 86 | 87 | guard let `self` = self else { return } 88 | 89 | if image == nil { 90 | self.imgBanner.image = self.img 91 | self.imgBannerHandler?(self.img) 92 | } else { 93 | self.imgBanner.image = image 94 | self.imgBannerHandler?(image ?? UIImage()) 95 | } 96 | }) 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/TableViewCells/SwitchCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwitchCell.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/11/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class SwitchCell: UITableViewCell { 11 | 12 | @IBOutlet weak private var swtch: UISwitch! 13 | @IBOutlet weak private var lblSwitch: UILabel! 14 | 15 | var switchHandler: ((_ onOff: Bool) -> Void)? 16 | 17 | deinit { 18 | print("SwitchCell is deinitialized") 19 | } 20 | } 21 | 22 | //MARK:- Action 23 | //MARK:- 24 | extension SwitchCell { 25 | 26 | func configureCell(value: Bool) { 27 | 28 | if value { 29 | lblSwitch.text = "Notification : On" 30 | swtch.isSelected = false 31 | swtch.setOn(true, animated: true) 32 | } else { 33 | lblSwitch.text = "Notification : Off" 34 | swtch.isSelected = true 35 | swtch.setOn(false, animated: true) 36 | } 37 | } 38 | } 39 | 40 | //MARK:- Action 41 | //MARK:- 42 | extension SwitchCell { 43 | 44 | @IBAction func onChanged(_ sender: UISwitch) { 45 | 46 | if sender.isSelected { 47 | 48 | sender.isSelected.toggle() 49 | lblSwitch.text = "Notification : On" 50 | if switchHandler != nil { 51 | switchHandler?(true) 52 | } 53 | 54 | } else { 55 | 56 | sender.isSelected.toggle() 57 | lblSwitch.text = "Notification : Off" 58 | if switchHandler != nil { 59 | switchHandler?(false) 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/TableViewCells/SwitchCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/TableViewCells/TextViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextViewCell.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/11/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class TextViewCell: UITableViewCell { 11 | 12 | @IBOutlet weak private var vwAddressLine: UIView! 13 | @IBOutlet weak private var lblPlaceHolder: UILabel! 14 | @IBOutlet weak private var txtViewAddress: UITextView! 15 | 16 | var placeHolder2 = "" 17 | 18 | // Completion Handler For TextField's Value Changed 19 | var txtViewValueHandler: ((_ txtView: UITextView) -> Void)? 20 | 21 | override func awakeFromNib() { 22 | super.awakeFromNib() 23 | 24 | txtViewAddress.delegate = self 25 | } 26 | 27 | deinit {} 28 | } 29 | 30 | 31 | //MARK:- Configure Cell 32 | //MARK:- 33 | extension TextViewCell { 34 | 35 | func configuareCell(info: FormModel, isEdit: Bool) { 36 | 37 | placeHolder2 = info.placeHolder2 ?? "" 38 | txtViewAddress.text = info.value 39 | lblPlaceHolder.text = info.placeHolder 40 | lblPlaceHolder.textColor = info.placeHolderColor 41 | txtViewAddress.placeholder = info.placeHolder2 42 | txtViewAddress.placeholderColor = .lightGray 43 | txtViewAddress.keyboardType = info.keyboardType ?? .default 44 | } 45 | } 46 | 47 | //MARK:- TextView Delegate 48 | //MARK:- 49 | extension TextViewCell: UITextViewDelegate { 50 | 51 | func textViewDidBeginEditing(_ textView: UITextView) { 52 | 53 | txtViewAddress.placeholder = "" 54 | } 55 | 56 | func textViewDidEndEditing(_ textView: UITextView) { 57 | 58 | if txtViewAddress.text == "" { 59 | txtViewAddress.placeholder = placeHolder2 60 | txtViewAddress.placeholderColor = .lightGray 61 | } 62 | 63 | if txtViewValueHandler != nil { 64 | txtViewValueHandler?(textView) 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Form/TableFormView/TableViewCells/TextViewCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, 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. 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/Home/HomeVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HomeVC.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/8/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class HomeVC: UIViewController { 11 | 12 | @IBOutlet weak private var btnShow: UIButton! 13 | @IBOutlet weak private var btnRegister: UIButton! 14 | 15 | var userData = [[FormModel]]() 16 | var userImage = [ProfileImageModel]() 17 | var userisChecked = [CheckBoxModel]() 18 | var userSwitchValue = [SwitchModel]() 19 | var userMultiPhoto = [MultiPhotoModel]() 20 | 21 | override func viewDidLoad() { 22 | super.viewDidLoad() 23 | 24 | initialize() 25 | } 26 | 27 | deinit {} 28 | } 29 | 30 | //MARK:- Action 31 | //MARK:- 32 | extension HomeVC { 33 | 34 | private func initialize() { 35 | 36 | navigationController?.navigationBar.shadowImage = UIImage() 37 | btnShow.shadow(color: .black, shadowOffset: CGSize(width: 5.0, height: 5.0), shadowRadius: 8.0, shadowOpacity: 0.5) 38 | btnRegister.shadow(color: .black, shadowOffset: CGSize(width: 5.0, height: 5.0), shadowRadius: 8.0, shadowOpacity: 0.5) 39 | } 40 | } 41 | 42 | //MARK:- Action 43 | //MARK:- 44 | extension HomeVC { 45 | 46 | @IBAction func onRegister(_ sender: UIButton) { 47 | 48 | if let formVC = CMainStoryboard.instantiateViewController(withIdentifier: FormVC.storyboardID) as? FormVC { 49 | 50 | formVC.isFromHome = true 51 | formVC.txtFieldData = userData 52 | formVC.userImage = userImage 53 | formVC.userisChecked = userisChecked 54 | formVC.userSwitchValue = userSwitchValue 55 | formVC.userMultiPhoto = userMultiPhoto 56 | self.navigationController?.pushViewController(formVC, animated: true) 57 | } 58 | } 59 | 60 | @IBAction func onShow(_ sender: UIButton) { 61 | 62 | if let listVC = CMainStoryboard.instantiateViewController(withIdentifier: ListVC.storyboardID) as? ListVC { 63 | 64 | listVC.userData = userData 65 | listVC.userImage = userImage 66 | listVC.userisChecked = userisChecked 67 | listVC.userSwitchValue = userSwitchValue 68 | listVC.userMultiPhoto = userMultiPhoto 69 | self.navigationController?.pushViewController(listVC, animated: true) 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/List/ListVC.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ListView.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/9/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class ListVC: UIViewController { 11 | 12 | @IBOutlet weak private var tblUserList: TblUserList! 13 | 14 | var userData = [[FormModel]]() 15 | var userImage = [ProfileImageModel]() 16 | var userisChecked = [CheckBoxModel]() 17 | var userSwitchValue = [SwitchModel]() 18 | var userMultiPhoto = [MultiPhotoModel]() 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | 23 | initialize() 24 | } 25 | } 26 | 27 | //MARK:- Initialize 28 | //MARK:- 29 | extension ListVC { 30 | 31 | private func initialize() { 32 | 33 | title = "Users" 34 | navigationController?.navigationBar.topItem?.title = "" 35 | 36 | tblUserList.userData = userData 37 | tblUserList.userImage = userImage 38 | tblUserList.userisChecked = userisChecked 39 | tblUserList.userSwitchValue = userSwitchValue 40 | tblUserList.userMultiPhoto = userMultiPhoto 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/List/TableView/ListCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ListCell.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/9/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class ListCell: UITableViewCell { 11 | 12 | @IBOutlet weak private var lblUserList: UILabel! 13 | } 14 | 15 | //MARK:- Configure Cell 16 | //MARK:- 17 | extension ListCell { 18 | 19 | func configureCell(data: String?) { 20 | 21 | lblUserList.text = data 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/List/TableView/ListCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Classes/List/TableView/TblUserList.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TblUserList.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/9/21. 6 | // 7 | 8 | import UIKit 9 | 10 | final class TblUserList: UITableView { 11 | 12 | var userData = [[FormModel]]() 13 | var userImage = [ProfileImageModel]() 14 | var userisChecked = [CheckBoxModel]() 15 | var userSwitchValue = [SwitchModel]() 16 | var userMultiPhoto = [MultiPhotoModel]() 17 | 18 | private var user = [String]() 19 | 20 | override func awakeFromNib() { 21 | super.awakeFromNib() 22 | 23 | initialize() 24 | } 25 | } 26 | 27 | //MARK:- Initialize 28 | //MARK:- 29 | extension TblUserList { 30 | 31 | private func initialize() { 32 | 33 | dataSource = self 34 | delegate = self 35 | register(ListCell.nib, forCellReuseIdentifier: ListCell.identifier) 36 | } 37 | } 38 | 39 | //MARK:- UITableView Datasource and Delegate 40 | //MARK:- 41 | extension TblUserList: UITableViewDataSource, UITableViewDelegate { 42 | 43 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 44 | 45 | return userData.count 46 | } 47 | 48 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 49 | 50 | if let userCell = tableView.dequeueReusableCell(withIdentifier: ListCell.identifier) as? ListCell { 51 | 52 | guard let index = userData[indexPath.row].firstIndex(where: { $0.placeHolder == "Name*" }) else { return UITableViewCell() } 53 | 54 | userCell.configureCell(data: userData[indexPath.row][index].value) 55 | 56 | return userCell 57 | } 58 | return UITableViewCell() 59 | } 60 | 61 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 62 | 63 | if let formVC = CMainStoryboard.instantiateViewController(withIdentifier: FormVC.storyboardID) as? FormVC { 64 | 65 | formVC.isFromEdit = true 66 | formVC.txtFieldData = userData 67 | formVC.index = indexPath.row 68 | formVC.userImage = userImage 69 | formVC.userisChecked = userisChecked 70 | formVC.userSwitchValue = userSwitchValue 71 | formVC.userMultiPhoto = userMultiPhoto 72 | 73 | self.parentContainerViewController()?.navigationController?.pushViewController(formVC, animated: true) 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/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 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UIApplicationSupportsIndirectInputEvents 43 | 44 | UILaunchStoryboardName 45 | LaunchScreen 46 | UIMainStoryboardFile 47 | Main 48 | UIRequiredDeviceCapabilities 49 | 50 | armv7 51 | 52 | UISupportedInterfaceOrientations 53 | 54 | UIInterfaceOrientationPortrait 55 | 56 | UISupportedInterfaceOrientations~ipad 57 | 58 | UIInterfaceOrientationPortrait 59 | UIInterfaceOrientationPortraitUpsideDown 60 | UIInterfaceOrientationLandscapeLeft 61 | UIInterfaceOrientationLandscapeRight 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Model/Model.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Model.swift 3 | // CommonLRF 4 | // 5 | // Created by mind-288 on 3/4/21. 6 | // 7 | 8 | import UIKit 9 | 10 | //MARK:- Model Form 11 | //MARK:- 12 | 13 | enum ControlType { 14 | 15 | case checkBox 16 | case textField 17 | case profileImage 18 | case switchType 19 | case textView 20 | case multiPhoto 21 | } 22 | 23 | enum TextFieldType: Equatable { 24 | 25 | case normal 26 | case password 27 | case dob 28 | case picker 29 | case actionSheet 30 | case selection(Bool?) // Pass true or false for Allowing multiple Selection 31 | case mobileNumber(Bool?) //Pass true or false for Country Flag 32 | } 33 | 34 | struct FormModel { 35 | 36 | var controlType: ControlType 37 | var txtFieldType: TextFieldType? 38 | var value: String? 39 | var placeHolder: String? 40 | var placeHolder2: String? 41 | var placeHolderColor: UIColor? 42 | var leftImgView: String? 43 | var rightImgView: String? 44 | var isEnabled: Bool? 45 | var isSecure: Bool? 46 | var keyboardType: UIKeyboardType? 47 | var isValid: Bool? 48 | } 49 | 50 | struct ProfileImageModel { 51 | 52 | var userImg: UIImage? 53 | var bannerImg: UIImage? 54 | } 55 | 56 | struct CheckBoxModel { 57 | var isChecked: Bool? 58 | } 59 | 60 | struct SwitchModel { 61 | var isOn: Bool? 62 | } 63 | 64 | struct MultiPhotoModel { 65 | 66 | var images: [UIImage]? 67 | } 68 | 69 | //MARK:- PlaceHolder Constants 70 | //MARK:- 71 | let placeHolderName = "Name*" 72 | let placeHolderEmail = "Email Address*" 73 | let placeHolderPassword = "Password*" 74 | let placeHolderMobNo = "Mobile Number*" 75 | let placeHolderDob = "Birth Date" 76 | let placeHolderDept = "Department" 77 | let placeHolderGender = "Gender" 78 | let placeHolderAddress = "Address" 79 | let placeHolderHobbies = "Hobbies" 80 | let placeHolderCountry = "Country" 81 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Storyboard/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 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Support/Constants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ApplicationConstants.swift 3 | // 4 | // 5 | // Created by mac-0006 on 11/04/19. 6 | // Copyright © 2019 mac-0006. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | let CScreenWidth = UIScreen.main.bounds.width 12 | let CSharedApplication = UIApplication.shared 13 | let appDelegate = CSharedApplication.delegate as! AppDelegate 14 | let CGCDMainThread = DispatchQueue.main 15 | let CMainStoryboard = UIStoryboard(name: "Main", bundle: nil) 16 | 17 | 18 | func print(_ item: @autoclosure () -> Any, separator: String = " ", terminator: String = "\n") { 19 | #if DEBUG 20 | //Swift.print(item(), separator: separator, terminator: terminator) 21 | #endif 22 | } 23 | 24 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Support/ExtensionUITextView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExtensionUITextView.swift 3 | // 4 | // Created by mac-0002 on 25/08/17. 5 | // Copyright © 2017. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | // MARK: - Extension of UITextView For UITextView's placeholder Text and For UITextView's placeholderColor 12 | extension UITextView : UITextViewDelegate { 13 | 14 | /// Placeholder Text of UITextView , as it is @IBInspectable so you can directlly set placeholder Text of UITextView From Interface Builder , No need to write any number of Lines. 15 | @IBInspectable var placeholder: String? { 16 | 17 | get { 18 | 19 | var placeholderLabelText:String? 20 | 21 | if let placeholderLabel = self.viewWithTag(100) as? UILabel { 22 | placeholderLabelText = placeholderLabel.text 23 | } 24 | 25 | return placeholderLabelText 26 | } set { 27 | 28 | if let placeholderLabel = self.viewWithTag(100) as? UILabel { 29 | placeholderLabel.text = newValue 30 | } else { 31 | 32 | self.addPlaceholderLabel(placeholder: newValue, placeholderColor: nil, placeholderFont: nil) 33 | } 34 | } 35 | } 36 | 37 | var placeholderFont: UIFont? { 38 | 39 | get { 40 | 41 | var placeholderLabelFont:UIFont? 42 | 43 | if let placeholderLabel = self.viewWithTag(100) as? UILabel { 44 | placeholderLabelFont = placeholderLabel.font 45 | } 46 | 47 | return placeholderLabelFont 48 | } set { 49 | 50 | if let placeholderLabel = self.viewWithTag(100) as? UILabel { 51 | placeholderLabel.font = newValue 52 | } else { 53 | 54 | self.addPlaceholderLabel(placeholder: nil, placeholderColor: nil, placeholderFont: newValue) 55 | } 56 | } 57 | } 58 | 59 | /// Placeholder Color of UITextView , as it is @IBInspectable so you can directlly set placeholder Color of UITextView From Interface Builder , No need to write any number of Lines. 60 | @IBInspectable var placeholderColor: UIColor? { 61 | 62 | get { 63 | 64 | var placeholdeLabelTextColor:UIColor? 65 | 66 | if let placeholderLabel = self.viewWithTag(100) as? UILabel { 67 | placeholdeLabelTextColor = placeholderLabel.textColor 68 | } 69 | 70 | return placeholdeLabelTextColor 71 | } set { 72 | 73 | if let placeholderLabel = self.viewWithTag(100) as? UILabel { 74 | placeholderLabel.textColor = newValue 75 | } else { 76 | 77 | self.addPlaceholderLabel(placeholder: nil, placeholderColor: newValue, placeholderFont: nil) 78 | } 79 | } 80 | } 81 | 82 | /// This Private Method is used to Add placeholderLabel in UITextView. 83 | /// 84 | /// - Parameters: 85 | /// - placeholder: A String Value that indicates the placeholder Text of UITextView. 86 | /// - placeholderColor: A UIColor Value that indicates the placeholder Color of UITextView. 87 | private func addPlaceholderLabel(placeholder: String?, placeholderColor: UIColor?, placeholderFont: UIFont?) { 88 | 89 | let placeholderLabel = UILabel() 90 | placeholderLabel.textAlignment = self.textAlignment 91 | placeholderLabel.numberOfLines = 0 92 | placeholderLabel.tag = 100 93 | placeholderLabel.text = placeholder 94 | placeholderLabel.textColor = placeholderColor 95 | placeholderLabel.font = placeholderFont 96 | placeholderLabel.sizeToFit() 97 | placeholderLabel.isHidden = self.text.count > 0 98 | self.addSubview(placeholderLabel) 99 | 100 | self.resizePlaceholderLabel() 101 | 102 | self.addObserver(self, forKeyPath: "text", options: .new, context: nil) 103 | } 104 | 105 | /// This Private Method is used to Assign Frame to placeholderLabel in UITextView. 106 | private func resizePlaceholderLabel() { 107 | 108 | if let placeholderLabel = self.viewWithTag(100) as? UILabel { 109 | 110 | let labelX = self.textContainer.lineFragmentPadding 111 | let labelY = self.textContainerInset.top 112 | 113 | placeholderLabel.frame = CGRect(x: labelX, y: labelY, width: (self.frame.size.width - (2 * labelX)), height: placeholderLabel.frame.size.height) 114 | } 115 | } 116 | 117 | public func textViewDidChange(_ textView: UITextView) { 118 | 119 | if let placeholderLabel = self.viewWithTag(100) as? UILabel { 120 | placeholderLabel.isHidden = self.text.count > 0 121 | } 122 | } 123 | 124 | open override func willMove(toSuperview newSuperview: UIView?) { 125 | 126 | if newSuperview == nil { 127 | if (self.viewWithTag(100) as? UILabel) != nil { 128 | self.removeObserver(self, forKeyPath: "text") 129 | } 130 | } 131 | } 132 | 133 | open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 134 | 135 | if keyPath == "text" { 136 | 137 | if let placeholderLabel = self.viewWithTag(100) as? UILabel { 138 | placeholderLabel.isHidden = self.text.count > 0 139 | } 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Support/ExtensionsUIView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExtensionsUIView.swift 3 | // 4 | // Created by mac-0005 on 07/01/2020. 5 | // Copyright © 2020. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | // MARK: - Extension of UIView For giving the round shape to any UIView. 12 | extension UIView { 13 | 14 | @IBInspectable fileprivate var cornerRadius: CGFloat { 15 | get { 16 | return self.layer.cornerRadius 17 | } set { 18 | self.layer.cornerRadius = newValue 19 | self.layer.masksToBounds = true 20 | } 21 | } 22 | 23 | @IBInspectable fileprivate var borderColor: UIColor? { 24 | get { 25 | guard let borderColor = self.layer.borderColor else { return nil } 26 | return UIColor(cgColor: borderColor) 27 | } set { 28 | self.layer.borderColor = newValue?.cgColor 29 | } 30 | } 31 | 32 | @IBInspectable fileprivate var borderWidth: CGFloat { 33 | get { 34 | return self.layer.borderWidth 35 | } set { 36 | self.layer.borderWidth = newValue 37 | } 38 | } 39 | 40 | func roundView() { 41 | 42 | layer.cornerRadius = CViewHeight > CViewWidth 43 | ? CViewWidth/2.0 44 | : CViewHeight/2.0 45 | layer.masksToBounds = true 46 | } 47 | } 48 | 49 | 50 | extension UIView { 51 | 52 | func shadow(color: UIColor, shadowOffset: CGSize, shadowRadius: CGFloat, shadowOpacity: Float) { 53 | 54 | self.layer.masksToBounds = false 55 | self.layer.shadowColor = color.cgColor 56 | self.layer.shadowOffset = shadowOffset 57 | self.layer.shadowRadius = shadowRadius 58 | self.layer.shadowOpacity = shadowOpacity 59 | self.layer.shadowPath = UIBezierPath(rect: self.bounds).cgPath 60 | 61 | self.layer.shouldRasterize = true 62 | } 63 | } 64 | 65 | extension UIView { 66 | 67 | var CViewSize: CGSize { 68 | return self.frame.size 69 | } 70 | var CViewWidth: CGFloat { 71 | return self.CViewSize.width 72 | } 73 | var CViewHeight: CGFloat { 74 | return self.CViewSize.height 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Support/MediaManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MediaManager.swift 3 | // 4 | // Created by mac-0002 on 03/01/20. 5 | // Copyright © 2020. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | fileprivate var topMostViewController : UIViewController? { 12 | return UIApplication.shared.topMostVC() 13 | } 14 | 15 | final class MediaManager: NSObject { 16 | 17 | /// Shared(Singleton) object of MediaManager class. 18 | static let shared: MediaManager = MediaManager() 19 | 20 | private(set) lazy var imagePickerController: UIImagePickerController = { 21 | let imagePickerController = UIImagePickerController() 22 | imagePickerController.delegate = self 23 | return imagePickerController 24 | }() 25 | 26 | private(set) var commpletion: ((_ image: UIImage?, _ info: [UIImagePickerController.InfoKey : Any]?) -> ())? 27 | } 28 | 29 | extension MediaManager { 30 | 31 | var allowsEditing: Bool { 32 | get { 33 | return imagePickerController.allowsEditing 34 | } set { 35 | imagePickerController.allowsEditing = newValue 36 | } 37 | } 38 | 39 | enum MediaSourceType: Equatable { 40 | 41 | case photoLibrary(String) 42 | case camera(String) 43 | case savedPhotosAlbum(String) 44 | 45 | fileprivate var strValue: String { 46 | 47 | switch self { 48 | 49 | case .photoLibrary(let strPhotoLibrary): 50 | return strPhotoLibrary 51 | 52 | case .camera(let strCamera): 53 | return strCamera 54 | 55 | case .savedPhotosAlbum(let strSavedPhotosAlbum): 56 | return strSavedPhotosAlbum 57 | } 58 | } 59 | 60 | fileprivate func takeAppropriateAction(mediaManager: MediaManager) { 61 | 62 | switch self { 63 | 64 | case .camera: 65 | mediaManager.takeAPhoto() 66 | 67 | case .photoLibrary: 68 | mediaManager.chooseFromPhotoLibrary() 69 | 70 | case .savedPhotosAlbum: 71 | mediaManager.chooseFromSavedPhotosAlbum() 72 | } 73 | } 74 | } 75 | } 76 | 77 | extension MediaManager { 78 | 79 | func presentImagePickerController(isEditing: Bool = false, title: String? = nil, message: String? = nil, mediaType: [MediaSourceType], commpletion: ((_ image: UIImage?, _ info: [UIImagePickerController.InfoKey : Any]?) -> ())?) { 80 | 81 | self.allowsEditing = isEditing 82 | 83 | let mediaSourceTypes = mediaType.removeDuplicates() 84 | var actions : [AAction] = [] 85 | let _ = mediaSourceTypes.compactMap({actions.append(AAction.Custom(title: $0.strValue))}) 86 | guard !actions.isEmpty else { 87 | return 88 | } 89 | actions.append(.Cancel) 90 | 91 | topMostViewController?.alertView(title: title, message: message, style: .actionSheet, actions: actions, handler: { [weak self] (action) in 92 | guard let self = self else { return } 93 | if action == AAction.Cancel { return } 94 | guard let index = actions.indexes(of: action).first else { return } 95 | let medisSource = mediaType[index] 96 | medisSource.takeAppropriateAction(mediaManager: self) 97 | }) 98 | self.commpletion = commpletion 99 | } 100 | 101 | /// A private method used to select an image from camera. 102 | private func takeAPhoto() { 103 | 104 | guard UIImagePickerController.isSourceTypeAvailable(.camera) else{ 105 | let msg = "Your device doesn't support camera." 106 | topMostViewController?.alertView(message:msg,actions: [.Ok]) 107 | return 108 | } 109 | 110 | imagePickerController.sourceType = .camera 111 | imagePickerController.allowsEditing = false 112 | topMostViewController?.present(imagePickerController, animated: true, completion: nil) 113 | } 114 | 115 | /// A private method used to select an image from photoLibrary. 116 | private func chooseFromPhotoLibrary() { 117 | 118 | guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else { 119 | let msg = "Your device doesn't support photo library." 120 | topMostViewController?.alertView(message:msg,actions: [.Ok]) 121 | return 122 | } 123 | 124 | imagePickerController.sourceType = .photoLibrary 125 | imagePickerController.allowsEditing = allowsEditing 126 | topMostViewController?.present(imagePickerController, animated: true, completion: nil) 127 | } 128 | 129 | /// A private method used to select an image from savedPhotosAlbum. 130 | private func chooseFromSavedPhotosAlbum() { 131 | 132 | guard UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum) else { 133 | let msg = "Your device doesn't support photo library." 134 | topMostViewController?.alertView(message:msg,actions: [.Ok]) 135 | return 136 | } 137 | 138 | imagePickerController.sourceType = .savedPhotosAlbum 139 | imagePickerController.allowsEditing = allowsEditing 140 | topMostViewController?.present(imagePickerController, animated: true, completion: nil) 141 | } 142 | } 143 | 144 | // MARK:- ImagePicker Delegate - 145 | extension MediaManager: UIImagePickerControllerDelegate, UINavigationControllerDelegate { 146 | 147 | internal func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { 148 | 149 | picker.dismiss(animated: true) { [weak self] in 150 | 151 | guard let self = self, let commpletion = self.commpletion else { 152 | return 153 | } 154 | 155 | var image:UIImage? 156 | if (self.allowsEditing) { 157 | image = info[.editedImage] as? UIImage 158 | } else { 159 | image = info[.originalImage] as? UIImage 160 | } 161 | 162 | commpletion(image, info) 163 | } 164 | } 165 | 166 | internal func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { 167 | 168 | picker.dismiss(animated: true) { [weak self] in 169 | 170 | guard let self = self, let commpletion = self.commpletion else { 171 | return 172 | } 173 | commpletion(nil, nil) 174 | } 175 | } 176 | } 177 | 178 | extension Array where Element: Equatable { 179 | 180 | func indexes(of element: Element) -> [Int] { 181 | return self.enumerated().filter({ element == $0.element }).map({ $0.offset }) 182 | } 183 | 184 | func removeDuplicates() -> [Element] { 185 | 186 | var result = [Element]() 187 | 188 | for value in self where !result.contains(value) { 189 | result.append(value) 190 | } 191 | 192 | return result 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Support/TabelView+CollectionViewExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UITableViewCell+Extension.swift 3 | // SetupApp 4 | // 5 | // Created by mac-00020 on 11/12/19. 6 | // Copyright © 2019 mac-00020. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | extension UITableViewCell { 13 | static var nib:UINib{ 14 | return UINib(nibName: identifier, bundle: nil) 15 | } 16 | 17 | static var identifier: String { 18 | return String(describing: self) 19 | } 20 | } 21 | 22 | extension UITableViewHeaderFooterView { 23 | static var nib:UINib{ 24 | return UINib(nibName: identifier, bundle: nil) 25 | } 26 | 27 | static var identifier: String { 28 | return String(describing: self) 29 | } 30 | } 31 | 32 | extension UICollectionReusableView { 33 | static var nib:UINib{ 34 | return UINib(nibName: identifier, bundle: nil) 35 | } 36 | 37 | static var identifier: String { 38 | return String(describing: self) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Support/UIButton+Extension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIButton+Extension.swift 3 | // 4 | // Created by mac-0005 on 07/01/2020. 5 | // Copyright © 2020. All rights reserved. 6 | // 7 | 8 | import UIKit 9 | 10 | typealias genericTouchUpInsideHandler = ((T) -> ()) 11 | 12 | // MARK: - Extension of UIButton For TouchUpInside Handler. 13 | extension UIButton { 14 | 15 | /// This Private Structure is used to create all AssociatedObjectKey which will be used within this extension. 16 | private struct AssociatedObjectKey { 17 | static var genericTouchUpInsideHandler = "genericTouchUpInsideHandler" 18 | } 19 | 20 | /// This method is used for UIButton's touchUpInside Handler 21 | /// - Parameter genericTouchUpInsideHandler: genericTouchUpInsideHandler will give you object of UIButton. 22 | func touchUpInside(genericTouchUpInsideHandler: @escaping genericTouchUpInsideHandler) { 23 | 24 | objc_setAssociatedObject( 25 | self, 26 | &AssociatedObjectKey.genericTouchUpInsideHandler, 27 | genericTouchUpInsideHandler, 28 | .OBJC_ASSOCIATION_RETAIN 29 | ) 30 | 31 | self.addTarget( 32 | self, 33 | action: #selector(handleButtonTouchEvent(sender:)), 34 | for: .touchUpInside 35 | ) 36 | 37 | } 38 | 39 | /// This Private method is used for handle the touch event of UIButton. 40 | /// 41 | /// - Parameter sender: UIButton. 42 | @objc private func handleButtonTouchEvent(sender: UIButton) { 43 | 44 | if let genericTouchUpInsideHandler = objc_getAssociatedObject(self, &AssociatedObjectKey.genericTouchUpInsideHandler) as? genericTouchUpInsideHandler { 45 | genericTouchUpInsideHandler(sender) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /GenerateDynamicCustomForm/Support/UIViewController+Alert.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Alert.swift 3 | // SetupApp 4 | // 5 | // Created by mac-0005 on 08/01/20. 6 | // Copyright © 2020 mac-00020. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | typealias alertActionHandler = ((UIAlertAction) -> ())? 13 | 14 | public enum AAction: Equatable { 15 | 16 | case Ok 17 | case Cancel 18 | case Custom(title:String) 19 | 20 | var title : String { 21 | switch self { 22 | case .Ok: 23 | return "Ok" 24 | case .Cancel: 25 | return "Cancel" 26 | case .Custom(let title): 27 | return title 28 | } 29 | } 30 | 31 | var style: UIAlertAction.Style { 32 | switch self { 33 | case .Cancel: 34 | return .cancel 35 | default: 36 | return .default 37 | } 38 | } 39 | } 40 | 41 | // MARK: - Extension of UIViewController For AlertView with Different Numbers of Buttons - 42 | extension UIViewController { 43 | 44 | func alertView(title: String? = nil, message: String? = nil, style: UIAlertController.Style = .alert, actions: [AAction] = [], handler: ((AAction) -> Void)? = nil) { 45 | 46 | var _actions = actions 47 | if actions.isEmpty { 48 | _actions.append(AAction.Ok) 49 | } 50 | var arrAction : [UIAlertAction] = [] 51 | let alertController = UIAlertController(title: title, message: message, preferredStyle: style) 52 | let onSelect : ((UIAlertAction) -> Void)? = { (alert) in 53 | guard let index = arrAction.firstIndex(of: alert) else { 54 | return 55 | } 56 | handler?(_actions[index]) 57 | } 58 | for action in _actions { 59 | arrAction.append(UIAlertAction(title: action.title, style: action.style, handler: onSelect)) 60 | } 61 | let _ = arrAction.map({alertController.addAction($0)}) 62 | self.present(alertController, animated: true, completion: nil) 63 | } 64 | } 65 | 66 | extension UIViewController { 67 | 68 | class var storyboardID : String { 69 | return "\(self)" 70 | } 71 | } 72 | 73 | // MARK: - Extension of UIApplication - 74 | 75 | extension UIApplication { 76 | 77 | static var appDelegate: AppDelegate? { 78 | return CSharedApplication.delegate as? AppDelegate 79 | } 80 | 81 | func topMostVC(viewController: UIViewController? = CSharedApplication.keyWindow?.rootViewController) -> UIViewController? { 82 | 83 | if let navigationViewController = viewController as? UINavigationController { 84 | return CSharedApplication.topMostVC(viewController: navigationViewController.visibleViewController) 85 | } 86 | if let tabBarViewController = viewController as? UITabBarController { 87 | if let selectedViewController = tabBarViewController.selectedViewController { 88 | return CSharedApplication.topMostVC(viewController: selectedViewController) 89 | } 90 | } 91 | if let presentedViewController = viewController?.presentedViewController { 92 | return CSharedApplication.topMostVC(viewController: presentedViewController) 93 | } 94 | return viewController 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 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. 22 | -------------------------------------------------------------------------------- /Media/form.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/GenerateDynamicCustomForm/0c53e6087c718f9663dc6884dbb0f758d15d3177/Media/form.gif -------------------------------------------------------------------------------- /Media/mi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mindinventory/GenerateDynamicCustomForm/0c53e6087c718f9663dc6884dbb0f758d15d3177/Media/mi.png -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'GenerateDynamicCustomForm' do 5 | # Comment the next line if you don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for GenerateDynamicCustomForm 9 | pod 'IQKeyboardManagerSwift' 10 | 11 | end 12 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - IQKeyboardManagerSwift (6.5.6) 3 | 4 | DEPENDENCIES: 5 | - IQKeyboardManagerSwift 6 | 7 | SPEC REPOS: 8 | trunk: 9 | - IQKeyboardManagerSwift 10 | 11 | SPEC CHECKSUMS: 12 | IQKeyboardManagerSwift: c7df9d2deb356c04522f5c4b7b6e4ce4d8ed94fe 13 | 14 | PODFILE CHECKSUM: e5f4012936db61c0079fb31eff2c5a6da67ee0d6 15 | 16 | COCOAPODS: 1.10.1 17 | -------------------------------------------------------------------------------- /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 kIQShouldIgnoreContentInsetAdjustment = "kIQShouldIgnoreContentInsetAdjustment" 29 | private var kIQShouldRestoreScrollViewContentOffset = "kIQShouldRestoreScrollViewContentOffset" 30 | 31 | @objc public extension UIScrollView { 32 | 33 | /** 34 | If YES, then scrollview will ignore scrolling (simply not scroll it) for adjusting textfield position. Default is NO. 35 | */ 36 | @objc var shouldIgnoreScrollingAdjustment: Bool { 37 | get { 38 | 39 | if let aValue = objc_getAssociatedObject(self, &kIQShouldIgnoreScrollingAdjustment) as? Bool { 40 | return aValue 41 | } else { 42 | return false 43 | } 44 | } 45 | set(newValue) { 46 | objc_setAssociatedObject(self, &kIQShouldIgnoreScrollingAdjustment, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) 47 | } 48 | } 49 | 50 | /** 51 | If YES, then scrollview will ignore content inset adjustment (simply not updating it) when keyboard is shown. Default is NO. 52 | */ 53 | @objc var shouldIgnoreContentInsetAdjustment: Bool { 54 | get { 55 | 56 | if let aValue = objc_getAssociatedObject(self, &kIQShouldIgnoreContentInsetAdjustment) as? Bool { 57 | return aValue 58 | } else { 59 | return false 60 | } 61 | } 62 | set(newValue) { 63 | objc_setAssociatedObject(self, &kIQShouldIgnoreContentInsetAdjustment, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) 64 | } 65 | } 66 | 67 | /** 68 | To set customized distance from keyboard for textField/textView. Can't be less than zero 69 | */ 70 | @objc var shouldRestoreScrollViewContentOffset: Bool { 71 | get { 72 | 73 | if let aValue = objc_getAssociatedObject(self, &kIQShouldRestoreScrollViewContentOffset) as? Bool { 74 | return aValue 75 | } else { 76 | return false 77 | } 78 | } 79 | set(newValue) { 80 | objc_setAssociatedObject(self, &kIQShouldRestoreScrollViewContentOffset, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) 81 | } 82 | } 83 | } 84 | 85 | internal extension UITableView { 86 | 87 | func previousIndexPath(of indexPath: IndexPath) -> IndexPath? { 88 | var previousRow = indexPath.row - 1 89 | var previousSection = indexPath.section 90 | 91 | //Fixing indexPath 92 | if previousRow < 0 { 93 | previousSection -= 1 94 | 95 | if previousSection >= 0 { 96 | previousRow = self.numberOfRows(inSection: previousSection) - 1 97 | } 98 | } 99 | 100 | if previousRow >= 0 && previousSection >= 0 { 101 | return IndexPath(row: previousRow, section: previousSection) 102 | } else { 103 | return nil 104 | } 105 | } 106 | } 107 | 108 | internal extension UICollectionView { 109 | 110 | func previousIndexPath(of indexPath: IndexPath) -> IndexPath? { 111 | var previousRow = indexPath.row - 1 112 | var previousSection = indexPath.section 113 | 114 | //Fixing indexPath 115 | if previousRow < 0 { 116 | previousSection -= 1 117 | 118 | if previousSection >= 0 { 119 | previousRow = self.numberOfItems(inSection: previousSection) - 1 120 | } 121 | } 122 | 123 | if previousRow >= 0 && previousSection >= 0 { 124 | return IndexPath(item: previousRow, section: previousSection) 125 | } else { 126 | return nil 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /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 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 | This method is provided to override by viewController's if the library lifts a viewController which you doesn't want to lift . This may happen if you have implemented side menu feature in your app and the library try to lift the side menu controller. Overriding this method in side menu class to return correct controller should fix the problem. 32 | */ 33 | func parentIQContainerViewController() -> UIViewController? { 34 | return self 35 | } 36 | 37 | /** 38 | To set customized distance from keyboard for textField/textView. Can't be less than zero 39 | 40 | @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 41 | */ 42 | @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.") 43 | @IBOutlet @objc var IQLayoutGuideConstraint: NSLayoutConstraint? { 44 | get { 45 | 46 | return objc_getAssociatedObject(self, &kIQLayoutGuideConstraint) as? NSLayoutConstraint 47 | } 48 | 49 | set(newValue) { 50 | objc_setAssociatedObject(self, &kIQLayoutGuideConstraint, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /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/IQTextView/IQTextView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IQTextView.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 | /** @abstract UITextView with placeholder support */ 27 | open class IQTextView: UITextView { 28 | 29 | @objc required public init?(coder aDecoder: NSCoder) { 30 | super.init(coder: aDecoder) 31 | 32 | #if swift(>=4.2) 33 | let UITextViewTextDidChange = UITextView.textDidChangeNotification 34 | #else 35 | let UITextViewTextDidChange = Notification.Name.UITextViewTextDidChange 36 | #endif 37 | 38 | NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: UITextViewTextDidChange, object: self) 39 | } 40 | 41 | @objc override public init(frame: CGRect, textContainer: NSTextContainer?) { 42 | super.init(frame: frame, textContainer: textContainer) 43 | 44 | #if swift(>=4.2) 45 | let notificationName = UITextView.textDidChangeNotification 46 | #else 47 | let notificationName = Notification.Name.UITextViewTextDidChange 48 | #endif 49 | 50 | NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: notificationName, object: self) 51 | } 52 | 53 | @objc override open func awakeFromNib() { 54 | super.awakeFromNib() 55 | 56 | #if swift(>=4.2) 57 | let UITextViewTextDidChange = UITextView.textDidChangeNotification 58 | #else 59 | let UITextViewTextDidChange = Notification.Name.UITextViewTextDidChange 60 | #endif 61 | 62 | NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), name: UITextViewTextDidChange, object: self) 63 | } 64 | 65 | deinit { 66 | IQ_PlaceholderLabel.removeFromSuperview() 67 | NotificationCenter.default.removeObserver(self) 68 | } 69 | 70 | private var placeholderInsets: UIEdgeInsets { 71 | return UIEdgeInsets(top: self.textContainerInset.top, left: self.textContainerInset.left + self.textContainer.lineFragmentPadding, bottom: self.textContainerInset.bottom, right: self.textContainerInset.right + self.textContainer.lineFragmentPadding) 72 | } 73 | 74 | private var placeholderExpectedFrame: CGRect { 75 | let placeholderInsets = self.placeholderInsets 76 | let maxWidth = self.frame.width-placeholderInsets.left-placeholderInsets.right 77 | let expectedSize = IQ_PlaceholderLabel.sizeThatFits(CGSize(width: maxWidth, height: self.frame.height-placeholderInsets.top-placeholderInsets.bottom)) 78 | 79 | return CGRect(x: placeholderInsets.left, y: placeholderInsets.top, width: maxWidth, height: expectedSize.height) 80 | } 81 | 82 | lazy var IQ_PlaceholderLabel: UILabel = { 83 | let label = UILabel() 84 | 85 | label.autoresizingMask = [.flexibleWidth, .flexibleHeight] 86 | label.lineBreakMode = .byWordWrapping 87 | label.numberOfLines = 0 88 | label.font = self.font 89 | label.textAlignment = self.textAlignment 90 | label.backgroundColor = UIColor.clear 91 | #if swift(>=5.1) 92 | label.textColor = UIColor.systemGray 93 | #else 94 | label.textColor = UIColor.lightText 95 | #endif 96 | label.alpha = 0 97 | self.addSubview(label) 98 | 99 | return label 100 | }() 101 | 102 | /** @abstract To set textView's placeholder text color. */ 103 | @IBInspectable open var placeholderTextColor: UIColor? { 104 | 105 | get { 106 | return IQ_PlaceholderLabel.textColor 107 | } 108 | 109 | set { 110 | IQ_PlaceholderLabel.textColor = newValue 111 | } 112 | } 113 | 114 | /** @abstract To set textView's placeholder text. Default is nil. */ 115 | @IBInspectable open var placeholder: String? { 116 | 117 | get { 118 | return IQ_PlaceholderLabel.text 119 | } 120 | 121 | set { 122 | IQ_PlaceholderLabel.text = newValue 123 | refreshPlaceholder() 124 | } 125 | } 126 | 127 | /** @abstract To set textView's placeholder attributed text. Default is nil. */ 128 | open var attributedPlaceholder: NSAttributedString? { 129 | get { 130 | return IQ_PlaceholderLabel.attributedText 131 | } 132 | 133 | set { 134 | IQ_PlaceholderLabel.attributedText = newValue 135 | refreshPlaceholder() 136 | } 137 | } 138 | 139 | @objc override open func layoutSubviews() { 140 | super.layoutSubviews() 141 | 142 | IQ_PlaceholderLabel.frame = placeholderExpectedFrame 143 | } 144 | 145 | @objc internal func refreshPlaceholder() { 146 | 147 | if !text.isEmpty || !attributedText.string.isEmpty { 148 | IQ_PlaceholderLabel.alpha = 0 149 | } else { 150 | IQ_PlaceholderLabel.alpha = 1 151 | } 152 | } 153 | 154 | @objc override open var text: String! { 155 | 156 | didSet { 157 | refreshPlaceholder() 158 | } 159 | } 160 | 161 | open override var attributedText: NSAttributedString! { 162 | 163 | didSet { 164 | refreshPlaceholder() 165 | } 166 | } 167 | 168 | @objc override open var font: UIFont? { 169 | 170 | didSet { 171 | 172 | if let unwrappedFont = font { 173 | IQ_PlaceholderLabel.font = unwrappedFont 174 | } else { 175 | IQ_PlaceholderLabel.font = UIFont.systemFont(ofSize: 12) 176 | } 177 | } 178 | } 179 | 180 | @objc override open var textAlignment: NSTextAlignment { 181 | didSet { 182 | IQ_PlaceholderLabel.textAlignment = textAlignment 183 | } 184 | } 185 | 186 | @objc override weak open var delegate: UITextViewDelegate? { 187 | 188 | get { 189 | refreshPlaceholder() 190 | return super.delegate 191 | } 192 | 193 | set { 194 | super.delegate = newValue 195 | } 196 | } 197 | 198 | @objc override open var intrinsicContentSize: CGSize { 199 | guard !hasText else { 200 | return super.intrinsicContentSize 201 | } 202 | 203 | var newSize = super.intrinsicContentSize 204 | let placeholderInsets = self.placeholderInsets 205 | newSize.height = placeholderExpectedFrame.height + placeholderInsets.top + placeholderInsets.bottom 206 | 207 | return newSize 208 | } 209 | } 210 | 211 | //#if swift(>=5.1) 212 | //import SwiftUI 213 | // 214 | //struct IQTextViewSwiftUI: UIViewRepresentable { 215 | // func makeUIView(context: Context) -> IQTextView { 216 | // IQTextView(frame: .zero) 217 | // } 218 | // 219 | // func updateUIView(_ view: IQTextView, context: Context) { 220 | // } 221 | //} 222 | // 223 | //struct IQTextViewSwiftUI_Preview: PreviewProvider { 224 | // static var previews: some View { 225 | // IQTextViewSwiftUI() 226 | // } 227 | //} 228 | // 229 | //#endif 230 | // 231 | -------------------------------------------------------------------------------- /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/IQToolbar/IQTitleBarButtonItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IQTitleBarButtonItem.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 | open class IQTitleBarButtonItem: IQBarButtonItem { 28 | 29 | @objc open var titleFont: UIFont? { 30 | 31 | didSet { 32 | if let unwrappedFont = titleFont { 33 | titleButton?.titleLabel?.font = unwrappedFont 34 | } else { 35 | titleButton?.titleLabel?.font = UIFont.systemFont(ofSize: 13) 36 | } 37 | } 38 | } 39 | 40 | @objc override open var title: String? { 41 | didSet { 42 | titleButton?.setTitle(title, for: .normal) 43 | } 44 | } 45 | 46 | /** 47 | titleColor to be used for displaying button text when displaying title (disabled state). 48 | */ 49 | @objc open var titleColor: UIColor? { 50 | 51 | didSet { 52 | 53 | if let color = titleColor { 54 | titleButton?.setTitleColor(color, for: .disabled) 55 | } else { 56 | titleButton?.setTitleColor(UIColor.lightGray, for: .disabled) 57 | } 58 | } 59 | } 60 | 61 | /** 62 | selectableTitleColor to be used for displaying button text when button is enabled. 63 | */ 64 | @objc open var selectableTitleColor: UIColor? { 65 | 66 | didSet { 67 | 68 | if let color = selectableTitleColor { 69 | titleButton?.setTitleColor(color, for: .normal) 70 | } else { 71 | #if swift(>=5.1) 72 | titleButton?.setTitleColor(UIColor.systemBlue, for: .normal) 73 | #else 74 | titleButton?.setTitleColor(UIColor(red: 0.0, green: 0.5, blue: 1.0, alpha: 1), for: .normal) 75 | #endif 76 | } 77 | } 78 | } 79 | 80 | /** 81 | Customized Invocation to be called on title button action. titleInvocation is internally created using setTitleTarget:action: method. 82 | */ 83 | @objc override open var invocation: IQInvocation? { 84 | 85 | didSet { 86 | 87 | if let target = invocation?.target, let action = invocation?.action { 88 | self.isEnabled = true 89 | titleButton?.isEnabled = true 90 | titleButton?.addTarget(target, action: action, for: .touchUpInside) 91 | } else { 92 | self.isEnabled = false 93 | titleButton?.isEnabled = false 94 | titleButton?.removeTarget(nil, action: nil, for: .touchUpInside) 95 | } 96 | } 97 | } 98 | 99 | internal var titleButton: UIButton? 100 | private var _titleView: UIView? 101 | 102 | override init() { 103 | super.init() 104 | } 105 | 106 | @objc public convenience init(title: String?) { 107 | 108 | self.init(title: nil, style: .plain, target: nil, action: nil) 109 | 110 | _titleView = UIView() 111 | _titleView?.backgroundColor = UIColor.clear 112 | 113 | titleButton = UIButton(type: .system) 114 | titleButton?.isEnabled = false 115 | titleButton?.titleLabel?.numberOfLines = 3 116 | titleButton?.setTitleColor(UIColor.lightGray, for: .disabled) 117 | #if swift(>=5.1) 118 | titleButton?.setTitleColor(UIColor.systemBlue, for: .normal) 119 | #else 120 | titleButton?.setTitleColor(UIColor(red: 0.0, green: 0.5, blue: 1.0, alpha: 1), for: .normal) 121 | #endif 122 | titleButton?.backgroundColor = UIColor.clear 123 | titleButton?.titleLabel?.textAlignment = .center 124 | titleButton?.setTitle(title, for: .normal) 125 | titleFont = UIFont.systemFont(ofSize: 13.0) 126 | titleButton?.titleLabel?.font = self.titleFont 127 | _titleView?.addSubview(titleButton!) 128 | 129 | if #available(iOS 11, *) { 130 | 131 | var layoutDefaultLowPriority: UILayoutPriority 132 | var layoutDefaultHighPriority: UILayoutPriority 133 | 134 | #if swift(>=4.0) 135 | let layoutPriorityLowValue = UILayoutPriority.defaultLow.rawValue-1 136 | let layoutPriorityHighValue = UILayoutPriority.defaultHigh.rawValue-1 137 | layoutDefaultLowPriority = UILayoutPriority(rawValue: layoutPriorityLowValue) 138 | layoutDefaultHighPriority = UILayoutPriority(rawValue: layoutPriorityHighValue) 139 | #else 140 | layoutDefaultLowPriority = UILayoutPriorityDefaultLow-1 141 | layoutDefaultHighPriority = UILayoutPriorityDefaultHigh-1 142 | #endif 143 | 144 | _titleView?.translatesAutoresizingMaskIntoConstraints = false 145 | _titleView?.setContentHuggingPriority(layoutDefaultLowPriority, for: .vertical) 146 | _titleView?.setContentHuggingPriority(layoutDefaultLowPriority, for: .horizontal) 147 | _titleView?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .vertical) 148 | _titleView?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .horizontal) 149 | 150 | titleButton?.translatesAutoresizingMaskIntoConstraints = false 151 | titleButton?.setContentHuggingPriority(layoutDefaultLowPriority, for: .vertical) 152 | titleButton?.setContentHuggingPriority(layoutDefaultLowPriority, for: .horizontal) 153 | titleButton?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .vertical) 154 | titleButton?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .horizontal) 155 | 156 | let top = NSLayoutConstraint.init(item: titleButton!, attribute: .top, relatedBy: .equal, toItem: _titleView, attribute: .top, multiplier: 1, constant: 0) 157 | let bottom = NSLayoutConstraint.init(item: titleButton!, attribute: .bottom, relatedBy: .equal, toItem: _titleView, attribute: .bottom, multiplier: 1, constant: 0) 158 | let leading = NSLayoutConstraint.init(item: titleButton!, attribute: .leading, relatedBy: .equal, toItem: _titleView, attribute: .leading, multiplier: 1, constant: 0) 159 | let trailing = NSLayoutConstraint.init(item: titleButton!, attribute: .trailing, relatedBy: .equal, toItem: _titleView, attribute: .trailing, multiplier: 1, constant: 0) 160 | 161 | _titleView?.addConstraints([top, bottom, leading, trailing]) 162 | } else { 163 | _titleView?.autoresizingMask = [.flexibleWidth, .flexibleHeight] 164 | titleButton?.autoresizingMask = [.flexibleWidth, .flexibleHeight] 165 | } 166 | 167 | customView = _titleView 168 | } 169 | 170 | @objc required public init?(coder aDecoder: NSCoder) { 171 | super.init(coder: aDecoder) 172 | } 173 | 174 | deinit { 175 | customView = nil 176 | titleButton?.removeTarget(nil, action: nil, for: .touchUpInside) 177 | _titleView = nil 178 | titleButton = nil 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /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.6) 3 | 4 | DEPENDENCIES: 5 | - IQKeyboardManagerSwift 6 | 7 | SPEC REPOS: 8 | trunk: 9 | - IQKeyboardManagerSwift 10 | 11 | SPEC CHECKSUMS: 12 | IQKeyboardManagerSwift: c7df9d2deb356c04522f5c4b7b6e4ce4d8ed94fe 13 | 14 | PODFILE CHECKSUM: e5f4012936db61c0079fb31eff2c5a6da67ee0d6 15 | 16 | COCOAPODS: 1.10.1 17 | -------------------------------------------------------------------------------- /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.6 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.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "Foundation" -framework "QuartzCore" -framework "UIKit" 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/IQKeyboardManagerSwift 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /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.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "Foundation" -framework "QuartzCore" -framework "UIKit" 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/IQKeyboardManagerSwift 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm-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-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm-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 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm-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 | Generated by CocoaPods - https://cocoapods.org 49 | Title 50 | 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | StringsTable 56 | Acknowledgements 57 | Title 58 | Acknowledgements 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_GenerateDynamicCustomForm : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_GenerateDynamicCustomForm 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm-frameworks-Debug-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm-frameworks-Debug-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm-frameworks-Release-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm-frameworks-Release-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | function on_error { 7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" 8 | } 9 | trap 'on_error $LINENO' ERR 10 | 11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 13 | # frameworks to, so exit 0 (signalling the script phase was successful). 14 | exit 0 15 | fi 16 | 17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 19 | 20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 22 | BCSYMBOLMAP_DIR="BCSymbolMaps" 23 | 24 | 25 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 26 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 27 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 28 | 29 | # Copies and strips a vendored framework 30 | install_framework() 31 | { 32 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 33 | local source="${BUILT_PRODUCTS_DIR}/$1" 34 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 35 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 36 | elif [ -r "$1" ]; then 37 | local source="$1" 38 | fi 39 | 40 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 41 | 42 | if [ -L "${source}" ]; then 43 | echo "Symlinked..." 44 | source="$(readlink "${source}")" 45 | fi 46 | 47 | if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then 48 | # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied 49 | find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do 50 | echo "Installing $f" 51 | install_bcsymbolmap "$f" "$destination" 52 | rm "$f" 53 | done 54 | rmdir "${source}/${BCSYMBOLMAP_DIR}" 55 | fi 56 | 57 | # Use filter instead of exclude so missing patterns don't throw errors. 58 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 59 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 60 | 61 | local basename 62 | basename="$(basename -s .framework "$1")" 63 | binary="${destination}/${basename}.framework/${basename}" 64 | 65 | if ! [ -r "$binary" ]; then 66 | binary="${destination}/${basename}" 67 | elif [ -L "${binary}" ]; then 68 | echo "Destination binary is symlinked..." 69 | dirname="$(dirname "${binary}")" 70 | binary="${dirname}/$(readlink "${binary}")" 71 | fi 72 | 73 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 74 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 75 | strip_invalid_archs "$binary" 76 | fi 77 | 78 | # Resign the code if required by the build settings to avoid unstable apps 79 | code_sign_if_enabled "${destination}/$(basename "$1")" 80 | 81 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 82 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 83 | local swift_runtime_libs 84 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 85 | for lib in $swift_runtime_libs; do 86 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 87 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 88 | code_sign_if_enabled "${destination}/${lib}" 89 | done 90 | fi 91 | } 92 | # Copies and strips a vendored dSYM 93 | install_dsym() { 94 | local source="$1" 95 | warn_missing_arch=${2:-true} 96 | if [ -r "$source" ]; then 97 | # Copy the dSYM into the targets temp dir. 98 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 99 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 100 | 101 | local basename 102 | basename="$(basename -s .dSYM "$source")" 103 | binary_name="$(ls "$source/Contents/Resources/DWARF")" 104 | binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" 105 | 106 | # Strip invalid architectures from the dSYM. 107 | if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then 108 | strip_invalid_archs "$binary" "$warn_missing_arch" 109 | fi 110 | if [[ $STRIP_BINARY_RETVAL == 0 ]]; then 111 | # Move the stripped file into its final destination. 112 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 113 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 114 | else 115 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 116 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" 117 | fi 118 | fi 119 | } 120 | 121 | # Used as a return value for each invocation of `strip_invalid_archs` function. 122 | STRIP_BINARY_RETVAL=0 123 | 124 | # Strip invalid architectures 125 | strip_invalid_archs() { 126 | binary="$1" 127 | warn_missing_arch=${2:-true} 128 | # Get architectures for current target binary 129 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 130 | # Intersect them with the architectures we are building for 131 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 132 | # If there are no archs supported by this binary then warn the user 133 | if [[ -z "$intersected_archs" ]]; then 134 | if [[ "$warn_missing_arch" == "true" ]]; then 135 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 136 | fi 137 | STRIP_BINARY_RETVAL=1 138 | return 139 | fi 140 | stripped="" 141 | for arch in $binary_archs; do 142 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 143 | # Strip non-valid architectures in-place 144 | lipo -remove "$arch" -output "$binary" "$binary" 145 | stripped="$stripped $arch" 146 | fi 147 | done 148 | if [[ "$stripped" ]]; then 149 | echo "Stripped $binary of architectures:$stripped" 150 | fi 151 | STRIP_BINARY_RETVAL=0 152 | } 153 | 154 | # Copies the bcsymbolmap files of a vendored framework 155 | install_bcsymbolmap() { 156 | local bcsymbolmap_path="$1" 157 | local destination="${BUILT_PRODUCTS_DIR}" 158 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" 159 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" 160 | } 161 | 162 | # Signs a framework with the provided identity 163 | code_sign_if_enabled() { 164 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 165 | # Use the current code_sign_identity 166 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 167 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 168 | 169 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 170 | code_sign_cmd="$code_sign_cmd &" 171 | fi 172 | echo "$code_sign_cmd" 173 | eval "$code_sign_cmd" 174 | fi 175 | } 176 | 177 | if [[ "$CONFIGURATION" == "Debug" ]]; then 178 | install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework" 179 | fi 180 | if [[ "$CONFIGURATION" == "Release" ]]; then 181 | install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework" 182 | fi 183 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 184 | wait 185 | fi 186 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm-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_GenerateDynamicCustomFormVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_GenerateDynamicCustomFormVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "QuartzCore" -framework "UIKit" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_GenerateDynamicCustomForm { 2 | umbrella header "Pods-GenerateDynamicCustomForm-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-GenerateDynamicCustomForm/Pods-GenerateDynamicCustomForm.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "QuartzCore" -framework "UIKit" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Generate Dynamic Custom Form: Create your own form within a minute. 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | You can generate a dynamic form view in a few minutes for signup, add a record. Creating a form is very easy. 14 | 15 | ## Preview 16 | ![video](/Media/form.gif) 17 | 18 |

19 | 20 | 21 | 22 |

23 | 24 | ## Table of content :- 25 | 26 | - [Description](#description) 27 | - [Features](#features) 28 | - [Usage](#usage) 29 | - [By Apple](#by-apple) 30 | - [License](#license) 31 | 32 | ## Description 33 | 34 | In this form there are various textFields like Username, email, Password, etc. it has validations also, if validation passes then user can submit form. If any validation doesn't pass then we are showing the validation using the label. The changes are reactive to the textField changes. User can also edit the form and can view changes. 35 | 36 | ## Features 37 | 38 | - TextField with different types like email, password, mobile number, etc. 39 | - Profile Photo and Banner image selection. 40 | - TextView for Address field. 41 | - DatePicker for Date of Birth. 42 | - Picker for department selection. 43 | - ActionSheet for Gender selection. 44 | - PopUpView for selecting multiple/single values. 45 | - Multiple photos selection. 46 | - Switch control for toggling values. 47 | - Checkbox for accepting terms and conditions. 48 | - Submit button for saving data. 49 | - After Successful saving of data one can check entered data and also edit the data. 50 | 51 | ## Usage 52 | 53 | - First create two enums one for Control Type and another one for TextField Type. 54 | 55 | 1. In ControlType enum you can add cases for different controls like, 56 | 57 | - TextField 58 | - ProfileImage 59 | - Switch 60 | - TextView 61 | - CheckBox 62 | 63 | ```Swift 64 | 65 | enum ControlType { 66 | 67 | case checkBox 68 | case textField 69 | case profileImage 70 | case switchType 71 | case textView 72 | case multiPhoto 73 | } 74 | 75 | ``` 76 | 77 | - Based on that you can create different cells in TableView 78 | 79 | 2. In TextField Type enum you can add cases for different TextField types like, 80 | 81 | - Normal Textfield 82 | - Password 83 | - Picker, date picker, etc. 84 | 85 | ```Swift 86 | 87 | enum TextFieldType: Equatable { 88 | 89 | case normal 90 | case password 91 | case dob 92 | case picker 93 | case actionSheet 94 | case selection(Bool?) // Pass true or false for Allowing multiple Selection 95 | case mobileNumber(Bool?) //Pass true or false for Country Flag 96 | } 97 | 98 | ``` 99 | 100 | - Based on that you can create different textfield with different keyboard type and inputView. 101 | 102 | 3. After that create a Structure with two enums that we have created early and add additional properties based on your requirement like, 103 | 104 | - TextField value 105 | - Placeholder 106 | - Placeholder color 107 | - Keyboard type 108 | - Secure text entry, etc. 109 | 110 | ```Swift 111 | 112 | struct FormModel { 113 | 114 | var controlType: ControlType 115 | var txtFieldType: TextFieldType? 116 | var value: String? 117 | var placeHolder: String? 118 | var placeHolder2: String? 119 | var placeHolderColor: UIColor? 120 | var leftImgView: String? 121 | var rightImgView: String? 122 | var isEnabled: Bool? 123 | var isSecure: Bool? 124 | var keyboardType: UIKeyboardType? 125 | var isValid: Bool? 126 | } 127 | 128 | ``` 129 | - Based on this Structure you will be able to create a Model which will be used by Tableview. 130 | 131 | ```Swift 132 | 133 | FormModel(controlType: .profileImage), // Profile Image 134 | 135 | FormModel(controlType: .textField, txtFieldType: .normal, value: "", placeHolder: placeHolderName, placeHolder2: "John Doe", placeHolderColor: .darkGray, leftImgView: "ic_user", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Name 136 | 137 | FormModel(controlType: .textField, txtFieldType: .normal, value: "", placeHolder: placeHolderEmail, placeHolder2: "name@example.com", placeHolderColor: .darkGray, leftImgView: "ic_email", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .emailAddress, isValid: true), // Email 138 | 139 | FormModel(controlType: .textField, txtFieldType: .password, value: "", placeHolder: placeHolderPassword, placeHolder2: "*******", placeHolderColor: .darkGray, leftImgView: "ic_password", rightImgView: nil, isEnabled: true, isSecure: true, keyboardType: .default, isValid: true), // Password 140 | 141 | FormModel(controlType: .textField, txtFieldType: .mobileNumber(false), value: "", placeHolder: placeHolderMobNo, placeHolder2: "1234567890", placeHolderColor: .darkGray, leftImgView: nil, rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .phonePad, isValid: true), // Mobile number 142 | 143 | FormModel(controlType: .textView, value: "", placeHolder: placeHolderAddress, placeHolder2: "21, Satelite Shopping Centre.", placeHolderColor: .darkGray, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Address (TextView) 144 | 145 | FormModel(controlType: .textField, txtFieldType: .dob, value: "", placeHolder: placeHolderDob, placeHolder2: "DD/MM/YYYY", placeHolderColor: .darkGray, leftImgView: "ic_calender", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Date of Birth (Date Picker) 146 | 147 | FormModel(controlType: .textField, txtFieldType: .actionSheet, value: "", placeHolder: placeHolderGender, placeHolder2: "Select Male or Female", placeHolderColor: .darkGray, leftImgView: "ic_gender", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Gender (Action Sheet) 148 | 149 | FormModel(controlType: .textField, txtFieldType: .selection(false), value: "", placeHolder: placeHolderCountry, placeHolder2: "Select Conutry", placeHolderColor: .darkGray, leftImgView: "ic_flag", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Countries India or Other 150 | 151 | FormModel(controlType: .textField, txtFieldType: .selection(true), value: "", placeHolder: placeHolderHobbies, placeHolder2: "Select Hobbies", placeHolderColor: .darkGray, leftImgView: "ic_food", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Hobbies (Multiple Selection View) 152 | 153 | FormModel(controlType: .textField,txtFieldType: .picker, value: "", placeHolder: placeHolderDept, placeHolder2: "Select Department", placeHolderColor: .darkGray, leftImgView: "ic_dept", rightImgView: nil, isEnabled: true, isSecure: false, keyboardType: .default, isValid: true), // Department (Picker) 154 | 155 | FormModel(controlType: .multiPhoto), // Multiple Photos 156 | 157 | FormModel(controlType: .switchType), // Notifications (Switch) 158 | 159 | FormModel(controlType: .checkBox) // Terms and Conditions (CheckBox) 160 | 161 | ``` 162 | 163 | - After this you have to just pass enum case in cellForRow and accordingly pass model data into cell to generate Form. - [Preview](#preview) 164 | 165 | ## By Apple 166 | 167 | - Xcode 12 168 | - iOS 11+ 169 | 170 | ## LICENSE! 171 | 172 | GenerateDynamicCustomForm is [MIT-licensed](/LICENSE). 173 | --------------------------------------------------------------------------------