From 9fe1c6636cb7d86ba1da1f3db8425243dec1dcc4 Mon Sep 17 00:00:00 2001 From: George <george.makhoul@kuwaitnet.com> Date: Sun, 9 Jun 2024 11:04:04 +0300 Subject: [PATCH] add folder action --- .DS_Store | Bin 8196 -> 8196 bytes MiniScanner.xcodeproj/project.pbxproj | 66 +- .../xcschemes/xcschememanagement.plist | 2 +- .../UserInterfaceState.xcuserstate | Bin 63307 -> 100236 bytes MiniScanner/.DS_Store | Bin 8196 -> 10244 bytes .../Extensions/UIButton+Extensions.swift | 65 ++ .../Extensions/UIColor+Extensions.swift | 1 + .../Extensions/UITextView+Extensions.swift | 29 + MiniScanner/Helpers/Globals.swift | 47 ++ MiniScanner/Helpers/UIWindow.swift | 33 + MiniScanner/Modules/.DS_Store | Bin 8196 -> 8196 bytes MiniScanner/Modules/Documents/.DS_Store | Bin 0 -> 6148 bytes .../AllFolderTableViewCell.swift | 10 + .../AllFolderTableViewCell.xib | 4 + .../FolderCollectionViewCell.swift | 0 .../CustomCells/FolderCollectionViewCell.xib | 0 .../KNAlert/KNAlertViewController.swift | 296 +++++++ .../KNAlert/KNAlertViewController.xib | 150 ++++ .../SearchFilesView/SearchFilesView.swift | 92 +++ .../SearchFilesView/SearchFilesView.xib | 100 +++ .../Modules/Documents/Documents.storyboard | 26 +- .../DocumentsTableViewController.swift | 59 +- MiniScanner/Supporting Files/.DS_Store | Bin 8196 -> 8196 bytes .../Supporting Files/AppDelegate.swift | 6 + .../Folder.imageset/Contents.json | 21 + .../Folder.imageset/folder_svgrepo.com.svg | 6 + .../Search.imageset/Contents.json | 21 + .../Search.imageset/IconButton.svg | 11 + .../Supporting Files/BMViewController.swift | 23 + Podfile | 2 + Podfile.lock | 6 +- .../Configuration/IQActiveConfiguration.swift | 203 +++++ .../IQBarButtonItemConfiguration.swift | 96 +++ .../IQKeyboardConfiguration.swift | 39 + .../IQRootControllerConfiguration.swift | 79 ++ .../IQScrollViewConfiguration.swift | 94 +++ .../IQToolbarConfiguration.swift | 75 ++ .../IQToolbarPlaceholderConfiguration.swift | 54 ++ .../IQKeyboardManagerConstants.swift | 151 ++++ .../IQKeyboardManager+Debug.swift | 71 ++ .../IQKeyboardManager+Deprecated.swift | 220 ++++++ .../IQKeyboardManager+Internal.swift | 239 ++++++ .../IQKeyboardManager+Position.swift | 718 +++++++++++++++++ .../IQKeyboardManager+Toolbar.swift | 280 +++++++ .../IQKeyboardManager+ToolbarActions.swift | 205 +++++ ...yboardManager+UIKeyboardNotification.swift | 148 ++++ ...dManager+UITextFieldViewNotification.swift | 46 ++ .../IQKeyboardManager/IQKeyboardManager.swift | 331 ++++++++ .../IQKeyboardManagerCompatible.swift | 59 ++ .../IQTextView/IQPlaceholderable.swift | 39 + .../IQTextView/IQTextView.swift | 208 +++++ .../IQToolbar/IQBarButtonItem.swift | 120 +++ .../IQToolbar/IQInvocation.swift | 42 + .../IQToolbar/IQPreviousNextView.swift | 29 + .../IQToolbar/IQTitleBarButtonItem.swift | 158 ++++ .../IQToolbar/IQToolbar.swift | 181 +++++ .../IQUIView+IQKeyboardToolbar.swift | 319 ++++++++ ...IQUIView+IQKeyboardToolbarDeprecated.swift | 228 ++++++ .../LIsteners/IQKeyboardListener.swift | 115 +++ .../LIsteners/IQTextFieldViewListener.swift | 126 +++ .../LIsteners/Info/IQKeyboardInfo.swift | 135 ++++ .../LIsteners/Info/IQTextFieldViewInfo.swift | 57 ++ .../PrivacyInfo.xcprivacy | 14 + ...rdReturnKeyHandler+TextFieldDelegate.swift | 154 ++++ ...ardReturnKeyHandler+TextViewDelegate.swift | 347 +++++++++ .../IQKeyboardReturnKeyHandler.swift | 261 +++++++ .../IQTextFieldViewInfoModel.swift | 56 ++ .../UIKitExtensions/IQNSArray+Sort.swift | 57 ++ .../IQUICollectionView+Additions.swift | 48 ++ .../IQUIScrollView+Additions.swift | 116 +++ .../IQUITableView+Additions.swift | 48 ++ .../IQUITextFieldView+Additions.swift | 137 ++++ .../UIKitExtensions/IQUIView+Hierarchy.swift | 354 +++++++++ .../IQUIViewController+Additions.swift | 48 ++ .../UIImage+NextPrevious.swift | 60 ++ Pods/IQKeyboardManagerSwift/LICENSE.md | 21 + Pods/IQKeyboardManagerSwift/README.md | 220 ++++++ Pods/Manifest.lock | 6 +- Pods/Pods.xcodeproj/project.pbxproj | 721 +++++++++++++++--- ...nagerSwift-IQKeyboardManagerSwift.xcscheme | 58 ++ .../xcschemes/IQKeyboardManagerSwift.xcscheme | 58 ++ .../xcschemes/xcschememanagement.plist | 18 +- .../IQKeyboardManagerSwift-Info.plist | 26 + .../IQKeyboardManagerSwift-dummy.m | 5 + .../IQKeyboardManagerSwift-prefix.pch | 12 + .../IQKeyboardManagerSwift-umbrella.h | 16 + .../IQKeyboardManagerSwift.debug.xcconfig | 15 + .../IQKeyboardManagerSwift.modulemap | 6 + .../IQKeyboardManagerSwift.release.xcconfig | 15 + ...gerSwift-IQKeyboardManagerSwift-Info.plist | 24 + ...Pods-MiniScanner-acknowledgements.markdown | 25 + .../Pods-MiniScanner-acknowledgements.plist | 31 + ...er-frameworks-Debug-input-files.xcfilelist | 1 + ...r-frameworks-Debug-output-files.xcfilelist | 1 + ...-frameworks-Release-input-files.xcfilelist | 1 + ...frameworks-Release-output-files.xcfilelist | 1 + .../Pods-MiniScanner-frameworks.sh | 2 + .../Pods-MiniScanner.debug.xcconfig | 8 +- .../Pods-MiniScanner.release.xcconfig | 8 +- 99 files changed, 8785 insertions(+), 155 deletions(-) create mode 100644 MiniScanner/Extensions/UIButton+Extensions.swift create mode 100644 MiniScanner/Extensions/UITextView+Extensions.swift create mode 100644 MiniScanner/Helpers/Globals.swift create mode 100644 MiniScanner/Helpers/UIWindow.swift create mode 100644 MiniScanner/Modules/Documents/.DS_Store rename MiniScanner/Modules/Documents/{CustomCells/AllFolderTableViewCell => CustomViews/AllFolderTableView}/AllFolderTableViewCell.swift (92%) rename MiniScanner/Modules/Documents/{CustomCells/AllFolderTableViewCell => CustomViews/AllFolderTableView}/AllFolderTableViewCell.xib (95%) rename MiniScanner/Modules/Documents/{CustomCells/AllFolderTableViewCell => CustomViews/AllFolderTableView}/CustomCells/FolderCollectionViewCell.swift (100%) rename MiniScanner/Modules/Documents/{CustomCells/AllFolderTableViewCell => CustomViews/AllFolderTableView}/CustomCells/FolderCollectionViewCell.xib (100%) create mode 100644 MiniScanner/Modules/Documents/CustomViews/KNAlert/KNAlertViewController.swift create mode 100644 MiniScanner/Modules/Documents/CustomViews/KNAlert/KNAlertViewController.xib create mode 100644 MiniScanner/Modules/Documents/CustomViews/SearchFilesView/SearchFilesView.swift create mode 100644 MiniScanner/Modules/Documents/CustomViews/SearchFilesView/SearchFilesView.xib create mode 100644 MiniScanner/Supporting Files/Assets.xcassets/Folder.imageset/Contents.json create mode 100644 MiniScanner/Supporting Files/Assets.xcassets/Folder.imageset/folder_svgrepo.com.svg create mode 100644 MiniScanner/Supporting Files/Assets.xcassets/Search.imageset/Contents.json create mode 100644 MiniScanner/Supporting Files/Assets.xcassets/Search.imageset/IconButton.svg create mode 100644 MiniScanner/Supporting Files/BMViewController.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQActiveConfiguration.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQBarButtonItemConfiguration.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQKeyboardConfiguration.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQRootControllerConfiguration.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQScrollViewConfiguration.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQToolbarConfiguration.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQToolbarPlaceholderConfiguration.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Debug.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Deprecated.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Internal.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Position.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Toolbar.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+ToolbarActions.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+UIKeyboardNotification.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+UITextFieldViewNotification.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManagerCompatible/IQKeyboardManagerCompatible.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbarDeprecated.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/IQKeyboardListener.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/IQTextFieldViewListener.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/Info/IQKeyboardInfo.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/Info/IQTextFieldViewInfo.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/PrivacyInfo.xcprivacy create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler+TextFieldDelegate.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler+TextViewDelegate.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQTextFieldViewInfoModel.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQNSArray+Sort.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUICollectionView+Additions.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUIScrollView+Additions.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUITableView+Additions.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUITextFieldView+Additions.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUIView+Hierarchy.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUIViewController+Additions.swift create mode 100644 Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/UIImage+NextPrevious.swift create mode 100644 Pods/IQKeyboardManagerSwift/LICENSE.md create mode 100644 Pods/IQKeyboardManagerSwift/README.md create mode 100644 Pods/Pods.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/IQKeyboardManagerSwift-IQKeyboardManagerSwift.xcscheme create mode 100644 Pods/Pods.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/IQKeyboardManagerSwift.xcscheme create mode 100644 Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist create mode 100644 Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-dummy.m create mode 100644 Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch create mode 100644 Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-umbrella.h create mode 100644 Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.debug.xcconfig create mode 100644 Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.modulemap create mode 100644 Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.release.xcconfig create mode 100644 Pods/Target Support Files/IQKeyboardManagerSwift/ResourceBundle-IQKeyboardManagerSwift-IQKeyboardManagerSwift-Info.plist diff --git a/.DS_Store b/.DS_Store index d96b22ba810b27d9169f0bea2509d58baae38c49..cf3157b6c369e2bd71d6f12e9c47e7d83e655f1c 100644 GIT binary patch delta 353 zcmZp1XmOa}&nU7nU^hRb$Yvga2aFu1M#ee{CPo&MPYBp=HWrFtVrF0vpR6D#Hd#TK zy}q0wpP`5$o1vJYfFY3~nIY9PCqFqUCqIdSfkA+Qf$=Ah*82|zKo$c7J3|0aM+!q4 zLncEGhU#uK)jX)G8T5d9@`1Kw!)&nvY5-cp;0VO?kgQ>WYAl8+gsNMQP`9ygG1F#t UiEk|F$nGO(Bh(<WEL^|@09!F>XaE2J delta 51 zcmZp1XmOa}&nU1lU^hRbz-AtS2aFs>W=1*+h86~sPYBp=HWrFt+T6`k!@QYY;v37x H3U+1ykH-&C diff --git a/MiniScanner.xcodeproj/project.pbxproj b/MiniScanner.xcodeproj/project.pbxproj index 3240794..c0cab02 100644 --- a/MiniScanner.xcodeproj/project.pbxproj +++ b/MiniScanner.xcodeproj/project.pbxproj @@ -65,6 +65,15 @@ 535984112C145083003EB6ED /* Poppins-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 535984022C145083003EB6ED /* Poppins-Regular.ttf */; }; 5359841A2C145E55003EB6ED /* DocumentsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535984182C145E55003EB6ED /* DocumentsTableViewCell.swift */; }; 5359841B2C145E55003EB6ED /* DocumentsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 535984192C145E55003EB6ED /* DocumentsTableViewCell.xib */; }; + 5359841E2C14B835003EB6ED /* SearchFilesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5359841D2C14B835003EB6ED /* SearchFilesView.swift */; }; + 535984202C14B8C5003EB6ED /* SearchFilesView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5359841F2C14B8C5003EB6ED /* SearchFilesView.xib */; }; + 53CD5F532C15022E0010424B /* KNAlertViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53CD5F512C15022E0010424B /* KNAlertViewController.xib */; }; + 53CD5F542C15022E0010424B /* KNAlertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53CD5F522C15022E0010424B /* KNAlertViewController.swift */; }; + 53CD5F562C1503150010424B /* BMViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53CD5F552C1503150010424B /* BMViewController.swift */; }; + 53CD5F582C1504CF0010424B /* UIButton+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53CD5F572C1504CF0010424B /* UIButton+Extensions.swift */; }; + 53CD5F5A2C1505500010424B /* UITextView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53CD5F592C1505500010424B /* UITextView+Extensions.swift */; }; + 53CD5F5C2C1505A20010424B /* Globals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53CD5F5B2C1505A20010424B /* Globals.swift */; }; + 53CD5F5E2C1505EC0010424B /* UIWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53CD5F5D2C1505EC0010424B /* UIWindow.swift */; }; 53F21F8B2C1246AF00172BFC /* AllFolderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F21F892C1246AF00172BFC /* AllFolderTableViewCell.swift */; }; 53F21F8C2C1246AF00172BFC /* AllFolderTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53F21F8A2C1246AF00172BFC /* AllFolderTableViewCell.xib */; }; 53F21F912C1248EC00172BFC /* FolderCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F21F8F2C1248EC00172BFC /* FolderCollectionViewCell.swift */; }; @@ -190,6 +199,15 @@ 535984022C145083003EB6ED /* Poppins-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Poppins-Regular.ttf"; sourceTree = "<group>"; }; 535984182C145E55003EB6ED /* DocumentsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentsTableViewCell.swift; sourceTree = "<group>"; }; 535984192C145E55003EB6ED /* DocumentsTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DocumentsTableViewCell.xib; sourceTree = "<group>"; }; + 5359841D2C14B835003EB6ED /* SearchFilesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchFilesView.swift; sourceTree = "<group>"; }; + 5359841F2C14B8C5003EB6ED /* SearchFilesView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SearchFilesView.xib; sourceTree = "<group>"; }; + 53CD5F512C15022E0010424B /* KNAlertViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KNAlertViewController.xib; sourceTree = "<group>"; }; + 53CD5F522C15022E0010424B /* KNAlertViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KNAlertViewController.swift; sourceTree = "<group>"; }; + 53CD5F552C1503150010424B /* BMViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BMViewController.swift; sourceTree = "<group>"; }; + 53CD5F572C1504CF0010424B /* UIButton+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIButton+Extensions.swift"; sourceTree = "<group>"; }; + 53CD5F592C1505500010424B /* UITextView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+Extensions.swift"; sourceTree = "<group>"; }; + 53CD5F5B2C1505A20010424B /* Globals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Globals.swift; sourceTree = "<group>"; }; + 53CD5F5D2C1505EC0010424B /* UIWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIWindow.swift; sourceTree = "<group>"; }; 53F21F892C1246AF00172BFC /* AllFolderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllFolderTableViewCell.swift; sourceTree = "<group>"; }; 53F21F8A2C1246AF00172BFC /* AllFolderTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AllFolderTableViewCell.xib; sourceTree = "<group>"; }; 53F21F8F2C1248EC00172BFC /* FolderCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FolderCollectionViewCell.swift; sourceTree = "<group>"; }; @@ -376,6 +394,8 @@ isa = PBXGroup; children = ( 535983F12C144E87003EB6ED /* Keys.swift */, + 53CD5F5B2C1505A20010424B /* Globals.swift */, + 53CD5F5D2C1505EC0010424B /* UIWindow.swift */, ); path = Helpers; sourceTree = "<group>"; @@ -413,6 +433,25 @@ path = DocumentsTableViewCell; sourceTree = "<group>"; }; + 5359841C2C14B816003EB6ED /* CustomViews */ = { + isa = PBXGroup; + children = ( + 53CD5F502C15022E0010424B /* KNAlert */, + 535984212C14B8CD003EB6ED /* SearchFilesView */, + 53F21F8D2C1248C400172BFC /* AllFolderTableView */, + ); + path = CustomViews; + sourceTree = "<group>"; + }; + 535984212C14B8CD003EB6ED /* SearchFilesView */ = { + isa = PBXGroup; + children = ( + 5359841D2C14B835003EB6ED /* SearchFilesView.swift */, + 5359841F2C14B8C5003EB6ED /* SearchFilesView.xib */, + ); + path = SearchFilesView; + sourceTree = "<group>"; + }; 53AF29712C1098AC0046E9C1 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -421,23 +460,31 @@ name = Frameworks; sourceTree = "<group>"; }; + 53CD5F502C15022E0010424B /* KNAlert */ = { + isa = PBXGroup; + children = ( + 53CD5F512C15022E0010424B /* KNAlertViewController.xib */, + 53CD5F522C15022E0010424B /* KNAlertViewController.swift */, + ); + path = KNAlert; + sourceTree = "<group>"; + }; 53F21F862C12468900172BFC /* CustomCells */ = { isa = PBXGroup; children = ( 535984132C145E22003EB6ED /* DocumentsTableViewCell */, - 53F21F8D2C1248C400172BFC /* AllFolderTableViewCell */, ); path = CustomCells; sourceTree = "<group>"; }; - 53F21F8D2C1248C400172BFC /* AllFolderTableViewCell */ = { + 53F21F8D2C1248C400172BFC /* AllFolderTableView */ = { isa = PBXGroup; children = ( 53F21F8E2C1248D200172BFC /* CustomCells */, 53F21F892C1246AF00172BFC /* AllFolderTableViewCell.swift */, 53F21F8A2C1246AF00172BFC /* AllFolderTableViewCell.xib */, ); - path = AllFolderTableViewCell; + path = AllFolderTableView; sourceTree = "<group>"; }; 53F21F8E2C1248D200172BFC /* CustomCells */ = { @@ -521,6 +568,7 @@ EC8A9B06254DC2EE00F9AF99 /* Documents */ = { isa = PBXGroup; children = ( + 5359841C2C14B816003EB6ED /* CustomViews */, 53F21F862C12468900172BFC /* CustomCells */, EC8A9B1C254DCEC600F9AF99 /* File.swift */, EC0CF217254D8DF200888722 /* Documents.storyboard */, @@ -554,6 +602,8 @@ 535983EA2C142B16003EB6ED /* UILabel+Extensions.swift */, 535983EC2C142B49003EB6ED /* UIFont+Extensions.swift */, 535983EE2C142C9F003EB6ED /* Localization.swift */, + 53CD5F572C1504CF0010424B /* UIButton+Extensions.swift */, + 53CD5F592C1505500010424B /* UITextView+Extensions.swift */, ); path = Extensions; sourceTree = "<group>"; @@ -568,6 +618,7 @@ EC0CF1FF254D8BBF00888722 /* SceneDelegate.swift */, EC0CF208254D8BC000888722 /* LaunchScreen.storyboard */, EC0CF20B254D8BC000888722 /* Info.plist */, + 53CD5F552C1503150010424B /* BMViewController.swift */, ); path = "Supporting Files"; sourceTree = "<group>"; @@ -683,8 +734,10 @@ 53F21FA02C1377B900172BFC /* Tajawal-Medium.ttf in Resources */, 53014FAC2C11A8E80071CE39 /* rotate@3x.png in Resources */, 535984112C145083003EB6ED /* Poppins-Regular.ttf in Resources */, + 53CD5F532C15022E0010424B /* KNAlertViewController.xib in Resources */, EC0CF20A254D8BC000888722 /* LaunchScreen.storyboard in Resources */, 53014FAB2C11A8E80071CE39 /* flash.png in Resources */, + 535984202C14B8C5003EB6ED /* SearchFilesView.xib in Resources */, 53F21F9B2C1377B900172BFC /* Tajawal-ExtraBold.ttf in Resources */, EC0CF218254D8DF200888722 /* Documents.storyboard in Resources */, 53F21F9C2C1377B900172BFC /* Tajawal-Light.ttf in Resources */, @@ -757,14 +810,17 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 5359841E2C14B835003EB6ED /* SearchFilesView.swift in Sources */, 53014FA02C11A8E80071CE39 /* MultiPageScanSession.swift in Sources */, 53014F9A2C11A8E80071CE39 /* CIImage+Utils.swift in Sources */, + 53CD5F5E2C1505EC0010424B /* UIWindow.swift in Sources */, EC8A9B17254DCC2900F9AF99 /* URL+Extensions.swift in Sources */, 535983F22C144E87003EB6ED /* Keys.swift in Sources */, EC70252C254E066400BE1958 /* SettingsViewController.swift in Sources */, EC0CF21D254D8F3900888722 /* String+Extensions.swift in Sources */, EC702540254E1E7500BE1958 /* WalkthroughViewController.swift in Sources */, EC0CF215254D8DE900888722 /* DocumentsTableViewController.swift in Sources */, + 53CD5F542C15022E0010424B /* KNAlertViewController.swift in Sources */, 53014F9D2C11A8E80071CE39 /* Array+Utils.swift in Sources */, 53014FAA2C11A8E80071CE39 /* Quadrilateral.swift in Sources */, 53014FA42C11A8E80071CE39 /* EditScanViewController.swift in Sources */, @@ -786,12 +842,14 @@ EC8A9B10254DC6DD00F9AF99 /* PDFManager.swift in Sources */, ECE9BBAA254E295900D45E43 /* Date+Extensions.swift in Sources */, 53014FA92C11A8E80071CE39 /* QuadrilateralView.swift in Sources */, + 53CD5F562C1503150010424B /* BMViewController.swift in Sources */, EC702546254E1E9E00BE1958 /* WalkthroughModel.swift in Sources */, 53014F912C11A8E80071CE39 /* ShutterButton.swift in Sources */, 53F21F8B2C1246AF00172BFC /* AllFolderTableViewCell.swift in Sources */, 53014FBD2C11A8E80071CE39 /* CaptureSession+Focus.swift in Sources */, 53014F982C11A8E80071CE39 /* URL+Utils.swift in Sources */, EC8A9B00254DBFC700F9AF99 /* UserDefaults+Extensions.swift in Sources */, + 53CD5F5C2C1505A20010424B /* Globals.swift in Sources */, EC8A9B03254DC08800F9AF99 /* NSNotification+Extensions.swift in Sources */, 5359841A2C145E55003EB6ED /* DocumentsTableViewCell.swift in Sources */, EC702522254DF13200BE1958 /* PencilKitViewController.swift in Sources */, @@ -816,12 +874,14 @@ 53014F942C11A8E80071CE39 /* DeviceOrientationHelper.swift in Sources */, EC8A9B27254DE91B00F9AF99 /* DocumentPreviewViewController.swift in Sources */, 53014F9F2C11A8E80071CE39 /* UIImage+Utils.swift in Sources */, + 53CD5F582C1504CF0010424B /* UIButton+Extensions.swift in Sources */, 53014F962C11A8E80071CE39 /* ScannerViewController.swift in Sources */, 53014FA52C11A8E80071CE39 /* EditScanCornerView.swift in Sources */, 53014F8E2C11A8E80071CE39 /* ImageScannerController.swift in Sources */, EC70252B254E066400BE1958 /* SettingsTableViewCell.swift in Sources */, 535983ED2C142B49003EB6ED /* UIFont+Extensions.swift in Sources */, EC8A9AD0254DB5A400F9AF99 /* AppTabBarController.swift in Sources */, + 53CD5F5A2C1505500010424B /* UITextView+Extensions.swift in Sources */, 53F21F912C1248EC00172BFC /* FolderCollectionViewCell.swift in Sources */, ECD43ED625A7BA9500B5A3F2 /* ThemeManager.swift in Sources */, 53014F9C2C11A8E80071CE39 /* CGRect+Utils.swift in Sources */, diff --git a/MiniScanner.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/xcschememanagement.plist b/MiniScanner.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/xcschememanagement.plist index 967e65e..638d735 100644 --- a/MiniScanner.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/MiniScanner.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,7 +7,7 @@ <key>MiniScanner.xcscheme_^#shared#^_</key> <dict> <key>orderHint</key> - <integer>2</integer> + <integer>4</integer> </dict> </dict> </dict> diff --git a/MiniScanner.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate b/MiniScanner.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate index 2650ace59b825022427085332ee8bc820d14776d..1c1a90e7a00a80ba794876925e657e873221ce1b 100644 GIT binary patch literal 100236 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 L|Nna^>zDrlfagF+ literal 63307 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 WdQJhhV8PsP<k#<tu<yTSHvBK75}FwR diff --git a/MiniScanner/.DS_Store b/MiniScanner/.DS_Store index 43430360f8b127aad2173de282fcc5f246d7831b..acf156a5b4057310c05955f3ceb8d582dcd6e107 100644 GIT binary patch delta 313 zcmZp1XbF&DU|?W$DortDU{C-uIe-{M3-C-V6q~50$f&k4U^hRb+GZXBNyf=Pg&Wx| z&2$uuElnpkir7y!6cnATD!2ti8<hnY<>ln(r2{oH0x>&-2SX}D4nqNuEMh43%*jtq z%E?ax84bjaKs;~qKS7zvuLKP+jO7%XA<Mzw%aF*B2gK<R6OhfHJWt30sH=g))W}#z z!NkY{<eJUrg;q1doVU4Aq>XuF0}HDlGtep^P~Zj<t{{(XEd0(qnO`PQgbCtZ4Uja@ W$p#>La)C_m<Zr^wxJ?FH)eZne#Yq4F delta 138 zcmZn(XmOBWU|?W$DortDU;r^WfEYvza8E20o2aMAsIW0$H$S7oW*z}a#>tFATP7Qe z2u_v|Hkhm+(mwgC2>;}3B6^!|iOykUH#5>vFtjk3d_mZL^B!?`W<h44IY1!64J2Ga dMs6(p&ODi4C6I#=ViCjSc%G@7e~Pm+0{{z_9%%po diff --git a/MiniScanner/Extensions/UIButton+Extensions.swift b/MiniScanner/Extensions/UIButton+Extensions.swift new file mode 100644 index 0000000..0d904e8 --- /dev/null +++ b/MiniScanner/Extensions/UIButton+Extensions.swift @@ -0,0 +1,65 @@ +// +// UIButton+Extensions.swift +// MiniScanner +// +// Created by George Makhoul on 09/06/2024. +// Copyright © 2024 AppsNectar. All rights reserved. +// + +import UIKit + +extension UIButton { + + // MARK: - Set Title + func set(title: String?) { + setTitle(title, for: .normal) + + contentVerticalAlignment = .center + contentHorizontalAlignment = .center + } + + func set(localized: String?) { + guard let title = localized else { return } + + setTitle(title.localized, for: .normal) + + contentVerticalAlignment = .center + contentHorizontalAlignment = .center + } + + func set(color: UIColor?) { + setTitleColor(color, for: .normal) + } + + func set(font: UIFont?) { + titleLabel?.font = font + } + + func set(title: String?, color: UIColor?, font: UIFont?) { + set(title: title) + set(color: color) + set(font: font) + } + + func set(localized: String?, color: UIColor?, font: UIFont?) { + set(localized: localized) + set(color: color) + set(font: font) + } + + // MARK: - Set Icon + func set(icon: UIImage = UIImage(named: "") ?? UIImage()) { + setImage(icon.withRenderingMode(.alwaysOriginal), for: .normal) + + contentMode = .center + clipsToBounds = false + + contentVerticalAlignment = .center + contentHorizontalAlignment = .center + } + + func set(colorBackground:UIColor){ + backgroundColor = colorBackground + } +} + diff --git a/MiniScanner/Extensions/UIColor+Extensions.swift b/MiniScanner/Extensions/UIColor+Extensions.swift index 93395b7..36d5f8a 100644 --- a/MiniScanner/Extensions/UIColor+Extensions.swift +++ b/MiniScanner/Extensions/UIColor+Extensions.swift @@ -15,6 +15,7 @@ extension UIColor { static let mainText = hex("#505050") static let titlesText = hex("#888888") static let cellBackground = hex("#F4F4F4") + static let lightButton = hex("#E9EDF2") } extension UIColor { diff --git a/MiniScanner/Extensions/UITextView+Extensions.swift b/MiniScanner/Extensions/UITextView+Extensions.swift new file mode 100644 index 0000000..08697e1 --- /dev/null +++ b/MiniScanner/Extensions/UITextView+Extensions.swift @@ -0,0 +1,29 @@ +// +// UITextView+Extensions.swift +// MiniScanner +// +// Created by George Makhoul on 09/06/2024. +// Copyright © 2024 AppsNectar. All rights reserved. +// +import UIKit + +extension UITextView { + func height() -> CGFloat { + if text.isEmpty { + return 0 + } + + let textView = UITextView(frame: CGRect(x: 0, y: 0, width: frame.width, height: .greatestFiniteMagnitude)) + textView.isHidden = true + textView.isEditable = false + textView.isSelectable = false + textView.isScrollEnabled = false + textView.textContainerInset = .zero + textView.textContainer.lineFragmentPadding = 0 + textView.text = text + textView.font = font + textView.sizeToFit() + + return textView.contentSize.height + } +} diff --git a/MiniScanner/Helpers/Globals.swift b/MiniScanner/Helpers/Globals.swift new file mode 100644 index 0000000..c785d14 --- /dev/null +++ b/MiniScanner/Helpers/Globals.swift @@ -0,0 +1,47 @@ +// +// Globals.swift +// MiniScanner +// +// Created by George Makhoul on 09/06/2024. +// Copyright © 2024 AppsNectar. All rights reserved. +// + +import Foundation +import UIKit +typealias AlertViewClosure = () -> () +typealias AlertViewTextClosure = (String) -> () + +@discardableResult +func alert(confirm: String, + destructive: String, + message: String, + vcToPresent: UIViewController? = nil, + _ completion: AlertViewTextClosure?, + _ cancelCompletion: AlertViewClosure? = nil) -> KNAlertViewController { + + let vc = KNAlertViewController(type: .decision, + message: message.localized, + confirm: confirm.localized, + destructive: destructive.localized) + vc.modalPresentationStyle = .overFullScreen + vc.modalTransitionStyle = .crossDissolve + vc.confirmClosure = completion + vc.destructiveClosure = cancelCompletion + + // Todo to be removed when detecting the error of twice appearing in the pop-up. + + if let vcToPresent = vcToPresent { + vcToPresent.present(vc, animated: false, completion: nil) + + } else { + if let topV = topViewController() as? KNAlertViewController { + return topV + } + topViewController()?.present(vc, animated: false, completion: nil) + } + + + + return vc +} + diff --git a/MiniScanner/Helpers/UIWindow.swift b/MiniScanner/Helpers/UIWindow.swift new file mode 100644 index 0000000..5d3c6de --- /dev/null +++ b/MiniScanner/Helpers/UIWindow.swift @@ -0,0 +1,33 @@ +// +// UIWindow.swift +// MiniScanner +// +// Created by George Makhoul on 09/06/2024. +// Copyright © 2024 AppsNectar. All rights reserved. +// + +import UIKit + +func topViewController() -> UIViewController? { + UIApplication.shared.windows.filter { $0.isKeyWindow }.first?.visibleViewController +} + +extension UIWindow { + var visibleViewController: UIViewController? { + return UIWindow.visibleViewController(viewController: self.rootViewController) + } + + static func visibleViewController(viewController: UIViewController?) -> UIViewController? { + if let navigation = viewController as? UINavigationController { + return UIWindow.visibleViewController(viewController: navigation.visibleViewController) + } else if let tabBar = viewController as? UITabBarController { + return UIWindow.visibleViewController(viewController: tabBar.selectedViewController) + } else { + if let presented = viewController?.presentedViewController { + return UIWindow.visibleViewController(viewController: presented) + } else { + return viewController + } + } + } +} diff --git a/MiniScanner/Modules/.DS_Store b/MiniScanner/Modules/.DS_Store index 4dabfe7b45bb262eb746e33cc700f6ce2212a004..f312c22fc26cb6f2c626c3e2f0e9150e2fc6e32a 100644 GIT binary patch delta 526 zcmZp1XmOa}FDlKzz`)4BAi%(o!;r{O41}2s$r}r&u}^H^-OSFx!ch-Wp~>LL5W?UL zgh;9w!ht$+7_u2k7%~`&81flP8Pb8QFrW#k4CO$z`3!kLIgm^a5T*iIdO-8bf%0h# zC7wC?$w@i+NkG$qmIKXaV9@&y20#`A13!ZcP+u}b>11m`F&Q+)>yZ^t))!RTtS8{W zgr<s77DZLQu-N20A#UXzNd-BX#U%y?*BF_YSy<WF**V#{*<*t<^2>uu5=%;pof0S4 z3wZi+a&mCS3rJK~n;IGGD3};o)aocyTN)Vv*~VtIwVWKH%KFwp@!2`KdHG!+7X!l) z7?5DV3#DOH_vC!xujtO}2Fk*HJUKvQ1G<8rC<+8bB{qrvW8BOx@r^|T7_240V9Wys Ocrj|&Fp^{JZ$<!DSB-E0 delta 115 zcmV-(0F3{HK!iY$PZbsb0003101yBGZ2)BeZUA%uPylkVah3;>fDN+;2m}ZL7L(r* zBD3BQKmwCc6AP2+5ETIllm8Hq4hRWf5Ey%VHaIveAUQUZoe@Qo7Zmc7ITf6<2^RhV Vv49Byvj-UV1hWPf0Rpjr1_8PeAJhN< diff --git a/MiniScanner/Modules/Documents/.DS_Store b/MiniScanner/Modules/Documents/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c8909fced09ac5e392e8dea117008b5b770b46d4 GIT binary patch literal 6148 zcmeHK&u`N(6n@?cX;vZiFr;0OBDhYYbbyAqWNks>N~UoDRFWk?L>f;?N;FlKa)v*K zD}M?93n%!V?V`5ZBu*1UewF<_|M>jkFSQ*Lkr+(l2Si;WY9leWwvb(5+|KEoZI~Jd zDAX8|CN!jkGW@Jr1*`)9x&pj*J6N+*DygF7^;^Ek<Vlpt2t9avI7Hg}r3~IW>zGok z`<m8S-~Nsj)#a&)^*uVx(z5FHeu$0D){UEv<2oJZZSYanK^0chau61;xpX9D7A^cR zI!=>%+}$3^yb9AiDHI`%6Lfj=D$QeA59BnDOT`UzgX^~4ad&4nd(_|G^&a*Q=DXhP zNxuhw|M7h8wr}6N|McbfQ#Q%v7d2}V*y)trGPr=Ra8{N4qsix>$TOLLKo4eb(+EnR zK=TPS%b|Nodq)3)&L~1_NCm~KZ$R7ucliz6y<nUpFeB`~2`!=zF&f7xfV?j!@HkqH zH};;YwHQ2$<rrJ^9Q~MeIp^mZ2SsbwKmqelZg;N1v)V_r3RnfMRsr50JS0ZnV53oO z9mv!b0N6scGWh(lz#Pw@Z?Msb7MRdfpr#6Q#Sof~de8Lp4K^AzorJl32oqVD8;VfT zF}|m|lkhd#+$vxdSXE$C7rT7^KfC<?ze=(ttAJJDzfwT7M!{%+DVekN+~oMI^^o2n qv2njfqoN=)$FXwwDBeL*hBl8Kpl`6zh#Hvv5KuDM%qnoD3j79lp`zyi literal 0 HcmV?d00001 diff --git a/MiniScanner/Modules/Documents/CustomCells/AllFolderTableViewCell/AllFolderTableViewCell.swift b/MiniScanner/Modules/Documents/CustomViews/AllFolderTableView/AllFolderTableViewCell.swift similarity index 92% rename from MiniScanner/Modules/Documents/CustomCells/AllFolderTableViewCell/AllFolderTableViewCell.swift rename to MiniScanner/Modules/Documents/CustomViews/AllFolderTableView/AllFolderTableViewCell.swift index d52dbd7..f13ef36 100644 --- a/MiniScanner/Modules/Documents/CustomCells/AllFolderTableViewCell/AllFolderTableViewCell.swift +++ b/MiniScanner/Modules/Documents/CustomViews/AllFolderTableView/AllFolderTableViewCell.swift @@ -10,12 +10,14 @@ import UIKit protocol AllFolderTableViewCellDelegate { func cellTapped(folder: AppConfigurator.Folder) + func addFolderTapped() } final class AllFolderTableViewCell: UIView { // MARK: - Outlets @IBOutlet private weak var view: UIView! @IBOutlet weak var collectionView: UICollectionView! + @IBOutlet weak var addFolderButton: UIButton! // MARK: - Properties var folders: [AppConfigurator.Folder] = [] @@ -44,6 +46,9 @@ final class AllFolderTableViewCell: UIView { setupCollectionView() } + @IBAction func addFolderButtonTapped(_ sender: UIButton) { + delegate?.addFolderTapped() + } private func setupCollectionView() { let layout = UICollectionViewFlowLayout() @@ -58,6 +63,11 @@ final class AllFolderTableViewCell: UIView { self.collectionView.reloadData() } + func refresh() { + folders = AppConfigurator().getFolders() + self.collectionView.reloadData() + } + func set(selectedFolder: AppConfigurator.Folder, delegate: AllFolderTableViewCellDelegate? ) { self.delegate = delegate for (index, _) in folders.enumerated() { diff --git a/MiniScanner/Modules/Documents/CustomCells/AllFolderTableViewCell/AllFolderTableViewCell.xib b/MiniScanner/Modules/Documents/CustomViews/AllFolderTableView/AllFolderTableViewCell.xib similarity index 95% rename from MiniScanner/Modules/Documents/CustomCells/AllFolderTableViewCell/AllFolderTableViewCell.xib rename to MiniScanner/Modules/Documents/CustomViews/AllFolderTableView/AllFolderTableViewCell.xib index 919a9b7..9094736 100644 --- a/MiniScanner/Modules/Documents/CustomCells/AllFolderTableViewCell/AllFolderTableViewCell.xib +++ b/MiniScanner/Modules/Documents/CustomViews/AllFolderTableView/AllFolderTableViewCell.xib @@ -11,6 +11,7 @@ <objects> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AllFolderTableViewCell" customModule="MiniScanner" customModuleProvider="target"> <connections> + <outlet property="addFolderButton" destination="RpH-94-tHk" id="EvT-GP-STM"/> <outlet property="collectionView" destination="ATv-Qf-nQ6" id="tpu-Qf-4th"/> <outlet property="view" destination="IMm-Qg-H9R" id="eqa-cf-UOK"/> </connections> @@ -43,6 +44,9 @@ <state key="normal" title="Add Folder"> <color key="titleColor" red="0.12156862745098039" green="0.52549019607843139" blue="1" alpha="1" colorSpace="calibratedRGB"/> </state> + <connections> + <action selector="addFolderButtonTapped:" destination="-1" eventType="touchUpInside" id="0jR-JG-JlH"/> + </connections> </button> </subviews> <viewLayoutGuide key="safeArea" id="dvn-eZ-g5z"/> diff --git a/MiniScanner/Modules/Documents/CustomCells/AllFolderTableViewCell/CustomCells/FolderCollectionViewCell.swift b/MiniScanner/Modules/Documents/CustomViews/AllFolderTableView/CustomCells/FolderCollectionViewCell.swift similarity index 100% rename from MiniScanner/Modules/Documents/CustomCells/AllFolderTableViewCell/CustomCells/FolderCollectionViewCell.swift rename to MiniScanner/Modules/Documents/CustomViews/AllFolderTableView/CustomCells/FolderCollectionViewCell.swift diff --git a/MiniScanner/Modules/Documents/CustomCells/AllFolderTableViewCell/CustomCells/FolderCollectionViewCell.xib b/MiniScanner/Modules/Documents/CustomViews/AllFolderTableView/CustomCells/FolderCollectionViewCell.xib similarity index 100% rename from MiniScanner/Modules/Documents/CustomCells/AllFolderTableViewCell/CustomCells/FolderCollectionViewCell.xib rename to MiniScanner/Modules/Documents/CustomViews/AllFolderTableView/CustomCells/FolderCollectionViewCell.xib diff --git a/MiniScanner/Modules/Documents/CustomViews/KNAlert/KNAlertViewController.swift b/MiniScanner/Modules/Documents/CustomViews/KNAlert/KNAlertViewController.swift new file mode 100644 index 0000000..79ca6be --- /dev/null +++ b/MiniScanner/Modules/Documents/CustomViews/KNAlert/KNAlertViewController.swift @@ -0,0 +1,296 @@ +// +// KNAlertViewController.swift +// opa +// +// Created by George Makhoul on 2/23/22. +// + +import UIKit + +final class KNAlertViewController: BMViewController { + + enum KNAlertViewType { + case none + + case success + case error + case decision + } + + // MARK: - Outlets + @IBOutlet private weak var dimView: UIView! + + @IBOutlet private weak var alertView: UIView! + @IBOutlet private weak var alertView_height: NSLayoutConstraint! + + @IBOutlet private weak var confirmationButton: UIButton! + @IBOutlet private weak var destructiveButton: UIButton! + + @IBOutlet private weak var buttonsView_height: NSLayoutConstraint! + + @IBOutlet private weak var messageTextView: UITextView! + @IBOutlet private weak var buttonStackView: UIStackView! + @IBOutlet private weak var buttonView_leading: NSLayoutConstraint! + @IBOutlet private weak var buttonsView_trailing: NSLayoutConstraint! + + @IBOutlet weak var alertImage: UIImageView! + @IBOutlet weak var folderName: UITextField! + + // MARK: - Properties + + private let dimViewColor: UIColor = UIColor.gray.withAlphaComponent(0.6) + private var type: KNAlertViewType = .none + private var content_height: CGFloat = 150 + + private var message: String = "" + + private var confirmButtonTitle: String = "Yes" + private var destructiveButtonTitle: String = "No" + + var shouldDismissAndLogin: Bool = false + + var confirmClosure: AlertViewTextClosure? + var destructiveClosure: AlertViewClosure? + + private let BUTTON_HEIGHT: CGFloat = 52 + private let BUTTON_WIDTH: CGFloat = 128 + + private var buttonsView_Spacing: CGFloat = 26 + private var folderNameText: String = "" + + // MARK: - Init + init(type: KNAlertViewType, message: String) { + super.init() + + self.type = type + self.message = message + } + + init(type: KNAlertViewType, message: String, confirm: String, destructive: String) { + super.init() + + self.type = type + self.message = message + + confirmButtonTitle = confirm + destructiveButtonTitle = destructive + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + + view.endEditing(true) + + setupUI() + updateUI() + updateHeight() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + showPopup() + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + } +} + +// MARK: - UI +extension KNAlertViewController { + private func setupUI() { + view.backgroundColor = .clear + dimView.backgroundColor = dimViewColor + + // alert + alertView.layer.cornerRadius = 16 + alertView.layer.borderColor = UIColor.white.cgColor + + // text + messageTextView.textAlignment = .center + messageTextView.textColor = .black + messageTextView.font = .medium(16) + messageTextView.text = "" + messageTextView.isEditable = false + messageTextView.isSelectable = false + messageTextView.textContainerInset = .zero + messageTextView.textContainer.lineFragmentPadding = 0 + + // buttons stack + buttonStackView.spacing = 27 + buttonStackView.backgroundColor = .clear + + // buttons + confirmationButton.set(localized: confirmButtonTitle, color: .white, font: .bold(17)) + confirmationButton.layer.cornerRadius = 20 + confirmationButton.backgroundColor = .mainText + + confirmationButton.addTarget(self, action: #selector(confirmationButtonTapped), for: .touchUpInside) + + destructiveButton.set(localized: destructiveButtonTitle, color: .titlesText, font: .bold(17)) + destructiveButton.layer.cornerRadius = 20 + destructiveButton.backgroundColor = .lightButton + + destructiveButton.addTarget(self, action: #selector(destructiveButtonTapped), for: .touchUpInside) + + buttonView_leading.constant = buttonsView_Spacing + buttonsView_trailing.constant = buttonsView_Spacing + + destructiveButton.isHidden = true + + confirmationButton.isHidden = true + + buttonsView_height.constant = 0 + + folderName.addTarget(self, action: #selector(textChanged), for: .editingChanged) + } + + @objc func textChanged() { + folderNameText = folderName.text ?? "" + } + + private func updateHeight() { + var height: CGFloat = 0 + + height += 28 + height += 20 + height += 28 + height += buttonsView_height.constant + height += 66 + height += 108 + height += 38 + height += 27 + //@TODO @LOW dynamic height? using a tableView? + let message_height = messageTextView.height() + + if message_height > 500 { + height += 500 + messageTextView.isScrollEnabled = true + } else { + height += message_height + messageTextView.isScrollEnabled = false + } + + if height < 130 { + content_height = 130 + } else { + content_height = height + 20 + } + } + + private func updateUI() { + messageTextView.text = message + + destructiveButton.isHidden = true + + confirmationButton.isHidden = true + + buttonsView_height.constant = 0 + + switch type { + case .success, .error: + let alert_width = alertView.frame.width + + buttonsView_Spacing = (alert_width - BUTTON_WIDTH) / 2 + + buttonView_leading.constant = buttonsView_Spacing + buttonsView_trailing.constant = buttonsView_Spacing + + confirmationButton.isHidden = false + confirmationButton.setTitle("OK", for: .normal) + buttonsView_height.constant = BUTTON_HEIGHT + + case .decision: + buttonsView_Spacing = 26 + + buttonView_leading.constant = buttonsView_Spacing + buttonsView_trailing.constant = buttonsView_Spacing + + destructiveButton.isHidden = false + + confirmationButton.isHidden = false + + confirmationButton.setTitle("Yes", for: .normal) + + buttonsView_height.constant = BUTTON_HEIGHT + + if !destructiveButtonTitle.isEmpty && !confirmButtonTitle.isEmpty { + confirmationButton.set(localized: confirmButtonTitle, color: .white, font: .bold(17)) + confirmationButton.layer.cornerRadius = 20 + + confirmationButton.backgroundColor = .mainText + + destructiveButton.set(title: destructiveButtonTitle, color: .titlesText, font: .bold(17)) + destructiveButton.layer.cornerRadius = 20 + destructiveButton.backgroundColor = .lightButton + } + default: + break + } + } + + private func showPopup() { + var transform = CGAffineTransform.identity + transform = transform.translatedBy(x: 0, y: UIScreen.main.bounds.height) + transform = transform.scaledBy(x: 0, y: 0) + alertView.transform = transform + + dimView.alpha = 0 + UIView.animate(withDuration: 0.3) { [weak self] in + self?.alertView_height.constant = (self?.content_height ?? 0) + self?.alertView.transform = .identity + self?.dimView.alpha = 1.0 + + self?.view.layoutIfNeeded() + } + } + + @objc private func dismissPopup() { + UIView.animate(withDuration: 0.3) { [weak self] in + var transform = CGAffineTransform.identity + transform = transform.translatedBy(x: 0, y: UIScreen.main.bounds.height) + transform = transform.scaledBy(x: 0, y: 0) + self?.alertView.transform = transform + + self?.dimView.alpha = 0 + self?.view.layoutIfNeeded() + } completion: { [weak self] finished in + if finished { + self?.dismiss(animated: false) { + // + } + } + } + } +} + +// MARK: - Delegate +extension KNAlertViewController { + @objc func destructiveButtonTapped() { + if let closure = destructiveClosure { + closure() + } else { + dismissPopup() + } + } + + @objc func confirmationButtonTapped() { + if let closure = confirmClosure { + closure(folderNameText) + } else { + dismissPopup() + } + } + + func hideEverything() { + view.isHidden = true + } +} + diff --git a/MiniScanner/Modules/Documents/CustomViews/KNAlert/KNAlertViewController.xib b/MiniScanner/Modules/Documents/CustomViews/KNAlert/KNAlertViewController.xib new file mode 100644 index 0000000..1af5265 --- /dev/null +++ b/MiniScanner/Modules/Documents/CustomViews/KNAlert/KNAlertViewController.xib @@ -0,0 +1,150 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> + <device id="retina6_1" orientation="portrait" appearance="light"/> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/> + <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <capability name="System colors in document resources" minToolsVersion="11.0"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <objects> + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="KNAlertViewController" customModule="MiniScanner" customModuleProvider="target"> + <connections> + <outlet property="alertImage" destination="xhV-HQ-Eg2" id="QFC-Qh-Pq9"/> + <outlet property="alertView" destination="HEa-7L-mBd" id="MYI-il-dxf"/> + <outlet property="alertView_height" destination="bda-Ts-u7O" id="0oR-a5-EyR"/> + <outlet property="buttonStackView" destination="mFa-hh-JzT" id="05H-L9-JXx"/> + <outlet property="buttonView_leading" destination="GIS-Wm-udf" id="2DG-Cf-wnA"/> + <outlet property="buttonsView_height" destination="H5D-nn-1fO" id="BRt-Rc-rfw"/> + <outlet property="buttonsView_trailing" destination="vzh-SN-Ztf" id="Brk-ob-y0k"/> + <outlet property="confirmationButton" destination="6RT-mM-MZO" id="DAx-Kd-q0W"/> + <outlet property="destructiveButton" destination="M8l-cs-Sk1" id="RMQ-kp-MLt"/> + <outlet property="dimView" destination="Ke8-mm-O5l" id="m3R-JB-7UI"/> + <outlet property="folderName" destination="lRh-I6-j02" id="fzN-a5-EaL"/> + <outlet property="messageTextView" destination="KRY-Mp-Cgi" id="PrE-JR-vbV"/> + <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> + </connections> + </placeholder> + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> + <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT"> + <rect key="frame" x="0.0" y="0.0" width="414" height="896"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ke8-mm-O5l" userLabel="dimView"> + <rect key="frame" x="0.0" y="0.0" width="414" height="896"/> + <color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </view> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="HEa-7L-mBd" userLabel="alertView"> + <rect key="frame" x="16" y="230" width="382" height="450"/> + <subviews> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Folder" translatesAutoresizingMaskIntoConstraints="NO" id="xhV-HQ-Eg2"> + <rect key="frame" x="137" y="38" width="108" height="108"/> + <constraints> + <constraint firstAttribute="height" constant="108" id="Jgf-qb-27O"/> + <constraint firstAttribute="width" constant="108" id="SkA-ZS-9Bt"/> + </constraints> + </imageView> + <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" text=" " textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="KRY-Mp-Cgi"> + <rect key="frame" x="28" y="176" width="326" height="74"/> + <color key="textColor" systemColor="labelColor"/> + <fontDescription key="fontDescription" name="HelveticaNeue-Medium" family="Helvetica Neue" pointSize="20"/> + <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/> + </textView> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0Iw-HP-6vl" userLabel="buttonsView"> + <rect key="frame" x="26" y="370" width="330" height="52"/> + <subviews> + <stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="mFa-hh-JzT"> + <rect key="frame" x="0.0" y="0.0" width="330" height="52"/> + <subviews> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="M8l-cs-Sk1" userLabel="destructiveButton"> + <rect key="frame" x="0.0" y="0.0" width="165" height="52"/> + <state key="normal" title=" "/> + </button> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6RT-mM-MZO" userLabel="confirmButton"> + <rect key="frame" x="165" y="0.0" width="165" height="52"/> + <constraints> + <constraint firstAttribute="height" constant="366" id="cUE-2O-C4X"/> + </constraints> + <state key="normal" title=" "/> + </button> + </subviews> + </stackView> + </subviews> + <color key="backgroundColor" systemColor="systemBackgroundColor"/> + <constraints> + <constraint firstItem="mFa-hh-JzT" firstAttribute="top" secondItem="0Iw-HP-6vl" secondAttribute="top" id="02x-AD-Zhw"/> + <constraint firstItem="mFa-hh-JzT" firstAttribute="leading" secondItem="0Iw-HP-6vl" secondAttribute="leading" id="DR3-dd-o3o"/> + <constraint firstAttribute="trailing" secondItem="mFa-hh-JzT" secondAttribute="trailing" id="EvO-ip-xRD"/> + <constraint firstAttribute="height" constant="52" id="H5D-nn-1fO"/> + <constraint firstAttribute="bottom" secondItem="mFa-hh-JzT" secondAttribute="bottom" id="heB-PX-nNZ"/> + </constraints> + </view> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="S4K-Dk-4tv"> + <rect key="frame" x="24" y="277" width="334" height="66"/> + <subviews> + <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Folder name" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="lRh-I6-j02"> + <rect key="frame" x="0.0" y="0.0" width="334" height="66"/> + <color key="backgroundColor" red="0.87450980392156863" green="0.87450980392156863" blue="0.87450980392156863" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/> + <fontDescription key="fontDescription" type="system" pointSize="20"/> + <textInputTraits key="textInputTraits"/> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="color" keyPath="placeholderLabel.textColor"> + <color key="value" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + </textField> + </subviews> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstItem="lRh-I6-j02" firstAttribute="leading" secondItem="S4K-Dk-4tv" secondAttribute="leading" id="CNW-sk-bPe"/> + <constraint firstAttribute="bottom" secondItem="lRh-I6-j02" secondAttribute="bottom" id="Skj-JH-h9X"/> + <constraint firstItem="lRh-I6-j02" firstAttribute="top" secondItem="S4K-Dk-4tv" secondAttribute="top" id="ncu-Jk-BzF"/> + <constraint firstAttribute="height" constant="66" id="pDD-hz-1vW"/> + <constraint firstAttribute="trailing" secondItem="lRh-I6-j02" secondAttribute="trailing" id="qa1-gG-zXR"/> + </constraints> + </view> + </subviews> + <color key="backgroundColor" systemColor="systemBackgroundColor"/> + <constraints> + <constraint firstItem="0Iw-HP-6vl" firstAttribute="top" secondItem="S4K-Dk-4tv" secondAttribute="bottom" constant="27" id="05e-QI-0KE"/> + <constraint firstItem="S4K-Dk-4tv" firstAttribute="top" secondItem="KRY-Mp-Cgi" secondAttribute="bottom" constant="27" id="6bh-Pg-HSv"/> + <constraint firstItem="KRY-Mp-Cgi" firstAttribute="leading" secondItem="HEa-7L-mBd" secondAttribute="leading" constant="28" id="7se-55-EI4"/> + <constraint firstItem="xhV-HQ-Eg2" firstAttribute="centerX" secondItem="HEa-7L-mBd" secondAttribute="centerX" id="8db-LY-2uf"/> + <constraint firstItem="0Iw-HP-6vl" firstAttribute="leading" secondItem="HEa-7L-mBd" secondAttribute="leading" constant="26" id="GIS-Wm-udf"/> + <constraint firstItem="KRY-Mp-Cgi" firstAttribute="top" secondItem="xhV-HQ-Eg2" secondAttribute="bottom" constant="30" id="KjU-E5-EGg"/> + <constraint firstAttribute="trailing" secondItem="KRY-Mp-Cgi" secondAttribute="trailing" constant="28" id="Kjz-ul-BMl"/> + <constraint firstItem="S4K-Dk-4tv" firstAttribute="leading" secondItem="HEa-7L-mBd" secondAttribute="leading" constant="24" id="SON-o3-IxS"/> + <constraint firstAttribute="trailing" secondItem="S4K-Dk-4tv" secondAttribute="trailing" constant="24" id="Seq-Zv-hrh"/> + <constraint firstAttribute="height" constant="450" id="bda-Ts-u7O"/> + <constraint firstItem="xhV-HQ-Eg2" firstAttribute="top" secondItem="HEa-7L-mBd" secondAttribute="top" constant="38" id="uzx-aJ-KBa"/> + <constraint firstAttribute="trailing" secondItem="0Iw-HP-6vl" secondAttribute="trailing" constant="26" id="vzh-SN-Ztf"/> + <constraint firstAttribute="bottom" secondItem="0Iw-HP-6vl" secondAttribute="bottom" constant="28" id="zIz-7A-Fhl"/> + </constraints> + </view> + </subviews> + <viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstItem="fnl-2z-Ty3" firstAttribute="leading" secondItem="HEa-7L-mBd" secondAttribute="leading" constant="-16" id="J59-Wx-NLp"/> + <constraint firstItem="Ke8-mm-O5l" firstAttribute="bottom" secondItem="i5M-Pr-FkT" secondAttribute="bottom" id="OO0-29-GbT"/> + <constraint firstAttribute="trailing" secondItem="Ke8-mm-O5l" secondAttribute="trailing" id="XEW-zk-P9r"/> + <constraint firstItem="Ke8-mm-O5l" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="gnh-Wf-UUa"/> + <constraint firstAttribute="leading" secondItem="Ke8-mm-O5l" secondAttribute="leading" id="jUn-qr-3a3"/> + <constraint firstItem="HEa-7L-mBd" firstAttribute="centerY" secondItem="fnl-2z-Ty3" secondAttribute="centerY" id="l3t-nt-x4P"/> + <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="HEa-7L-mBd" secondAttribute="trailing" constant="16" id="wTo-Vm-Gmy"/> + </constraints> + <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> + <point key="canvasLocation" x="131.8840579710145" y="131.91964285714286"/> + </view> + </objects> + <resources> + <image name="Folder" width="108" height="108"/> + <systemColor name="labelColor"> + <color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </systemColor> + <systemColor name="systemBackgroundColor"> + <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </systemColor> + </resources> +</document> diff --git a/MiniScanner/Modules/Documents/CustomViews/SearchFilesView/SearchFilesView.swift b/MiniScanner/Modules/Documents/CustomViews/SearchFilesView/SearchFilesView.swift new file mode 100644 index 0000000..4be47b2 --- /dev/null +++ b/MiniScanner/Modules/Documents/CustomViews/SearchFilesView/SearchFilesView.swift @@ -0,0 +1,92 @@ +// +// SearchFilesView.swift +// MiniScanner +// +// Created by George Makhoul on 08/06/2024. +// Copyright © 2024 AppsNectar. All rights reserved. +// + +import UIKit +protocol SearchFilesViewDelegate { + func searchfor(text: String) +} + +final class SearchFilesView: UIView { + // MARK: - Outlets + @IBOutlet private weak var view: UIView! + @IBOutlet private weak var titleLabel: UILabel! + @IBOutlet private weak var searchButton: UIButton! + @IBOutlet weak var searchTextField: UITextField! + @IBOutlet weak var exitButton: UIButton! + @IBOutlet weak var boxView: UIView! + + // MARK: - Properties + var delegate: SearchFilesViewDelegate? + + // MARK: - LifeCycle + override init(frame: CGRect) { + super.init(frame: frame) + setupNib() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + setupNib() + } + + private func setupNib() { + Bundle.main.loadNibNamed("SearchFilesView", owner: self, options: nil) + view.frame = bounds + view.autoresizingMask = [.flexibleHeight, .flexibleWidth] + addSubview(view) + setupUI() + } + + @IBAction func searchTapped(_ sender: UIButton) { + searchTextField.isHidden = !searchTextField.isHidden + titleLabel.isHidden = !searchTextField.isHidden + searchButton.isHidden = !searchTextField.isHidden + exitButton.isHidden = searchTextField.isHidden + if !searchTextField.isHidden { + searchTextField.clearButtonMode = .always + searchTextField.becomeFirstResponder() + } + } + + @IBAction func exitButtonTapped(_ sender: UIButton) { + searchTextField.isHidden = true + exitButton.isHidden = true + searchButton.isHidden = false + titleLabel.isHidden = false + searchTextField.text = "" + searchTextField.resignFirstResponder() + delegate?.searchfor(text: "") + } + + private func setupUI() { + boxView.layer.cornerRadius = 30 + titleLabel.set(text: "Folder files", color: .titlesText, font: .bold(20)) + searchTextField.isHidden = true + searchTextField.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged) + searchTextField.delegate = self + titleLabel.isHidden = !searchTextField.isHidden + searchButton.isHidden = !searchTextField.isHidden + } +} + +// MARK: - TextFieldDelegate +extension SearchFilesView: UITextFieldDelegate { + @objc func textFieldDidChange() { + + if let text = searchTextField.text { + if text.count >= 1 || text.count == 0 { + delegate?.searchfor(text: text) + } + } + } + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + textField.resignFirstResponder() + return true + } +} diff --git a/MiniScanner/Modules/Documents/CustomViews/SearchFilesView/SearchFilesView.xib b/MiniScanner/Modules/Documents/CustomViews/SearchFilesView/SearchFilesView.xib new file mode 100644 index 0000000..fab1890 --- /dev/null +++ b/MiniScanner/Modules/Documents/CustomViews/SearchFilesView/SearchFilesView.xib @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> + <device id="retina6_12" orientation="portrait" appearance="light"/> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/> + <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <objects> + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="SearchFilesView" customModule="MiniScanner" customModuleProvider="target"> + <connections> + <outlet property="boxView" destination="7OB-D5-Eoo" id="dj7-CY-O95"/> + <outlet property="exitButton" destination="gib-7t-l8K" id="lOb-pi-xXf"/> + <outlet property="searchButton" destination="Wvg-I0-BpL" id="aBu-tp-Mv7"/> + <outlet property="searchTextField" destination="j1b-ot-aeo" id="lQj-pM-Wl0"/> + <outlet property="titleLabel" destination="Tx0-9F-C5a" id="UwJ-Id-ivY"/> + <outlet property="view" destination="iN0-l3-epB" id="73W-ss-jde"/> + </connections> + </placeholder> + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> + <view contentMode="scaleToFill" id="iN0-l3-epB"> + <rect key="frame" x="0.0" y="0.0" width="393" height="61"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7OB-D5-Eoo"> + <rect key="frame" x="0.0" y="0.0" width="393" height="61"/> + <subviews> + <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="j1b-ot-aeo"> + <rect key="frame" x="20" y="8" width="291" height="45"/> + <constraints> + <constraint firstAttribute="height" constant="45" id="8og-JU-Tk9"/> + </constraints> + <fontDescription key="fontDescription" type="system" pointSize="14"/> + <textInputTraits key="textInputTraits"/> + </textField> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tx0-9F-C5a"> + <rect key="frame" x="20" y="21" width="42" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="gib-7t-l8K"> + <rect key="frame" x="323" y="9.6666666666666643" width="42" height="42"/> + <constraints> + <constraint firstAttribute="height" constant="42" id="BV7-Zr-s9R"/> + <constraint firstAttribute="width" constant="42" id="psC-sW-GBY"/> + </constraints> + <color key="tintColor" red="0.53333336109999996" green="0.53333336109999996" blue="0.53333336109999996" alpha="1" colorSpace="custom" customColorSpace="displayP3"/> + <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> + <state key="normal" image="x.circle.fill" catalog="system"/> + <connections> + <action selector="exitButtonTapped:" destination="-1" eventType="touchUpInside" id="or4-1k-2KT"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Wvg-I0-BpL"> + <rect key="frame" x="323" y="10.666666666666664" width="42" height="42"/> + <constraints> + <constraint firstAttribute="height" constant="42" id="FP9-rR-OWb"/> + <constraint firstAttribute="width" constant="42" id="dz8-nZ-KX5"/> + </constraints> + <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> + <state key="normal" image="Search"/> + <connections> + <action selector="searchTapped:" destination="-1" eventType="touchUpInside" id="ZKY-QX-lFi"/> + </connections> + </button> + </subviews> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstAttribute="trailing" secondItem="gib-7t-l8K" secondAttribute="trailing" constant="28" id="3oe-ES-QCQ"/> + <constraint firstItem="j1b-ot-aeo" firstAttribute="leading" secondItem="7OB-D5-Eoo" secondAttribute="leading" constant="20" symbolic="YES" id="70a-0m-DKY"/> + <constraint firstAttribute="trailing" secondItem="Wvg-I0-BpL" secondAttribute="trailing" constant="28" id="9N5-IU-kgT"/> + <constraint firstItem="Wvg-I0-BpL" firstAttribute="centerY" secondItem="Tx0-9F-C5a" secondAttribute="centerY" id="E7k-Gg-A5d"/> + <constraint firstItem="gib-7t-l8K" firstAttribute="leading" secondItem="j1b-ot-aeo" secondAttribute="trailing" constant="12" id="J5S-ey-UeG"/> + <constraint firstItem="gib-7t-l8K" firstAttribute="centerY" secondItem="7OB-D5-Eoo" secondAttribute="centerY" id="VKM-wG-a7T"/> + <constraint firstItem="j1b-ot-aeo" firstAttribute="centerY" secondItem="7OB-D5-Eoo" secondAttribute="centerY" id="YRo-yg-X1w"/> + <constraint firstItem="Tx0-9F-C5a" firstAttribute="leading" secondItem="7OB-D5-Eoo" secondAttribute="leading" constant="20" symbolic="YES" id="ok5-BG-cY2"/> + <constraint firstItem="Tx0-9F-C5a" firstAttribute="centerY" secondItem="7OB-D5-Eoo" secondAttribute="centerY" constant="1" id="pBx-eA-4e3"/> + <constraint firstItem="j1b-ot-aeo" firstAttribute="leading" secondItem="7OB-D5-Eoo" secondAttribute="leading" constant="20" symbolic="YES" id="sHT-8G-9II"/> + </constraints> + </view> + </subviews> + <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstItem="7OB-D5-Eoo" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="ThP-ZW-8td"/> + <constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="7OB-D5-Eoo" secondAttribute="trailing" id="gTR-a7-A7M"/> + <constraint firstAttribute="bottom" secondItem="7OB-D5-Eoo" secondAttribute="bottom" id="jeU-kj-eLj"/> + <constraint firstItem="7OB-D5-Eoo" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="zk4-jX-U1J"/> + </constraints> + <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> + <point key="canvasLocation" x="101.5267175572519" y="-258.80281690140845"/> + </view> + </objects> + <resources> + <image name="Search" width="42" height="42"/> + <image name="x.circle.fill" catalog="system" width="128" height="123"/> + </resources> +</document> diff --git a/MiniScanner/Modules/Documents/Documents.storyboard b/MiniScanner/Modules/Documents/Documents.storyboard index 392273d..4ca2ef5 100644 --- a/MiniScanner/Modules/Documents/Documents.storyboard +++ b/MiniScanner/Modules/Documents/Documents.storyboard @@ -12,7 +12,6 @@ <!--Table View Controller--> <scene sceneID="H5o-MQ-blf"> <objects> - <placeholder placeholderIdentifier="IBFirstResponder" id="zgv-ee-Jgu" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> <tableViewController id="gvn-iJ-Pzo" sceneMemberID="viewController"> <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="bPB-U2-F5q"> <rect key="frame" x="0.0" y="0.0" width="414" height="896"/> @@ -25,6 +24,7 @@ </tableView> <navigationItem key="navigationItem" id="eDl-rz-mCg"/> </tableViewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="zgv-ee-Jgu" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> </objects> <point key="canvasLocation" x="1999" y="-614"/> </scene> @@ -50,21 +50,23 @@ <rect key="frame" x="0.0" y="80" width="414" height="450"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/> </tableView> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yDO-Jh-xQu"> - <rect key="frame" x="22" y="33" width="42" height="21"/> - <fontDescription key="fontDescription" type="system" pointSize="17"/> - <nil key="textColor"/> - <nil key="highlightedColor"/> - </label> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="VPm-dN-3u7" customClass="SearchFilesView" customModule="MiniScanner" customModuleProvider="target"> + <rect key="frame" x="0.0" y="10" width="414" height="70"/> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstAttribute="height" constant="70" id="eOB-Os-XoP"/> + </constraints> + </view> </subviews> <color key="backgroundColor" systemColor="systemBackgroundColor"/> <constraints> - <constraint firstItem="60c-jY-XTk" firstAttribute="top" secondItem="27n-zM-bE7" secondAttribute="top" constant="80" id="FBD-jw-cc7"/> + <constraint firstItem="60c-jY-XTk" firstAttribute="top" secondItem="VPm-dN-3u7" secondAttribute="bottom" id="EMn-mL-Oiq"/> <constraint firstItem="60c-jY-XTk" firstAttribute="leading" secondItem="27n-zM-bE7" secondAttribute="leading" id="MOu-65-XoB"/> - <constraint firstItem="60c-jY-XTk" firstAttribute="top" secondItem="yDO-Jh-xQu" secondAttribute="bottom" constant="26" id="cjQ-4R-Uh2"/> + <constraint firstAttribute="trailing" secondItem="VPm-dN-3u7" secondAttribute="trailing" id="SqO-9W-uqD"/> <constraint firstAttribute="bottom" secondItem="60c-jY-XTk" secondAttribute="bottom" constant="24" id="hxd-n2-r1v"/> <constraint firstAttribute="trailing" secondItem="60c-jY-XTk" secondAttribute="trailing" id="odE-ga-ZOX"/> - <constraint firstItem="yDO-Jh-xQu" firstAttribute="leading" secondItem="27n-zM-bE7" secondAttribute="leading" constant="22" id="x0T-fP-0hf"/> + <constraint firstItem="VPm-dN-3u7" firstAttribute="top" secondItem="27n-zM-bE7" secondAttribute="top" constant="10" id="y4F-ru-A1g"/> + <constraint firstItem="VPm-dN-3u7" firstAttribute="leading" secondItem="27n-zM-bE7" secondAttribute="leading" id="zOO-hG-XV6"/> </constraints> </view> </subviews> @@ -83,13 +85,15 @@ <navigationItem key="navigationItem" id="rJm-3G-CYc"/> <connections> <outlet property="AllFolderView" destination="7uR-kU-jQL" id="fWz-Eg-JcR"/> + <outlet property="allFolderView_height" destination="qZv-Hx-LJ7" id="4LY-Kr-mUv"/> <outlet property="fixedTableSheet" destination="27n-zM-bE7" id="5zJ-W1-AKn"/> + <outlet property="searchForFilesView" destination="VPm-dN-3u7" id="YhB-5N-43R"/> <outlet property="tableView" destination="60c-jY-XTk" id="ck5-Mw-NDZ"/> </connections> </viewController> <placeholder placeholderIdentifier="IBFirstResponder" id="SsQ-by-Voz" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> </objects> - <point key="canvasLocation" x="2767" y="-98"/> + <point key="canvasLocation" x="2766.666666666667" y="-98.4375"/> </scene> <!--View Controller--> <scene sceneID="3WQ-hx-1mu"> diff --git a/MiniScanner/Modules/Documents/DocumentsTableViewController.swift b/MiniScanner/Modules/Documents/DocumentsTableViewController.swift index cbf4b61..9cedbe3 100644 --- a/MiniScanner/Modules/Documents/DocumentsTableViewController.swift +++ b/MiniScanner/Modules/Documents/DocumentsTableViewController.swift @@ -22,8 +22,11 @@ final class DocumentsTableViewController: UIViewController, UITableViewDelegate, @IBOutlet weak var tableView: UITableView! @IBOutlet weak var AllFolderView: AllFolderTableViewCell! @IBOutlet weak var fixedTableSheet: UIView! + @IBOutlet weak var searchForFilesView: SearchFilesView! private var viewModels: [File] = [] + private var searchedViewModel: [File] = [] + private var localFileManager: LocalFileManager? private var sortType: SortyFileType = .date @@ -31,6 +34,8 @@ final class DocumentsTableViewController: UIViewController, UITableViewDelegate, private var renameAlertController: UIAlertController? private var renameFileName: String? private var selectedFolder: AppConfigurator.Folder? + private var isSearching: Bool = false + @IBOutlet weak var allFolderView_height: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() @@ -51,7 +56,7 @@ final class DocumentsTableViewController: UIViewController, UITableViewDelegate, if let folder = selectedFolder { AllFolderView?.set(selectedFolder: folder, delegate: self) } - + searchForFilesView.delegate = self localFileManager = LocalFileManager() tabBarController?.delegate = UIApplication.shared.delegate as? UITabBarControllerDelegate @@ -90,6 +95,7 @@ final class DocumentsTableViewController: UIViewController, UITableViewDelegate, guard let directoryURL = localFileManager?.getFolderUrl(folder: folder), let viewModels = localFileManager?.filesForDirectory(directoryURL, sortType: sortType) else { return } self.viewModels = viewModels + self.searchedViewModel = viewModels AllFolderView?.set(selectedFolder: folder, delegate: self) tableView.reloadData() } @@ -104,7 +110,7 @@ final class DocumentsTableViewController: UIViewController, UITableViewDelegate, func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning Incomplete implementation, return the number of rows - return viewModels.count + return isSearching ? searchedViewModel.count :viewModels.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { @@ -112,7 +118,7 @@ final class DocumentsTableViewController: UIViewController, UITableViewDelegate, for: indexPath) as? DocumentsTableViewCell else { return UITableViewCell() } // Configure the cell... - let viewModel = viewModels[indexPath.row] + let viewModel = isSearching ? searchedViewModel[indexPath.row ] : viewModels[indexPath.row] cell.configure(with: viewModel, image: localFileManager?.getThumbnail(for: viewModel.fileURL)) return cell @@ -132,7 +138,7 @@ final class DocumentsTableViewController: UIViewController, UITableViewDelegate, } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - let viewModel = viewModels[indexPath.row] + let viewModel = isSearching ? searchedViewModel[indexPath.row] : viewModels[indexPath.row] let controller = DocumentPreviewViewController.buildViewController() controller.file = viewModel controller.hidesBottomBarWhenPushed = true @@ -217,7 +223,7 @@ final class DocumentsTableViewController: UIViewController, UITableViewDelegate, } private func renameFile(at indexPath: IndexPath) { - let viewModel = viewModels[indexPath.row] + let viewModel = isSearching ? searchedViewModel[indexPath.row] : viewModels[indexPath.row] renameAlertController = UIAlertController(title: "Rename document".localized, message: nil, preferredStyle: .alert) renameAlertController!.addTextField { [weak self] textField in @@ -251,7 +257,7 @@ final class DocumentsTableViewController: UIViewController, UITableViewDelegate, } private func deleteFile(at indexPath: IndexPath) { - let viewModel = viewModels[indexPath.row] + let viewModel = isSearching ? searchedViewModel[indexPath.row] : viewModels[indexPath.row] if UserDefaults.standard.askOnSwipeDelete { let alertController = UIAlertController(title: Bundle.appName, @@ -277,12 +283,18 @@ final class DocumentsTableViewController: UIViewController, UITableViewDelegate, do { try self.localFileManager?.filesManager.removeItem(at: fileURL) try self.localFileManager?.removeThumbnail(for: fileURL) - self.viewModels.remove(at: indexPath.row) + if isSearching { + self.searchedViewModel.remove(at: indexPath.row) + } else { + self.viewModels.remove(at: indexPath.row) + } self.tableView.deleteRows(at: [indexPath], with: .fade) } catch { return } } + + } /// Tells the delegate that the user picked a still image. @@ -340,8 +352,41 @@ extension DocumentsTableViewController: ImageScannerControllerDelegate { } extension DocumentsTableViewController: AllFolderTableViewCellDelegate { + func addFolderTapped() { + alert(confirm: "Add Folder", destructive: "Cancel", message: "Add Folder?"){ folderName in + let newFolder = AppConfigurator.Folder(name: folderName, savedName: folderName.replacingOccurrences(of: " ", with: "_"), isSelected: false) + var currentFolders = AppConfigurator().getFolders() + currentFolders.append(newFolder) + if let encoded = try? JSONEncoder().encode(currentFolders) { + UserDefaults.standard.set(encoded, forKey: "folders") + self.AllFolderView?.refresh() + self.dismiss(animated: true) + } + } + } + func cellTapped(folder: AppConfigurator.Folder) { selectedFolder = folder fetchViewModels() } } + +extension DocumentsTableViewController: SearchFilesViewDelegate { + func searchfor(text: String) { + if text.count == 0 { + isSearching = false + UIView.animate(withDuration: 0.5) { + self.allFolderView_height.constant = 240 + self.AllFolderView.isHidden = false + } + } else { + isSearching = true + UIView.animate(withDuration: 0.5) { + self.allFolderView_height.constant = 0 + self.AllFolderView.isHidden = true + } + self.searchedViewModel = self.viewModels.filter { $0.displayName.lowercased().contains(text.lowercased()) } + } + tableView.reloadData() + } +} diff --git a/MiniScanner/Supporting Files/.DS_Store b/MiniScanner/Supporting Files/.DS_Store index 280fde470002ef4f1c64823aae72cc256184d207..4305f7734bae3905870154284d7bffee466c2663 100644 GIT binary patch delta 24 fcmZp1XmQxUE6i?brlVkNX*yX~%zksQ@J1d0R2T-Q delta 16 XcmZp1XmQxUD?C|E%x!b9@J1d0FCYa( diff --git a/MiniScanner/Supporting Files/AppDelegate.swift b/MiniScanner/Supporting Files/AppDelegate.swift index b9fea47..c06e467 100644 --- a/MiniScanner/Supporting Files/AppDelegate.swift +++ b/MiniScanner/Supporting Files/AppDelegate.swift @@ -1,5 +1,6 @@ import UIKit import LanguageManager_iOS +import IQKeyboardManagerSwift @main class AppDelegate: UIResponder, UIApplicationDelegate { @@ -13,6 +14,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } else { AppConfigurator().setDefaults() } + IQKeyboardManager.shared.enable = true + IQKeyboardManager.shared.resignOnTouchOutside = true + IQKeyboardManager.shared.toolbarConfiguration.previousNextDisplayMode = .alwaysShow + IQKeyboardManager.shared.toolbarConfiguration.tintColor = .mainBlue + setAppLanguage() return true } diff --git a/MiniScanner/Supporting Files/Assets.xcassets/Folder.imageset/Contents.json b/MiniScanner/Supporting Files/Assets.xcassets/Folder.imageset/Contents.json new file mode 100644 index 0000000..db8d02f --- /dev/null +++ b/MiniScanner/Supporting Files/Assets.xcassets/Folder.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "folder_svgrepo.com.svg", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MiniScanner/Supporting Files/Assets.xcassets/Folder.imageset/folder_svgrepo.com.svg b/MiniScanner/Supporting Files/Assets.xcassets/Folder.imageset/folder_svgrepo.com.svg new file mode 100644 index 0000000..39291a2 --- /dev/null +++ b/MiniScanner/Supporting Files/Assets.xcassets/Folder.imageset/folder_svgrepo.com.svg @@ -0,0 +1,6 @@ +<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M25.5551 78.4055H89.1949C92.127 78.4055 94.5 76.0324 94.5 73.1004V20.25H20.25V73.1004C20.25 76.0324 22.623 78.4055 25.5551 78.4055Z" fill="#8B8B8B"/> +<path d="M18.8051 85.1555H82.4449C85.377 85.1555 87.75 82.7824 87.75 79.8504V27H13.5V79.8504C13.5 82.7824 15.873 85.1555 18.8051 85.1555Z" fill="#D2D2D2"/> +<path d="M101.25 54.3165V94.8165C101.25 98.5396 98.223 101.567 94.5 101.567H13.5C9.77695 101.567 6.75 98.5396 6.75 94.8165V40.479C6.75 36.756 9.77695 33.729 13.5 33.729H49.7918C52.3758 33.729 54.7277 35.195 55.8562 37.5153L60.7605 47.5665H94.5C98.223 47.5665 101.25 50.5935 101.25 54.3165Z" fill="#1F86FF"/> +<path d="M74.25 54.0001C74.25 51.8169 74.1023 49.6653 73.8176 47.5665H60.7605L55.8562 37.5153C54.7277 35.195 52.3652 33.729 49.7918 33.729H13.5C9.77695 33.729 6.75 36.756 6.75 40.479V94.8165C6.75 95.5231 6.85547 96.2087 7.06641 96.8521C13.1203 99.6681 19.8809 101.25 27 101.25C53.093 101.25 74.25 80.0931 74.25 54.0001Z" fill="#0075FF"/> +</svg> diff --git a/MiniScanner/Supporting Files/Assets.xcassets/Search.imageset/Contents.json b/MiniScanner/Supporting Files/Assets.xcassets/Search.imageset/Contents.json new file mode 100644 index 0000000..8fbac3d --- /dev/null +++ b/MiniScanner/Supporting Files/Assets.xcassets/Search.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "IconButton.svg", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MiniScanner/Supporting Files/Assets.xcassets/Search.imageset/IconButton.svg b/MiniScanner/Supporting Files/Assets.xcassets/Search.imageset/IconButton.svg new file mode 100644 index 0000000..258ff3b --- /dev/null +++ b/MiniScanner/Supporting Files/Assets.xcassets/Search.imageset/IconButton.svg @@ -0,0 +1,11 @@ +<svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="42" height="42" rx="10" fill="#888888"/> +<g clip-path="url(#clip0_144_1587)"> +<path d="M24.9536 24.2555L30.375 29.6606M27.25 18.7231C27.25 23.0378 23.7522 26.5356 19.4375 26.5356C15.1228 26.5356 11.625 23.0378 11.625 18.7231C11.625 14.4084 15.1228 10.9106 19.4375 10.9106C23.7522 10.9106 27.25 14.4084 27.25 18.7231Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> +</g> +<defs> +<clipPath id="clip0_144_1587"> +<rect width="25" height="25" fill="white" transform="matrix(-1 0 0 1 33.5 8.5)"/> +</clipPath> +</defs> +</svg> diff --git a/MiniScanner/Supporting Files/BMViewController.swift b/MiniScanner/Supporting Files/BMViewController.swift new file mode 100644 index 0000000..690ad6d --- /dev/null +++ b/MiniScanner/Supporting Files/BMViewController.swift @@ -0,0 +1,23 @@ +// +// BMViewController.swift +// MiniScanner +// +// Created by George Makhoul on 09/06/2024. +// Copyright © 2024 AppsNectar. All rights reserved. +// + +import Foundation +import UIKit + +class BMViewController: UIViewController { + + init() { + let nibName = String(describing: type(of: self)) + super.init(nibName: nibName, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} diff --git a/Podfile b/Podfile index 114e943..8803dd2 100644 --- a/Podfile +++ b/Podfile @@ -7,6 +7,8 @@ target 'MiniScanner' do # Pods for MiniScanner pod 'LanguageManager-iOS' + pod 'IQKeyboardManagerSwift' + post_install do |installer| installer.pods_project.targets.each do |target| diff --git a/Podfile.lock b/Podfile.lock index 913eedd..e3f77d7 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,16 +1,20 @@ PODS: + - IQKeyboardManagerSwift (7.0.3) - LanguageManager-iOS (1.2.7) DEPENDENCIES: + - IQKeyboardManagerSwift - LanguageManager-iOS SPEC REPOS: trunk: + - IQKeyboardManagerSwift - LanguageManager-iOS SPEC CHECKSUMS: + IQKeyboardManagerSwift: f9c5dc36cba16ddd2e51fa7d51c34a2e083029b5 LanguageManager-iOS: 6b2dbb3793445827114708f0759b76e96932d7c8 -PODFILE CHECKSUM: b552b1df80271db8c0ce748b0da6dd348ea0f82d +PODFILE CHECKSUM: 144b9dcd597bb6f7ec4e403aff5675d2db4f19f1 COCOAPODS: 1.14.3 diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQActiveConfiguration.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQActiveConfiguration.swift new file mode 100644 index 0000000..ef0b892 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQActiveConfiguration.swift @@ -0,0 +1,203 @@ +// +// IQActiveConfiguration.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +internal final class IQActiveConfiguration { + + private let keyboardListener: IQKeyboardListener = IQKeyboardListener() + private let textFieldViewListener: IQTextFieldViewListener = IQTextFieldViewListener() + + private var changeObservers: [AnyHashable: ConfigurationCompletion] = [:] + + @objc public enum Event: Int { + case hide + case show + case change + + var name: String { + switch self { + case .hide: + return "hide" + case .show: + return "show" + case .change: + return "change" + } + } + } + + private var lastEvent: Event = .hide + + var rootControllerConfiguration: IQRootControllerConfiguration? + + var isReady: Bool { + if textFieldViewInfo != nil, + let rootControllerConfiguration = rootControllerConfiguration { + return rootControllerConfiguration.isReady + } + return false + } + + init() { + addKeyboardListener() + addTextFieldViewListener() + } + + private func sendEvent() { + + if let textFieldViewInfo = textFieldViewInfo, + let rootControllerConfiguration = rootControllerConfiguration, + rootControllerConfiguration.isReady { + if keyboardInfo.keyboardShowing { + if lastEvent == .hide { + self.notify(event: .show, keyboardInfo: keyboardInfo, textFieldViewInfo: textFieldViewInfo) + } else { + self.notify(event: .change, keyboardInfo: keyboardInfo, textFieldViewInfo: textFieldViewInfo) + } + } else if lastEvent != .hide { + if rootControllerConfiguration.beginOrientation == rootControllerConfiguration.currentOrientation { + self.notify(event: .hide, keyboardInfo: keyboardInfo, textFieldViewInfo: textFieldViewInfo) + self.rootControllerConfiguration = nil + } else if rootControllerConfiguration.hasChanged { + animate(alongsideTransition: { + rootControllerConfiguration.restore() + }, completion: nil) + } + } + } + } + + private func updateRootController(info: IQTextFieldViewInfo?) { + + guard let info = info, + let controller: UIViewController = info.textFieldView.iq.parentContainerViewController() else { + if let rootControllerConfiguration = rootControllerConfiguration, + rootControllerConfiguration.hasChanged { + animate(alongsideTransition: { + rootControllerConfiguration.restore() + }, completion: nil) + } + rootControllerConfiguration = nil + return + } + + let newConfiguration = IQRootControllerConfiguration(rootController: controller) + + if newConfiguration.rootController.view.window != rootControllerConfiguration?.rootController.view.window || + newConfiguration.beginOrientation != rootControllerConfiguration?.beginOrientation { + + if rootControllerConfiguration?.rootController != newConfiguration.rootController { + + // If there was an old configuration but things are changed + if let rootControllerConfiguration = rootControllerConfiguration, + rootControllerConfiguration.hasChanged { + animate(alongsideTransition: { + rootControllerConfiguration.restore() + }, completion: nil) + } + } + + rootControllerConfiguration = newConfiguration + } + } +} + +@available(iOSApplicationExtension, unavailable) +extension IQActiveConfiguration { + + var keyboardInfo: IQKeyboardInfo { + return keyboardListener.keyboardInfo + } + + private func addKeyboardListener() { + keyboardListener.registerSizeChange(identifier: "IQActiveConfiguration", changeHandler: { [self] name, _ in + + if let info = textFieldViewInfo, keyboardInfo.keyboardShowing { + if let rootControllerConfiguration = rootControllerConfiguration { + let beginIsPortrait: Bool = rootControllerConfiguration.beginOrientation.isPortrait + let currentIsPortrait: Bool = rootControllerConfiguration.currentOrientation.isPortrait + if beginIsPortrait != currentIsPortrait { + updateRootController(info: info) + } + } else { + updateRootController(info: info) + } + } + + self.sendEvent() + + if name == .didHide { + updateRootController(info: nil) + } + }) + } + + public func animate(alongsideTransition transition: @escaping () -> Void, completion: (() -> Void)? = nil) { + keyboardListener.animate(alongsideTransition: transition, completion: completion) + } +} + +@available(iOSApplicationExtension, unavailable) +extension IQActiveConfiguration { + + var textFieldViewInfo: IQTextFieldViewInfo? { + return textFieldViewListener.textFieldViewInfo + } + + private func addTextFieldViewListener() { + textFieldViewListener.registerTextFieldViewChange(identifier: "IQActiveConfiguration", + changeHandler: { [self] info in + if info.name == .beginEditing { + updateRootController(info: info) + self.sendEvent() + } + }) + } +} + +@available(iOSApplicationExtension, unavailable) +extension IQActiveConfiguration { + + typealias ConfigurationCompletion = (_ event: Event, + _ keyboardInfo: IQKeyboardInfo, + _ textFieldInfo: IQTextFieldViewInfo) -> Void + + func registerChange(identifier: AnyHashable, changeHandler: @escaping ConfigurationCompletion) { + changeObservers[identifier] = changeHandler + } + + func unregisterChange(identifier: AnyHashable) { + changeObservers[identifier] = nil + } + + private func notify(event: Event, keyboardInfo: IQKeyboardInfo, textFieldViewInfo: IQTextFieldViewInfo) { + lastEvent = event + + for block in changeObservers.values { + block(event, keyboardInfo, textFieldViewInfo) + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQBarButtonItemConfiguration.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQBarButtonItemConfiguration.swift new file mode 100644 index 0000000..9377c01 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQBarButtonItemConfiguration.swift @@ -0,0 +1,96 @@ +// +// IQBarButtonItemConfiguration.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +/** + IQBarButtonItemConfiguration for creating toolbar with bar button items + */ +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc public final class IQBarButtonItemConfiguration: NSObject { + + @objc public init(systemItem: UIBarButtonItem.SystemItem, action: Selector? = nil) { + self.systemItem = systemItem + self.image = nil + self.title = nil + self.action = action + super.init() + } + + @objc public init(image: UIImage, action: Selector? = nil) { + self.systemItem = nil + self.image = image + self.title = nil + self.action = action + super.init() + } + + @objc public init(title: String, action: Selector? = nil) { + self.systemItem = nil + self.image = nil + self.title = title + self.action = action + super.init() + } + + public let systemItem: UIBarButtonItem.SystemItem? // System Item to be used to instantiate bar button. + + @objc public let image: UIImage? // Image to show on bar button item if it's not a system item. + + @objc public let title: String? // Title to show on bar button item if it's not a system item. + + @objc public var action: Selector? // action for bar button item. Usually 'doneAction:(IQBarButtonItem*)item'. + + public override var accessibilityLabel: String? { didSet { } } // Accessibility related labels + + func apply(on oldBarButtonItem: IQBarButtonItem, target: AnyObject?) -> IQBarButtonItem { + + var newBarButtonItem: IQBarButtonItem = oldBarButtonItem + + if systemItem == nil, !oldBarButtonItem.isSystemItem { + newBarButtonItem.title = title + newBarButtonItem.accessibilityLabel = accessibilityLabel + newBarButtonItem.accessibilityIdentifier = newBarButtonItem.accessibilityLabel + newBarButtonItem.image = image + newBarButtonItem.target = target + newBarButtonItem.action = action + } else { + if let systemItem: UIBarButtonItem.SystemItem = systemItem { + newBarButtonItem = IQBarButtonItem(barButtonSystemItem: systemItem, target: target, action: action) + newBarButtonItem.isSystemItem = true + } else if let image: UIImage = image { + newBarButtonItem = IQBarButtonItem(image: image, style: .plain, target: target, action: action) + } else { + newBarButtonItem = IQBarButtonItem(title: title, style: .plain, target: target, action: action) + } + + newBarButtonItem.invocation = oldBarButtonItem.invocation + newBarButtonItem.accessibilityLabel = accessibilityLabel + newBarButtonItem.accessibilityIdentifier = oldBarButtonItem.accessibilityLabel + newBarButtonItem.isEnabled = oldBarButtonItem.isEnabled + newBarButtonItem.tag = oldBarButtonItem.tag + } + return newBarButtonItem + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQKeyboardConfiguration.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQKeyboardConfiguration.swift new file mode 100644 index 0000000..653bc2c --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQKeyboardConfiguration.swift @@ -0,0 +1,39 @@ +// +// IQKeyboardConfiguration.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc public final class IQKeyboardConfiguration: NSObject { + + /** + Override the keyboardAppearance for all textField/textView. Default is NO. + */ + @objc public var overrideAppearance: Bool = false + + /** + If overrideKeyboardAppearance is YES, then all the textField keyboardAppearance is set using this property. + */ + @objc public var appearance: UIKeyboardAppearance = UIKeyboardAppearance.default +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQRootControllerConfiguration.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQRootControllerConfiguration.swift new file mode 100644 index 0000000..93aba8c --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQRootControllerConfiguration.swift @@ -0,0 +1,79 @@ +// +// IQRootControllerConfiguration.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +internal struct IQRootControllerConfiguration { + + let rootController: UIViewController + let beginOrigin: CGPoint + let beginSafeAreaInsets: UIEdgeInsets + let beginOrientation: UIInterfaceOrientation + + init(rootController: UIViewController) { + self.rootController = rootController + beginOrigin = rootController.view.frame.origin + beginSafeAreaInsets = rootController.view.safeAreaInsets + + let interfaceOrientation: UIInterfaceOrientation + if let scene = rootController.view.window?.windowScene { + interfaceOrientation = scene.interfaceOrientation + } else { + interfaceOrientation = .unknown + } + + beginOrientation = interfaceOrientation + } + + var currentOrientation: UIInterfaceOrientation { + let interfaceOrientation: UIInterfaceOrientation + if let scene = rootController.view.window?.windowScene { + interfaceOrientation = scene.interfaceOrientation + } else { + interfaceOrientation = .unknown + } + return interfaceOrientation + } + + var isReady: Bool { + return rootController.view.window != nil + } + + var hasChanged: Bool { + return !rootController.view.frame.origin.equalTo(beginOrigin) + } + + @discardableResult + func restore() -> Bool { + if !rootController.view.frame.origin.equalTo(beginOrigin) { + // Setting it's new frame + var rect: CGRect = rootController.view.frame + rect.origin = beginOrigin + rootController.view.frame = rect + return true + } + return false + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQScrollViewConfiguration.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQScrollViewConfiguration.swift new file mode 100644 index 0000000..49f6f16 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQScrollViewConfiguration.swift @@ -0,0 +1,94 @@ +// +// IQScrollViewConfiguration.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +internal struct IQScrollViewConfiguration { + let scrollView: UIScrollView + let startingContentOffset: CGPoint + let startingScrollIndicatorInsets: UIEdgeInsets + let startingContentInset: UIEdgeInsets + + private let canRestoreContentOffset: Bool + + init(scrollView: UIScrollView, canRestoreContentOffset: Bool) { + self.scrollView = scrollView + self.canRestoreContentOffset = canRestoreContentOffset + + startingContentOffset = scrollView.contentOffset + startingContentInset = scrollView.contentInset + startingScrollIndicatorInsets = scrollView.verticalScrollIndicatorInsets + } + + var hasChanged: Bool { + if scrollView.contentInset != self.startingContentInset { + return true + } + + if canRestoreContentOffset, + scrollView.iq.restoreContentOffset, + !scrollView.contentOffset.equalTo(startingContentOffset) { + return true + } + return false + } + + @discardableResult + func restore(for textFieldView: UIView?) -> Bool { + var success: Bool = false + + if scrollView.contentInset != self.startingContentInset { + scrollView.contentInset = self.startingContentInset + scrollView.layoutIfNeeded() // (Bug ID: #1996) + success = true + } + + if scrollView.verticalScrollIndicatorInsets != self.startingScrollIndicatorInsets { + scrollView.verticalScrollIndicatorInsets = self.startingScrollIndicatorInsets + } + + if canRestoreContentOffset, + scrollView.iq.restoreContentOffset, + !scrollView.contentOffset.equalTo(startingContentOffset) { + + // (Bug ID: #1365, #1508, #1541) + let stackView: UIStackView? = textFieldView?.iq.superviewOf(type: UIStackView.self, + belowView: scrollView) + // (Bug ID: #1901, #1996) + let animatedContentOffset: Bool = stackView != nil || + scrollView is UICollectionView || + scrollView is UITableView + + if animatedContentOffset { + scrollView.setContentOffset(startingContentOffset, animated: UIView.areAnimationsEnabled) + } else { + scrollView.contentOffset = startingContentOffset + } + success = true + } + + return success + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQToolbarConfiguration.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQToolbarConfiguration.swift new file mode 100644 index 0000000..3c6244b --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQToolbarConfiguration.swift @@ -0,0 +1,75 @@ +// +// IQToolbarConfiguration.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc public final class IQToolbarConfiguration: NSObject { + + /** + If YES, then uses textField's tintColor property for IQToolbar, otherwise tint color is default. Default is NO. + */ + @objc public var useTextFieldTintColor: Bool = false + + /** + This is used for toolbar.tintColor when textfield.keyboardAppearance is UIKeyboardAppearanceDefault. + If useTextFieldTintColor is YES then this property is ignored. Default is nil and uses black color. + */ + @objc public var tintColor: UIColor? + + /** + This is used for toolbar.barTintColor. Default is nil. + */ + @objc public var barTintColor: UIColor? + + /** + IQPreviousNextDisplayModeDefault: Show NextPrevious when there are more than 1 textField otherwise hide. + IQPreviousNextDisplayModeAlwaysHide: Do not show NextPrevious buttons in any case. + IQPreviousNextDisplayModeAlwaysShow: Always show nextPrevious buttons, + if there are more than 1 textField then both buttons will be visible but will be shown as disabled. + */ + @objc public var previousNextDisplayMode: IQPreviousNextDisplayMode = .default + + /** + /** + IQAutoToolbarBySubviews: Creates Toolbar according to subview's hierarchy of Textfield's in view. + IQAutoToolbarByTag: Creates Toolbar according to tag property of TextField's. + IQAutoToolbarByPosition: Creates Toolbar according to the y,x position + of textField in it's superview coordinate. + + Default is IQAutoToolbarBySubviews. + */ + AutoToolbar managing behavior. Default is IQAutoToolbarBySubviews. + */ + @objc public var manageBehavior: IQAutoToolbarManageBehavior = .bySubviews + + /** + Buttons configuration displayed on the toolbar, the selector parameter is ignored in below configuration + */ + @objc public var previousBarButtonConfiguration: IQBarButtonItemConfiguration? + @objc public var nextBarButtonConfiguration: IQBarButtonItemConfiguration? + @objc public var doneBarButtonConfiguration: IQBarButtonItemConfiguration? + + @objc public let placeholderConfiguration: IQToolbarPlaceholderConfiguration = .init() +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQToolbarPlaceholderConfiguration.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQToolbarPlaceholderConfiguration.swift new file mode 100644 index 0000000..5ee4387 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Configuration/IQToolbarPlaceholderConfiguration.swift @@ -0,0 +1,54 @@ +// +// IQToolbarPlaceholderConfiguration.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc public final class IQToolbarPlaceholderConfiguration: NSObject { + + /** + If YES, then it add the textField's placeholder text on IQToolbar. Default is YES. + */ + @objc public var showPlaceholder: Bool = true + + /** + Placeholder Font. Default is nil. + */ + @objc public var font: UIFont? + + /** + Placeholder Color. Default is nil. Which means lightGray + */ + @objc public var color: UIColor? + + /** + Placeholder Button Color when it's treated as button. Default is nil. + */ + @objc public var buttonColor: UIColor? + + /** + Placeholder accessibility Label + */ + public override var accessibilityLabel: String? { didSet { } } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift new file mode 100644 index 0000000..a3aac5c --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift @@ -0,0 +1,151 @@ +// +// IQKeyboardManagerConstants.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +// MARK: IQAutoToolbarManageBehavior + +/** +`IQAutoToolbarBySubviews` +Creates Toolbar according to subview's hierarchy of Textfield's in view. + +`IQAutoToolbarByTag` +Creates Toolbar according to tag property of TextField's. + +`IQAutoToolbarByPosition` +Creates Toolbar according to the y,x position of textField in it's superview coordinate. +*/ +@available(iOSApplicationExtension, unavailable) +@objc public enum IQAutoToolbarManageBehavior: Int { + case bySubviews + case byTag + case byPosition +} + +/** + `IQPreviousNextDisplayModeDefault` + Show NextPrevious when there are more than 1 textField otherwise hide. + + `IQPreviousNextDisplayModeAlwaysHide` + Do not show NextPrevious buttons in any case. + + `IQPreviousNextDisplayModeAlwaysShow` + Always show nextPrevious buttons, + if there are more than 1 textField then both buttons will be visible but will be shown as disabled. + */ +@available(iOSApplicationExtension, unavailable) +@objc public enum IQPreviousNextDisplayMode: Int { + case `default` + case alwaysHide + case alwaysShow +} + +/** + `IQEnableModeDefault` + Pick default settings. + + `IQEnableModeEnabled` + setting is enabled. + + `IQEnableModeDisabled` + setting is disabled. + */ +@available(iOSApplicationExtension, unavailable) +@objc public enum IQEnableMode: Int { + case `default` + case enabled + case disabled +} + +/* + /---------------------------------------------------------------------------------------------------\ + \---------------------------------------------------------------------------------------------------/ + | iOS Notification Mechanism | + /---------------------------------------------------------------------------------------------------\ + \---------------------------------------------------------------------------------------------------/ + + ------------------------------------------------------------ + When UITextField become first responder + ------------------------------------------------------------ + - UITextFieldTextDidBeginEditingNotification (UITextField) + - UIKeyboardWillShowNotification + - UIKeyboardDidShowNotification + + ------------------------------------------------------------ + When UITextView become first responder + ------------------------------------------------------------ + - UIKeyboardWillShowNotification + - UITextViewTextDidBeginEditingNotification (UITextView) + - UIKeyboardDidShowNotification + + ------------------------------------------------------------ + When switching focus from UITextField to another UITextField + ------------------------------------------------------------ + - UITextFieldTextDidEndEditingNotification (UITextField1) + - UITextFieldTextDidBeginEditingNotification (UITextField2) + - UIKeyboardWillShowNotification + - UIKeyboardDidShowNotification + + ------------------------------------------------------------ + When switching focus from UITextView to another UITextView + ------------------------------------------------------------ + - UITextViewTextDidEndEditingNotification: (UITextView1) + - UIKeyboardWillShowNotification + - UITextViewTextDidBeginEditingNotification: (UITextView2) + - UIKeyboardDidShowNotification + + ------------------------------------------------------------ + When switching focus from UITextField to UITextView + ------------------------------------------------------------ + - UITextFieldTextDidEndEditingNotification (UITextField) + - UIKeyboardWillShowNotification + - UITextViewTextDidBeginEditingNotification (UITextView) + - UIKeyboardDidShowNotification + + ------------------------------------------------------------ + When switching focus from UITextView to UITextField + ------------------------------------------------------------ + - UITextViewTextDidEndEditingNotification (UITextView) + - UITextFieldTextDidBeginEditingNotification (UITextField) + - UIKeyboardWillShowNotification + - UIKeyboardDidShowNotification + + ------------------------------------------------------------ + When opening/closing UIKeyboard Predictive bar + ------------------------------------------------------------ + - UIKeyboardWillShowNotification + - UIKeyboardDidShowNotification + + ------------------------------------------------------------ + On orientation change + ------------------------------------------------------------ + - UIApplicationWillChangeStatusBarOrientationNotification + - UIKeyboardWillHideNotification + - UIKeyboardDidHideNotification + - UIApplicationDidChangeStatusBarOrientationNotification + - UIKeyboardWillShowNotification + - UIKeyboardDidShowNotification + - UIKeyboardWillShowNotification + - UIKeyboardDidShowNotification + + */ diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Debug.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Debug.swift new file mode 100644 index 0000000..43df95f --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Debug.swift @@ -0,0 +1,71 @@ +// +// IQKeyboardManager+Debug.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +// MARK: Debugging & Developer options +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManager { + + @MainActor + private struct AssociatedKeys { + static var enableDebugging: Int = 0 + } + + @objc var enableDebugging: Bool { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.enableDebugging) as? Bool ?? false + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.enableDebugging, + newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + @MainActor + struct Static { + static var indentation = 0 + } + + internal func showLog(_ logString: String, indentation: Int = 0) { + + guard enableDebugging else { + return + } + + if indentation < 0 { + Static.indentation = max(0, Static.indentation + indentation) + } + + var preLog: String = "IQKeyboardManager" + for _ in 0 ... Static.indentation { + preLog += "|\t" + } + + print(preLog + logString) + + if indentation > 0 { + Static.indentation += indentation + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Deprecated.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Deprecated.swift new file mode 100644 index 0000000..c2cef98 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Deprecated.swift @@ -0,0 +1,220 @@ +// +// IQKeyboardManager.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +// swiftlint:disable unused_setter_value +// swiftlint:disable identifier_name +// swiftlint:disable line_length +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManager { + + @available(*, unavailable, renamed: "resignOnTouchOutside") + @objc var shouldResignOnTouchOutside: Bool { + get { false } + set { } + } + + @available(*, unavailable, renamed: "playInputClicks") + @objc var shouldPlayInputClicks: Bool { + get { false } + set { } + } + + @available(*, unavailable, message: "This feature has been removed due to few compatibility problems") + @objc func registerTextFieldViewClass(_ aClass: UIView.Type, + didBeginEditingNotificationName: String, + didEndEditingNotificationName: String) { + } + + @available(*, unavailable, message: "This feature has been removed due to few compatibility problems") + @objc func unregisterTextFieldViewClass(_ aClass: UIView.Type, + didBeginEditingNotificationName: String, + didEndEditingNotificationName: String) { + } +} + +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManager { + + @available(*, unavailable, renamed: "toolbarConfiguration.manageBehavior") + @objc var toolbarManageBehaviour: IQAutoToolbarManageBehavior { + get { .bySubviews } + set { } + } + + @available(*, unavailable, renamed: "toolbarConfiguration.useTextFieldTintColor") + @objc var shouldToolbarUsesTextFieldTintColor: Bool { + get { false } + set { } + } + + @available(*, unavailable, renamed: "toolbarConfiguration.tintColor") + @objc var toolbarTintColor: UIColor? { + get { nil } + set { } + } + + @available(*, unavailable, renamed: "toolbarConfiguration.barTintColor") + @objc var toolbarBarTintColor: UIColor? { + get { nil } + set { } + } + + @available(*, unavailable, renamed: "toolbarConfiguration.previousNextDisplayMode") + @objc var previousNextDisplayMode: IQPreviousNextDisplayMode { + get { .default } + set { } + } +} + +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManager { + @available(*, unavailable, renamed: "toolbarConfiguration.previousBarButtonConfiguration.image", + message: "To change, please assign a new toolbarConfiguration.previousBarButtonConfiguration") + @objc var toolbarPreviousBarButtonItemImage: UIImage? { + get { nil } + set { } + } + @available(*, unavailable, renamed: "toolbarConfiguration.previousBarButtonConfiguration.title", + message: "To change, please assign a new toolbarConfiguration.previousBarButtonConfiguration") + @objc var toolbarPreviousBarButtonItemText: String? { + get { nil } + set { } + } + @available(*, unavailable, renamed: "toolbarConfiguration.previousBarButtonConfiguration.accessibilityLabel", + message: "To change, please assign a new toolbarConfiguration.previousBarButtonConfiguration") + @objc var toolbarPreviousBarButtonItemAccessibilityLabel: String? { + get { nil } + set { } + } + + @available(*, unavailable, renamed: "toolbarConfiguration.nextBarButtonConfiguration.image", + message: "To change, please assign a new toolbarConfiguration.nextBarButtonConfiguration") + @objc var toolbarNextBarButtonItemImage: UIImage? { + get { nil } + set { } + } + @available(*, unavailable, renamed: "toolbarConfiguration.nextBarButtonConfiguration.title", + message: "To change, please assign a new toolbarConfiguration.nextBarButtonConfiguration") + @objc var toolbarNextBarButtonItemText: String? { + get { nil } + set { } + } + @available(*, unavailable, renamed: "toolbarConfiguration.nextBarButtonConfiguration.accessibilityLabel", + message: "To change, please assign a new toolbarConfiguration.nextBarButtonConfiguration") + @objc var toolbarNextBarButtonItemAccessibilityLabel: String? { + get { nil } + set { } + } + + @available(*, unavailable, renamed: "toolbarConfiguration.doneBarButtonConfiguration.image", + message: "To change, please assign a new toolbarConfiguration.doneBarButtonConfiguration") + @objc var toolbarDoneBarButtonItemImage: UIImage? { + get { nil } + set { } + } + @available(*, unavailable, renamed: "toolbarConfiguration.doneBarButtonConfiguration.title", + message: "To change, please assign a new toolbarConfiguration.doneBarButtonConfiguration") + @objc var toolbarDoneBarButtonItemText: String? { + get { nil } + set { } + } + @available(*, unavailable, renamed: "toolbarConfiguration.doneBarButtonConfiguration.accessibilityLabel", + message: "To change, please assign a new toolbarConfiguration.doneBarButtonConfiguration") + @objc var toolbarDoneBarButtonItemAccessibilityLabel: String? { + get { nil } + set { } + } +} + +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManager { + + @available(*, unavailable, renamed: "toolbarConfiguration.placeholderConfiguration.accessibilityLabel") + @objc var toolbarTitlBarButtonItemAccessibilityLabel: String? { + get { nil } + set { } + } + + @available(*, unavailable, renamed: "toolbarConfiguration.placeholderConfiguration.showPlaceholder") + @objc var shouldShowToolbarPlaceholder: Bool { + get { false } + set { } + } + + @available(*, unavailable, renamed: "toolbarConfiguration.placeholderConfiguration.font") + @objc var placeholderFont: UIFont? { + get { nil } + set { } + } + + @available(*, unavailable, renamed: "toolbarConfiguration.placeholderConfiguration.color") + @objc var placeholderColor: UIColor? { + get { nil } + set { } + } + + @available(*, unavailable, renamed: "toolbarConfiguration.placeholderConfiguration.buttonColor") + @objc var placeholderButtonColor: UIColor? { + get { nil } + set { } + } +} + +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManager { + + @available(*, unavailable, renamed: "keyboardConfiguration.overrideAppearance") + @objc var overrideKeyboardAppearance: Bool { + get { false } + set { } + } + + @available(*, unavailable, renamed: "keyboardConfiguration.appearance") + @objc var keyboardAppearance: UIKeyboardAppearance { + get { .default } + set { } + } +} + +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManager { + + typealias SizeBlock = (_ size: CGSize) -> Void + + @available(*, unavailable, message: "This feature has been moved to IQKeyboardListener, use it directly by creating new instance") + @objc func registerKeyboardSizeChange(identifier: AnyHashable, sizeHandler: @escaping SizeBlock) {} + + @available(*, unavailable, message: "This feature has been moved to IQKeyboardListener, use it directly by creating new instance") + @objc func unregisterKeyboardSizeChange(identifier: AnyHashable) {} + + @available(*, unavailable, message: "This feature has been moved to IQKeyboardListener, use it directly by creating new instance") + @objc var keyboardShowing: Bool { false } + + @available(*, unavailable, message: "This feature has been moved to IQKeyboardListener, use it directly by creating new instance") + @objc var keyboardFrame: CGRect { .zero } +} +// swiftlint:enable unused_setter_value +// swiftlint:enable identifier_name +// swiftlint:enable line_length diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Internal.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Internal.swift new file mode 100644 index 0000000..36a1874 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Internal.swift @@ -0,0 +1,239 @@ +// +// IQKeyboardManager+Internal.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +internal extension IQKeyboardManager { + + /** Get all UITextField/UITextView siblings of textFieldView. */ + func responderViews() -> [UIView]? { + + guard let textFieldView: UIView = activeConfiguration.textFieldViewInfo?.textFieldView else { + return nil + } + + var superConsideredView: UIView? + + // If find any consider responderView in it's upper hierarchy then will get deepResponderView. + for allowedClass in toolbarPreviousNextAllowedClasses { + superConsideredView = textFieldView.iq.superviewOf(type: allowedClass) + if superConsideredView != nil { + break + } + } + + var swiftUIHostingView: UIView? + let swiftUIHostingViewName: String = "UIHostingView<" + var superView: UIView? = textFieldView.superview + while let unwrappedSuperView: UIView = superView { + + let classNameString: String = { + var name: String = "\(type(of: unwrappedSuperView.self))" + if name.hasPrefix("_") { + name.removeFirst() + } + return name + }() + + if classNameString.hasPrefix(swiftUIHostingViewName) { + swiftUIHostingView = unwrappedSuperView + break + } + + superView = unwrappedSuperView.superview + } + + // (Enhancement ID: #22) + // If there is a superConsideredView in view's hierarchy, + // then fetching all it's subview that responds. + // No sorting for superConsideredView, it's by subView position. + if let view: UIView = swiftUIHostingView { + return view.iq.deepResponderViews() + } else if let view: UIView = superConsideredView { + return view.iq.deepResponderViews() + } else { // Otherwise fetching all the siblings + + let textFields: [UIView] = textFieldView.iq.responderSiblings() + + // Sorting textFields according to behavior + switch toolbarConfiguration.manageBehavior { + // If autoToolbar behavior is bySubviews, then returning it. + case .bySubviews: return textFields + + // If autoToolbar behavior is by tag, then sorting it according to tag property. + case .byTag: return textFields.sortedByTag() + + // If autoToolbar behavior is by tag, then sorting it according to tag property. + case .byPosition: return textFields.sortedByPosition() + } + } + } + + func privateIsEnabled() -> Bool { + + var isEnabled: Bool = enable + + guard let textFieldViewInfo: IQTextFieldViewInfo = activeConfiguration.textFieldViewInfo else { + return isEnabled + } + + let enableMode: IQEnableMode = textFieldViewInfo.textFieldView.iq.enableMode + + if enableMode == .enabled { + isEnabled = true + } else if enableMode == .disabled { + isEnabled = false + } else if var textFieldViewController = textFieldViewInfo.textFieldView.iq.viewContainingController() { + + // If it is searchBar textField embedded in Navigation Bar + if textFieldViewInfo.textFieldView.iq.textFieldSearchBar() != nil, + let navController: UINavigationController = textFieldViewController as? UINavigationController, + let topController: UIViewController = navController.topViewController { + textFieldViewController = topController + } + + // If viewController is kind of enable viewController class, then assuming it's enabled. + if !isEnabled, enabledDistanceHandlingClasses.contains(where: { textFieldViewController.isKind(of: $0) }) { + isEnabled = true + } + + if isEnabled { + + // If viewController is kind of disabled viewController class, then assuming it's disabled. + if disabledDistanceHandlingClasses.contains(where: { textFieldViewController.isKind(of: $0) }) { + isEnabled = false + } + + // Special Controllers + if isEnabled { + + let classNameString: String = "\(type(of: textFieldViewController.self))" + + // _UIAlertControllerTextFieldViewController + if classNameString.contains("UIAlertController"), + classNameString.hasSuffix("TextFieldViewController") { + isEnabled = false + } + } + } + } + + return isEnabled + } + + func privateIsEnableAutoToolbar() -> Bool { + + var isEnabled: Bool = enableAutoToolbar + + guard let textFieldViewInfo: IQTextFieldViewInfo = activeConfiguration.textFieldViewInfo, + var textFieldViewController = textFieldViewInfo.textFieldView.iq.viewContainingController() else { + return isEnabled + } + + // If it is searchBar textField embedded in Navigation Bar + if textFieldViewInfo.textFieldView.iq.textFieldSearchBar() != nil, + let navController: UINavigationController = textFieldViewController as? UINavigationController, + let topController: UIViewController = navController.topViewController { + textFieldViewController = topController + } + + if !isEnabled, enabledToolbarClasses.contains(where: { textFieldViewController.isKind(of: $0) }) { + isEnabled = true + } + + if isEnabled { + + // If found any toolbar disabled classes then return. + if disabledToolbarClasses.contains(where: { textFieldViewController.isKind(of: $0) }) { + isEnabled = false + } + + // Special Controllers + if isEnabled { + + let classNameString: String = "\(type(of: textFieldViewController.self))" + + // _UIAlertControllerTextFieldViewController + if classNameString.contains("UIAlertController"), classNameString.hasSuffix("TextFieldViewController") { + isEnabled = false + } + } + } + + return isEnabled + } + + func privateResignOnTouchOutside() -> Bool { + + var isEnabled: Bool = resignOnTouchOutside + + guard let textFieldViewInfo: IQTextFieldViewInfo = activeConfiguration.textFieldViewInfo else { + return isEnabled + } + + let enableMode: IQEnableMode = textFieldViewInfo.textFieldView.iq.resignOnTouchOutsideMode + + if enableMode == .enabled { + isEnabled = true + } else if enableMode == .disabled { + isEnabled = false + } else if var textFieldViewController = textFieldViewInfo.textFieldView.iq.viewContainingController() { + + // If it is searchBar textField embedded in Navigation Bar + if textFieldViewInfo.textFieldView.iq.textFieldSearchBar() != nil, + let navController: UINavigationController = textFieldViewController as? UINavigationController, + let topController: UIViewController = navController.topViewController { + textFieldViewController = topController + } + + // If viewController is kind of enable viewController class, then assuming resignOnTouchOutside is enabled. + if !isEnabled, + enabledTouchResignedClasses.contains(where: { textFieldViewController.isKind(of: $0) }) { + isEnabled = true + } + + if isEnabled { + + // If viewController is kind of disable viewController class, + // then assuming resignOnTouchOutside is disable. + if disabledTouchResignedClasses.contains(where: { textFieldViewController.isKind(of: $0) }) { + isEnabled = false + } + + // Special Controllers + if isEnabled { + + let classNameString: String = "\(type(of: textFieldViewController.self))" + + // _UIAlertControllerTextFieldViewController + if classNameString.contains("UIAlertController"), + classNameString.hasSuffix("TextFieldViewController") { + isEnabled = false + } + } + } + } + return isEnabled + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Position.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Position.swift new file mode 100644 index 0000000..d76cb9d --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Position.swift @@ -0,0 +1,718 @@ +// +// IQKeyboardManager+Position.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +// swiftlint:disable file_length +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManager { + + @MainActor + private struct AssociatedKeys { + static var movedDistance: Int = 0 + static var movedDistanceChanged: Int = 0 + static var lastScrollViewConfiguration: Int = 0 + static var startingTextViewConfiguration: Int = 0 + static var activeConfiguration: Int = 0 + } + + /** + moved distance to the top used to maintain distance between keyboard and textField. + Most of the time this will be a positive value. + */ + private(set) var movedDistance: CGFloat { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.movedDistance) as? CGFloat ?? 0.0 + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.movedDistance, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + movedDistanceChanged?(movedDistance) + } + } + + /** + Will be called then movedDistance will be changed + */ + @objc var movedDistanceChanged: ((CGFloat) -> Void)? { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.movedDistanceChanged) as? ((CGFloat) -> Void) + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.movedDistanceChanged, + newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + movedDistanceChanged?(movedDistance) + } + } + + /** Variable to save lastScrollView that was scrolled. */ + internal var lastScrollViewConfiguration: IQScrollViewConfiguration? { + get { + return objc_getAssociatedObject(self, + &AssociatedKeys.lastScrollViewConfiguration) as? IQScrollViewConfiguration + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.lastScrollViewConfiguration, + newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** used to adjust contentInset of UITextView. */ + internal var startingTextViewConfiguration: IQScrollViewConfiguration? { + get { + return objc_getAssociatedObject(self, + &AssociatedKeys.startingTextViewConfiguration) as? IQScrollViewConfiguration + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.startingTextViewConfiguration, + newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + internal func addActiveConfigurationObserver() { + activeConfiguration.registerChange(identifier: UUID().uuidString, changeHandler: { event, _, _ in + switch event { + case .show: + self.handleKeyboardTextFieldViewVisible() + case .change: + self.handleKeyboardTextFieldViewChanged() + case .hide: + self.handleKeyboardTextFieldViewHide() + } + }) + } + + @objc internal func applicationDidBecomeActive(_ notification: Notification) { + + guard privateIsEnabled(), + activeConfiguration.keyboardInfo.keyboardShowing, + activeConfiguration.isReady else { + return + } + adjustPosition() + } + + /* Adjusting RootViewController's frame according to interface orientation. */ + // swiftlint:disable cyclomatic_complexity + // swiftlint:disable function_body_length + internal func adjustPosition() { + + // We are unable to get textField object while keyboard showing on WKWebView's textField. (Bug ID: #11) + guard UIApplication.shared.applicationState == .active, + let textFieldView: UIView = activeConfiguration.textFieldViewInfo?.textFieldView, + let superview: UIView = textFieldView.superview, + let rootConfiguration = activeConfiguration.rootControllerConfiguration, + let window: UIWindow = rootConfiguration.rootController.view.window else { + return + } + + showLog(">>>>> \(#function) started >>>>>", indentation: 1) + let startTime: CFTimeInterval = CACurrentMediaTime() + + let rootController: UIViewController = rootConfiguration.rootController + let textFieldViewRectInWindow: CGRect = superview.convert(textFieldView.frame, to: window) + let textFieldViewRectInRootSuperview: CGRect = superview.convert(textFieldView.frame, + to: rootController.view.superview) + + // Getting RootViewOrigin. + var rootViewOrigin: CGPoint = rootController.view.frame.origin + + let keyboardDistance: CGFloat + + do { + // Maintain keyboardDistanceFromTextField + let specialKeyboardDistanceFromTextField: CGFloat + + if let searchBar: UIView = textFieldView.iq.textFieldSearchBar() { + specialKeyboardDistanceFromTextField = searchBar.iq.distanceFromKeyboard + } else { + specialKeyboardDistanceFromTextField = textFieldView.iq.distanceFromKeyboard + } + + if specialKeyboardDistanceFromTextField == UIView.defaultKeyboardDistance { + keyboardDistance = keyboardDistanceFromTextField + } else { + keyboardDistance = specialKeyboardDistanceFromTextField + } + } + + let kbSize: CGSize + let originalKbSize: CGSize = activeConfiguration.keyboardInfo.frame.size + + do { + var kbFrame: CGRect = activeConfiguration.keyboardInfo.frame + + kbFrame.origin.y -= keyboardDistance + kbFrame.size.height += keyboardDistance + + kbFrame.origin.y -= rootConfiguration.beginSafeAreaInsets.bottom + kbFrame.size.height += rootConfiguration.beginSafeAreaInsets.bottom + + // (Bug ID: #469) (Bug ID: #381) (Bug ID: #1506) + // Calculating actual keyboard covered size respect to window, + // keyboard frame may be different when hardware keyboard is attached + let intersectRect: CGRect = kbFrame.intersection(window.frame) + + if intersectRect.isNull { + kbSize = CGSize(width: kbFrame.size.width, height: 0) + } else { + kbSize = intersectRect.size + } + } + + let statusBarHeight: CGFloat + + let navigationBarAreaHeight: CGFloat + if let navigationController: UINavigationController = rootController.navigationController { + navigationBarAreaHeight = navigationController.navigationBar.frame.maxY + } else { + statusBarHeight = window.windowScene?.statusBarManager?.statusBarFrame.height ?? 0 + navigationBarAreaHeight = statusBarHeight + } + + let isScrollableTextView: Bool + + if let textView: UIScrollView = textFieldView as? UIScrollView, + textFieldView.responds(to: #selector(getter: UITextView.isEditable)) { + isScrollableTextView = textView.isScrollEnabled + } else { + isScrollableTextView = false + } + + let directionalLayoutMargin: NSDirectionalEdgeInsets = rootController.view.directionalLayoutMargins + let topLayoutGuide: CGFloat = CGFloat.maximum(navigationBarAreaHeight, directionalLayoutMargin.top) + + // Validation of textView for case where there is a tab bar + // at the bottom or running on iPhone X and textView is at the bottom. + let bottomLayoutGuide: CGFloat = isScrollableTextView ? 0 : directionalLayoutMargin.bottom + + // Move positive = textField is hidden. + // Move negative = textField is showing. + // Calculating move position. + var moveUp: CGFloat + + do { + let visibleHeight: CGFloat = window.frame.height-kbSize.height + + let topMovement: CGFloat = textFieldViewRectInRootSuperview.minY-topLayoutGuide + let bottomMovement: CGFloat = textFieldViewRectInWindow.maxY - visibleHeight + bottomLayoutGuide + moveUp = CGFloat.minimum(topMovement, bottomMovement) + moveUp = CGFloat(Int(moveUp)) + } + + showLog("Need to move: \(moveUp), will be moving \(moveUp < 0 ? "down" : "up")") + + var superScrollView: UIScrollView? + var superView: UIScrollView? = textFieldView.iq.superviewOf(type: UIScrollView.self) + + // Getting UIScrollView whose scrolling is enabled. // (Bug ID: #285) + while let view: UIScrollView = superView { + + if view.isScrollEnabled, !view.iq.ignoreScrollingAdjustment { + superScrollView = view + break + } else { + // Getting it's superScrollView. // (Enhancement ID: #21, #24) + superView = view.iq.superviewOf(type: UIScrollView.self) + } + } + + // If there was a lastScrollView. // (Bug ID: #34) + if let lastConfiguration: IQScrollViewConfiguration = lastScrollViewConfiguration { + // If we can't find current superScrollView, then setting lastScrollView to it's original form. + if superScrollView == nil { + + if lastConfiguration.hasChanged { + if lastConfiguration.scrollView.contentInset != lastConfiguration.startingContentInset { + showLog("Restoring contentInset to: \(lastConfiguration.startingContentInset)") + } + + if lastConfiguration.scrollView.iq.restoreContentOffset, + !lastConfiguration.scrollView.contentOffset.equalTo(lastConfiguration.startingContentOffset) { + showLog("Restoring contentOffset to: \(lastConfiguration.startingContentOffset)") + } + + activeConfiguration.animate(alongsideTransition: { + lastConfiguration.restore(for: textFieldView) + }) + } + + self.lastScrollViewConfiguration = nil + } else if superScrollView != lastConfiguration.scrollView { + // If both scrollView's are different, + // then reset lastScrollView to it's original frame and setting current scrollView as last scrollView. + if lastConfiguration.hasChanged { + if lastConfiguration.scrollView.contentInset != lastConfiguration.startingContentInset { + showLog("Restoring contentInset to: \(lastConfiguration.startingContentInset)") + } + + if lastConfiguration.scrollView.iq.restoreContentOffset, + !lastConfiguration.scrollView.contentOffset.equalTo(lastConfiguration.startingContentOffset) { + showLog("Restoring contentOffset to: \(lastConfiguration.startingContentOffset)") + } + + activeConfiguration.animate(alongsideTransition: { + lastConfiguration.restore(for: textFieldView) + }) + } + + if let superScrollView = superScrollView { + let configuration = IQScrollViewConfiguration(scrollView: superScrollView, + canRestoreContentOffset: true) + self.lastScrollViewConfiguration = configuration + showLog(""" + Saving ScrollView New contentInset: \(configuration.startingContentInset) + and contentOffset: \(configuration.startingContentOffset) + """) + } else { + self.lastScrollViewConfiguration = nil + } + } + // Else the case where superScrollView == lastScrollView means we are on same scrollView + // after switching to different textField. So doing nothing, going ahead + } else if let superScrollView: UIScrollView = superScrollView { + // If there was no lastScrollView and we found a current scrollView. then setting it as lastScrollView. + + let configuration = IQScrollViewConfiguration(scrollView: superScrollView, canRestoreContentOffset: true) + self.lastScrollViewConfiguration = configuration + showLog(""" + Saving ScrollView New contentInset: \(configuration.startingContentInset) + and contentOffset: \(configuration.startingContentOffset) + """) + } + + // Special case for ScrollView. + // If we found lastScrollView then setting it's contentOffset to show textField. + if let lastScrollViewConfiguration: IQScrollViewConfiguration = lastScrollViewConfiguration { + // Saving + var lastView: UIView = textFieldView + var superScrollView: UIScrollView? = lastScrollViewConfiguration.scrollView + + while let scrollView: UIScrollView = superScrollView { + + var isContinue: Bool = false + + if moveUp > 0 { + isContinue = moveUp > (-scrollView.contentOffset.y - scrollView.contentInset.top) + + } else if let tableView: UITableView = scrollView.iq.superviewOf(type: UITableView.self) { + // Special treatment for UITableView due to their cell reusing logic + + isContinue = scrollView.contentOffset.y > 0 + + if isContinue, + let tableCell: UITableViewCell = textFieldView.iq.superviewOf(type: UITableViewCell.self), + let indexPath: IndexPath = tableView.indexPath(for: tableCell), + let previousIndexPath: IndexPath = tableView.previousIndexPath(of: indexPath) { + + let previousCellRect: CGRect = tableView.rectForRow(at: previousIndexPath) + if !previousCellRect.isEmpty { + let superview: UIView? = rootController.view.superview + let previousCellRectInRootSuperview: CGRect = tableView.convert(previousCellRect, + to: superview) + + moveUp = CGFloat.minimum(0, previousCellRectInRootSuperview.maxY - topLayoutGuide) + } + } + } else if let collectionView = scrollView.iq.superviewOf(type: UICollectionView.self) { + // Special treatment for UICollectionView due to their cell reusing logic + + isContinue = scrollView.contentOffset.y > 0 + + if isContinue, + let collectionCell = textFieldView.iq.superviewOf(type: UICollectionViewCell.self), + let indexPath: IndexPath = collectionView.indexPath(for: collectionCell), + let previousIndexPath: IndexPath = collectionView.previousIndexPath(of: indexPath), + let attributes = collectionView.layoutAttributesForItem(at: previousIndexPath) { + + let previousCellRect: CGRect = attributes.frame + if !previousCellRect.isEmpty { + let superview: UIView? = rootController.view.superview + let previousCellRectInRootSuperview: CGRect = collectionView.convert(previousCellRect, + to: superview) + + moveUp = CGFloat.minimum(0, previousCellRectInRootSuperview.maxY - topLayoutGuide) + } + } + } else { + isContinue = textFieldViewRectInRootSuperview.minY < topLayoutGuide + + if isContinue { + moveUp = CGFloat.minimum(0, textFieldViewRectInRootSuperview.minY - topLayoutGuide) + } + } + + // Looping in upper hierarchy until we don't found any scrollView then + // in it's upper hierarchy till UIWindow object. + if isContinue { + + var tempScrollView: UIScrollView? = scrollView.iq.superviewOf(type: UIScrollView.self) + var nextScrollView: UIScrollView? + while let view: UIScrollView = tempScrollView { + + if view.isScrollEnabled, !view.iq.ignoreScrollingAdjustment { + nextScrollView = view + break + } else { + tempScrollView = view.iq.superviewOf(type: UIScrollView.self) + } + } + + // Getting lastViewRect. + if let lastViewRect: CGRect = lastView.superview?.convert(lastView.frame, to: scrollView) { + + // Calculating the expected Y offset from move and scrollView's contentOffset. + let minimumMovement: CGFloat = CGFloat.minimum(scrollView.contentOffset.y, -moveUp) + var suggestedOffsetY: CGFloat = scrollView.contentOffset.y - minimumMovement + + // Rearranging the expected Y offset according to the view. + suggestedOffsetY = CGFloat.minimum(suggestedOffsetY, lastViewRect.minY) + + // [_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type + // nextScrollView == nil If processing scrollView is last scrollView in + // upper hierarchy (there is no other scrollView upper hierarchy.) + // [_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type + // suggestedOffsetY >= 0 suggestedOffsetY must be greater than in + // order to keep distance from navigationBar (Bug ID: #92) + if isScrollableTextView, + nextScrollView == nil, + suggestedOffsetY >= 0 { + + // Converting Rectangle according to window bounds. + if let superview: UIView = textFieldView.superview { + + let currentTextFieldViewRect: CGRect = superview.convert(textFieldView.frame, + to: window) + + // Calculating expected fix distance which needs to be managed from navigation bar + let expectedFixDistance: CGFloat = currentTextFieldViewRect.minY - topLayoutGuide + + // Now if expectedOffsetY (scrollView.contentOffset.y + expectedFixDistance) + // is lower than current suggestedOffsetY, which means we're in a position where + // navigationBar up and hide, then reducing suggestedOffsetY with expectedOffsetY + // (scrollView.contentOffset.y + expectedFixDistance) + let expectedOffsetY: CGFloat = scrollView.contentOffset.y + expectedFixDistance + suggestedOffsetY = CGFloat.minimum(suggestedOffsetY, expectedOffsetY) + + // Setting move to 0 because now we don't want to move any view anymore + // (All will be managed by our contentInset logic. + moveUp = 0 + } else { + // Subtracting the Y offset from the move variable, + // because we are going to change scrollView's contentOffset.y to suggestedOffsetY. + moveUp -= (suggestedOffsetY-scrollView.contentOffset.y) + } + } else { + // Subtracting the Y offset from the move variable, + // because we are going to change scrollView's contentOffset.y to suggestedOffsetY. + moveUp -= (suggestedOffsetY-scrollView.contentOffset.y) + } + + let newContentOffset: CGPoint = CGPoint(x: scrollView.contentOffset.x, y: suggestedOffsetY) + + if !scrollView.contentOffset.equalTo(newContentOffset) { + + showLog(""" + old contentOffset: \(scrollView.contentOffset) + new contentOffset: \(newContentOffset) + """) + self.showLog("Remaining Move: \(moveUp)") + + // Getting problem while using `setContentOffset:animated:`, So I used animation API. + activeConfiguration.animate(alongsideTransition: { + + // (Bug ID: #1365, #1508, #1541) + let stackView: UIStackView? = textFieldView.iq.superviewOf(type: UIStackView.self, + belowView: scrollView) + // (Bug ID: #1901, #1996) + let animatedContentOffset: Bool = stackView != nil || + scrollView is UICollectionView || + scrollView is UITableView + + if animatedContentOffset { + scrollView.setContentOffset(newContentOffset, animated: UIView.areAnimationsEnabled) + } else { + scrollView.contentOffset = newContentOffset + } + }, completion: { + + if scrollView is UITableView || scrollView is UICollectionView { + // This will update the next/previous states + self.reloadInputViews() + } + }) + } + } + + // Getting next lastView & superScrollView. + lastView = scrollView + superScrollView = nextScrollView + } else { + moveUp = 0 + break + } + } + + // Updating contentInset + let lastScrollView = lastScrollViewConfiguration.scrollView + if let lastScrollViewRect: CGRect = lastScrollView.superview?.convert(lastScrollView.frame, to: window), + !lastScrollView.iq.ignoreContentInsetAdjustment { + + var bottomInset: CGFloat = (kbSize.height)-(window.frame.height-lastScrollViewRect.maxY) + let keyboardAndSafeArea: CGFloat = keyboardDistance + rootConfiguration.beginSafeAreaInsets.bottom + var bottomScrollIndicatorInset: CGFloat = bottomInset - keyboardAndSafeArea + + // Update the insets so that the scrollView doesn't shift incorrectly + // when the offset is near the bottom of the scroll view. + bottomInset = CGFloat.maximum(lastScrollViewConfiguration.startingContentInset.bottom, bottomInset) + let startingScrollInset: UIEdgeInsets = lastScrollViewConfiguration.startingScrollIndicatorInsets + bottomScrollIndicatorInset = CGFloat.maximum(startingScrollInset.bottom, + bottomScrollIndicatorInset) + + bottomInset -= lastScrollView.safeAreaInsets.bottom + bottomScrollIndicatorInset -= lastScrollView.safeAreaInsets.bottom + + var movedInsets: UIEdgeInsets = lastScrollView.contentInset + movedInsets.bottom = bottomInset + + if lastScrollView.contentInset != movedInsets { + showLog("old ContentInset: \(lastScrollView.contentInset) new ContentInset: \(movedInsets)") + + activeConfiguration.animate(alongsideTransition: { + lastScrollView.contentInset = movedInsets + lastScrollView.layoutIfNeeded() // (Bug ID: #1996) + + var newScrollIndicatorInset: UIEdgeInsets = lastScrollView.verticalScrollIndicatorInsets + + newScrollIndicatorInset.bottom = bottomScrollIndicatorInset + lastScrollView.scrollIndicatorInsets = newScrollIndicatorInset + }) + } + } + } + // Going ahead. No else if. + + // Special case for UITextView + // (Readjusting textView.contentInset when textView hight is too big to fit on screen) + // _lastScrollView If not having inside any scrollView, now contentInset manages the full screen textView. + // [_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type + if isScrollableTextView, let textView = textFieldView as? UIScrollView { + + let keyboardYPosition: CGFloat = window.frame.height - originalKbSize.height + var rootSuperViewFrameInWindow: CGRect = window.frame + if let rootSuperview: UIView = rootController.view.superview { + rootSuperViewFrameInWindow = rootSuperview.convert(rootSuperview.bounds, to: window) + } + + let keyboardOverlapping: CGFloat = rootSuperViewFrameInWindow.maxY - keyboardYPosition + + let availableHeight: CGFloat = rootSuperViewFrameInWindow.height-topLayoutGuide-keyboardOverlapping + let textViewHeight: CGFloat = CGFloat.minimum(textView.frame.height, availableHeight) + + if textView.frame.size.height-textView.contentInset.bottom>textViewHeight { + // If frame is not change by library in past, then saving user textView properties (Bug ID: #92) + if startingTextViewConfiguration == nil { + startingTextViewConfiguration = IQScrollViewConfiguration(scrollView: textView, + canRestoreContentOffset: false) + } + + var newContentInset: UIEdgeInsets = textView.contentInset + newContentInset.bottom = textView.frame.size.height-textViewHeight + newContentInset.bottom -= textView.safeAreaInsets.bottom + + if textView.contentInset != newContentInset { + self.showLog(""" + \(textFieldView) Old UITextView.contentInset: \(textView.contentInset) + New UITextView.contentInset: \(newContentInset) + """) + + activeConfiguration.animate(alongsideTransition: { + + textView.contentInset = newContentInset + textView.layoutIfNeeded() // (Bug ID: #1996) + textView.scrollIndicatorInsets = newContentInset + }) + } + } + } + + // +Positive or zero. + if moveUp >= 0 { + + rootViewOrigin.y = CGFloat.maximum(rootViewOrigin.y - moveUp, CGFloat.minimum(0, -originalKbSize.height)) + + if !rootController.view.frame.origin.equalTo(rootViewOrigin) { + showLog("Moving Upward") + + activeConfiguration.animate(alongsideTransition: { + + var rect: CGRect = rootController.view.frame + rect.origin = rootViewOrigin + rootController.view.frame = rect + + // Animating content if needed (Bug ID: #204) + if self.layoutIfNeededOnUpdate { + // Animating content (Bug ID: #160) + rootController.view.setNeedsLayout() + rootController.view.layoutIfNeeded() + } + + let classNameString: String = "\(type(of: rootController.self))" + self.showLog("Set \(classNameString) origin to: \(rootViewOrigin)") + }) + } + + movedDistance = (rootConfiguration.beginOrigin.y-rootViewOrigin.y) + } else { // -Negative + let disturbDistance: CGFloat = rootViewOrigin.y-rootConfiguration.beginOrigin.y + + // disturbDistance Negative = frame disturbed. + // disturbDistance positive = frame not disturbed. + if disturbDistance <= 0 { + + rootViewOrigin.y -= CGFloat.maximum(moveUp, disturbDistance) + + if !rootController.view.frame.origin.equalTo(rootViewOrigin) { + showLog("Moving Downward") + // Setting adjusted rootViewRect + // Setting adjusted rootViewRect + + activeConfiguration.animate(alongsideTransition: { + + var rect: CGRect = rootController.view.frame + rect.origin = rootViewOrigin + rootController.view.frame = rect + + // Animating content if needed (Bug ID: #204) + if self.layoutIfNeededOnUpdate { + // Animating content (Bug ID: #160) + rootController.view.setNeedsLayout() + rootController.view.layoutIfNeeded() + } + + let classNameString: String = "\(type(of: rootController.self))" + self.showLog("Set \(classNameString) origin to: \(rootViewOrigin)") + }) + } + + movedDistance = (rootConfiguration.beginOrigin.y-rootViewOrigin.y) + } + } + + let elapsedTime: CFTimeInterval = CACurrentMediaTime() - startTime + showLog("<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) + } + // swiftlint:enable cyclomatic_complexity + // swiftlint:enable function_body_length + + // swiftlint:disable cyclomatic_complexity + // swiftlint:disable function_body_length + internal func restorePosition() { + + // Setting rootViewController frame to it's original position. // (Bug ID: #18) + guard let configuration: IQRootControllerConfiguration = activeConfiguration.rootControllerConfiguration else { + return + } + let startTime: CFTimeInterval = CACurrentMediaTime() + showLog(">>>>> \(#function) started >>>>>", indentation: 1) + + activeConfiguration.animate(alongsideTransition: { + if configuration.hasChanged { + let classNameString: String = "\(type(of: configuration.rootController.self))" + self.showLog("Restoring \(classNameString) origin to: \(configuration.beginOrigin)") + } + configuration.restore() + + // Animating content if needed (Bug ID: #204) + if self.layoutIfNeededOnUpdate { + // Animating content (Bug ID: #160) + configuration.rootController.view.setNeedsLayout() + configuration.rootController.view.layoutIfNeeded() + } + }) + + // Restoring the contentOffset of the lastScrollView + if let textFieldView: UIView = activeConfiguration.textFieldViewInfo?.textFieldView, + let lastConfiguration: IQScrollViewConfiguration = lastScrollViewConfiguration { + + activeConfiguration.animate(alongsideTransition: { + + if lastConfiguration.hasChanged { + if lastConfiguration.scrollView.contentInset != lastConfiguration.startingContentInset { + self.showLog("Restoring contentInset to: \(lastConfiguration.startingContentInset)") + } + + if lastConfiguration.scrollView.iq.restoreContentOffset, + !lastConfiguration.scrollView.contentOffset.equalTo(lastConfiguration.startingContentOffset) { + self.showLog("Restoring contentOffset to: \(lastConfiguration.startingContentOffset)") + } + + lastConfiguration.restore(for: textFieldView) + } + + // This is temporary solution. Have to implement the save and restore scrollView state + var superScrollView: UIScrollView? = lastConfiguration.scrollView + + while let scrollView: UIScrollView = superScrollView { + + let width: CGFloat = CGFloat.maximum(scrollView.contentSize.width, scrollView.frame.width) + let height: CGFloat = CGFloat.maximum(scrollView.contentSize.height, scrollView.frame.height) + let contentSize: CGSize = CGSize(width: width, height: height) + + let minimumY: CGFloat = contentSize.height - scrollView.frame.height + + if minimumY < scrollView.contentOffset.y { + + let newContentOffset: CGPoint = CGPoint(x: scrollView.contentOffset.x, y: minimumY) + if !scrollView.contentOffset.equalTo(newContentOffset) { + + // (Bug ID: #1365, #1508, #1541) + let stackView: UIStackView? = textFieldView.iq.superviewOf(type: UIStackView.self, + belowView: scrollView) + + // (Bug ID: #1901, #1996) + let animatedContentOffset: Bool = stackView != nil || + scrollView is UICollectionView || + scrollView is UITableView + + if animatedContentOffset { + scrollView.setContentOffset(newContentOffset, animated: UIView.areAnimationsEnabled) + } else { + scrollView.contentOffset = newContentOffset + } + + self.showLog("Restoring contentOffset to: \(newContentOffset)") + } + } + + superScrollView = scrollView.iq.superviewOf(type: UIScrollView.self) + } + }) + } + + self.movedDistance = 0 + let elapsedTime: CFTimeInterval = CACurrentMediaTime() - startTime + showLog("<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) + } + // swiftlint:enable cyclomatic_complexity + // swiftlint:enable function_body_length +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Toolbar.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Toolbar.swift new file mode 100644 index 0000000..a7b1791 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Toolbar.swift @@ -0,0 +1,280 @@ +// +// IQKeyboardManager+Toolbar.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManager { + + /** + Default tag for toolbar with Done button -1002. + */ + private static let kIQDoneButtonToolbarTag = -1002 + + /** + Default tag for toolbar with Previous/Next buttons -1005. + */ + private static let kIQPreviousNextButtonToolbarTag = -1005 + + // swiftlint:disable function_body_length + // swiftlint:disable cyclomatic_complexity + /** + Add toolbar if it is required to add on textFields and it's siblings. + */ + internal func addToolbarIfRequired() { + + // Either there is no inputAccessoryView or + // if accessoryView is not appropriate for current situation + // (There is Previous/Next/Done toolbar) + guard let siblings: [UIView] = responderViews(), !siblings.isEmpty, + let textField: UIView = activeConfiguration.textFieldViewInfo?.textFieldView, + textField.responds(to: #selector(setter: UITextField.inputAccessoryView)) else { + return + } + + if let inputAccessoryView: UIView = textField.inputAccessoryView { + + if inputAccessoryView.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag || + inputAccessoryView.tag == IQKeyboardManager.kIQDoneButtonToolbarTag { + // continue + } else { + let swiftUIAccessoryName: String = "InputAccessoryHost<InputAccessoryBar>" + let classNameString: String = "\(type(of: inputAccessoryView.classForCoder))" + + // If it's SwiftUI accessory view but doesn't have a height (fake accessory view), then we should + // add our own accessoryView otherwise, keep the SwiftUI accessoryView since user has added it from code + guard classNameString.hasPrefix(swiftUIAccessoryName), inputAccessoryView.subviews.isEmpty else { + return + } + } + } + + showLog(">>>>> \(#function) started >>>>>", indentation: 1) + let startTime: CFTimeInterval = CACurrentMediaTime() + + showLog("Found \(siblings.count) responder sibling(s)") + + let rightConfiguration: IQBarButtonItemConfiguration + if let configuration: IQBarButtonItemConfiguration = toolbarConfiguration.doneBarButtonConfiguration { + rightConfiguration = configuration + rightConfiguration.action = #selector(self.doneAction(_:)) + } else { + rightConfiguration = IQBarButtonItemConfiguration(systemItem: .done, action: #selector(self.doneAction(_:))) + rightConfiguration.accessibilityLabel = "Done" + } + + let isTableCollectionView: Bool + if textField.iq.superviewOf(type: UITableView.self) != nil || + textField.iq.superviewOf(type: UICollectionView.self) != nil { + isTableCollectionView = true + } else { + isTableCollectionView = false + } + + let previousNextDisplayMode: IQPreviousNextDisplayMode = toolbarConfiguration.previousNextDisplayMode + + let havePreviousNext: Bool + switch previousNextDisplayMode { + case .default: + // If the textField is part of UITableView/UICollectionView then we should be exposing previous/next too + // Because at this time we don't know the previous or next cell if it contains another textField to move. + if isTableCollectionView { + havePreviousNext = true + } else if siblings.count <= 1 { + // If only one object is found, then adding only Done button. + havePreviousNext = false + } else { + havePreviousNext = true + } + case .alwaysShow: + havePreviousNext = true + case .alwaysHide: + havePreviousNext = false + } + + let placeholderConfig: IQToolbarPlaceholderConfiguration = toolbarConfiguration.placeholderConfiguration + if havePreviousNext { + let prevConfiguration: IQBarButtonItemConfiguration + if let configuration: IQBarButtonItemConfiguration = toolbarConfiguration.previousBarButtonConfiguration { + configuration.action = #selector(self.previousAction(_:)) + prevConfiguration = configuration + } else { + prevConfiguration = IQBarButtonItemConfiguration(image: (UIImage.keyboardPreviousImage), + action: #selector(self.previousAction(_:))) + prevConfiguration.accessibilityLabel = "Previous" + } + + let nextConfiguration: IQBarButtonItemConfiguration + if let configuration: IQBarButtonItemConfiguration = toolbarConfiguration.nextBarButtonConfiguration { + configuration.action = #selector(self.nextAction(_:)) + nextConfiguration = configuration + } else { + nextConfiguration = IQBarButtonItemConfiguration(image: (UIImage.keyboardNextImage), + action: #selector(self.nextAction(_:))) + nextConfiguration.accessibilityLabel = "Next" + } + + let titleText: String? = placeholderConfig.showPlaceholder ? textField.iq.drawingPlaceholder : nil + textField.iq.addToolbar(target: self, + previousConfiguration: prevConfiguration, + nextConfiguration: nextConfiguration, + rightConfiguration: rightConfiguration, title: titleText, + titleAccessibilityLabel: placeholderConfig.accessibilityLabel) + + // (Bug ID: #78) + textField.inputAccessoryView?.tag = IQKeyboardManager.kIQPreviousNextButtonToolbarTag + + if isTableCollectionView { + // (Bug ID: #56) + // In case of UITableView, the next/previous buttons should always be enabled. + textField.iq.toolbar.previousBarButton.isEnabled = true + textField.iq.toolbar.nextBarButton.isEnabled = true + } else { + // If firstTextField, then previous should not be enabled. + textField.iq.toolbar.previousBarButton.isEnabled = (siblings.first != textField) + // If lastTextField then next should not be enabled. + textField.iq.toolbar.nextBarButton.isEnabled = (siblings.last != textField) + } + + } else { + + let titleText: String? = placeholderConfig.showPlaceholder ? textField.iq.drawingPlaceholder : nil + textField.iq.addToolbar(target: self, rightConfiguration: rightConfiguration, + title: titleText, + titleAccessibilityLabel: placeholderConfig.accessibilityLabel) + + textField.inputAccessoryView?.tag = IQKeyboardManager.kIQDoneButtonToolbarTag // (Bug ID: #78) + } + + let toolbar: IQToolbar = textField.iq.toolbar + + // Setting toolbar tintColor // (Enhancement ID: #30) + if toolbarConfiguration.useTextFieldTintColor { + toolbar.tintColor = textField.tintColor + } else { + toolbar.tintColor = toolbarConfiguration.tintColor + } + + // Setting toolbar to keyboard. + if let textFieldView: UITextInput = textField as? UITextInput { + + // Bar style according to keyboard appearance + switch textFieldView.keyboardAppearance { + + case .dark?: + toolbar.barStyle = .black + toolbar.barTintColor = nil + default: + toolbar.barStyle = .default + toolbar.barTintColor = toolbarConfiguration.barTintColor + } + } + + // Setting toolbar title font. // (Enhancement ID: #30) + if toolbarConfiguration.placeholderConfiguration.showPlaceholder, + !textField.iq.hidePlaceholder { + + // Updating placeholder font to toolbar. //(Bug ID: #148, #272) + if toolbar.titleBarButton.title == nil || + toolbar.titleBarButton.title != textField.iq.drawingPlaceholder { + toolbar.titleBarButton.title = textField.iq.drawingPlaceholder + } + + // Setting toolbar title font. // (Enhancement ID: #30) + toolbar.titleBarButton.titleFont = toolbarConfiguration.placeholderConfiguration.font + + // Setting toolbar title color. // (Enhancement ID: #880) + toolbar.titleBarButton.titleColor = toolbarConfiguration.placeholderConfiguration.color + + // Setting toolbar button title color. // (Enhancement ID: #880) + toolbar.titleBarButton.selectableTitleColor = toolbarConfiguration.placeholderConfiguration.buttonColor + + } else { + toolbar.titleBarButton.title = nil + } + + // In case of UITableView (Special), the next/previous buttons has to be refreshed every-time. (Bug ID: #56) + + // If firstTextField, then previous should not be enabled. + textField.iq.toolbar.previousBarButton.isEnabled = (siblings.first != textField) + + // If lastTextField then next should not be enabled. + textField.iq.toolbar.nextBarButton.isEnabled = (siblings.last != textField) + + let elapsedTime: CFTimeInterval = CACurrentMediaTime() - startTime + showLog("<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) + } + // swiftlint:enable function_body_length + // swiftlint:enable cyclomatic_complexity + + /** Remove any toolbar if it is IQToolbar. */ + internal func removeToolbarIfRequired() { // (Bug ID: #18) + + guard let siblings: [UIView] = responderViews(), !siblings.isEmpty, + let textField: UIView = activeConfiguration.textFieldViewInfo?.textFieldView, + textField.responds(to: #selector(setter: UITextField.inputAccessoryView)), + textField.inputAccessoryView == nil || + textField.inputAccessoryView?.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag || + textField.inputAccessoryView?.tag == IQKeyboardManager.kIQDoneButtonToolbarTag else { + return + } + + showLog(">>>>> \(#function) started >>>>>", indentation: 1) + let startTime: CFTimeInterval = CACurrentMediaTime() + + showLog("Found \(siblings.count) responder sibling(s)") + + for view in siblings { + if let toolbar: IQToolbar = view.inputAccessoryView as? IQToolbar { + + // setInputAccessoryView: check (Bug ID: #307) + if view.responds(to: #selector(setter: UITextField.inputAccessoryView)), + toolbar.tag == IQKeyboardManager.kIQDoneButtonToolbarTag || + toolbar.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag { + + if let textField: UITextField = view as? UITextField { + textField.inputAccessoryView = nil + } else if let textView: UITextView = view as? UITextView { + textView.inputAccessoryView = nil + } + + view.reloadInputViews() + } + } + } + + let elapsedTime: CFTimeInterval = CACurrentMediaTime() - startTime + showLog("<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) + } + + /** reloadInputViews to reload toolbar buttons enable/disable state on the fly Enhancement ID #434. */ + @objc func reloadInputViews() { + + // If enabled then adding toolbar. + if privateIsEnableAutoToolbar() { + self.addToolbarIfRequired() + } else { + self.removeToolbarIfRequired() + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+ToolbarActions.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+ToolbarActions.swift new file mode 100644 index 0000000..5b01190 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+ToolbarActions.swift @@ -0,0 +1,205 @@ +// +// IQKeyboardManager+ToolbarActions.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +// MARK: Previous next button actions +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManager { + + /** + Returns YES if can navigate to previous responder textField/textView, otherwise NO. + */ + @objc var canGoPrevious: Bool { + // If it is not first textField. then it's previous object canBecomeFirstResponder. + guard let textFields: [UIView] = responderViews(), + let textFieldRetain: UIView = activeConfiguration.textFieldViewInfo?.textFieldView, + let index: Int = textFields.firstIndex(of: textFieldRetain), + index > 0 else { + return false + } + return true + } + + /** + Returns YES if can navigate to next responder textField/textView, otherwise NO. + */ + @objc var canGoNext: Bool { + // If it is not first textField. then it's previous object canBecomeFirstResponder. + guard let textFields: [UIView] = responderViews(), + let textFieldRetain: UIView = activeConfiguration.textFieldViewInfo?.textFieldView, + let index: Int = textFields.firstIndex(of: textFieldRetain), + index < textFields.count-1 else { + return false + } + return true + } + + /** + Navigate to previous responder textField/textView. + */ + @discardableResult + @objc func goPrevious() -> Bool { + + // If it is not first textField. then it's previous object becomeFirstResponder. + guard let textFields: [UIView] = responderViews(), + let textFieldRetain: UIView = activeConfiguration.textFieldViewInfo?.textFieldView, + let index: Int = textFields.firstIndex(of: textFieldRetain), + index > 0 else { + return false + } + + let nextTextField: UIView = textFields[index-1] + + let isAcceptAsFirstResponder: Bool = nextTextField.becomeFirstResponder() + + // If it refuses then becoming previous textFieldView as first responder again. (Bug ID: #96) + if !isAcceptAsFirstResponder { + showLog("Refuses to become first responder: \(nextTextField)") + } + + return isAcceptAsFirstResponder + } + + /** + Navigate to next responder textField/textView. + */ + @discardableResult + @objc func goNext() -> Bool { + + // If it is not first textField. then it's previous object becomeFirstResponder. + guard let textFields: [UIView] = responderViews(), + let textFieldRetain: UIView = activeConfiguration.textFieldViewInfo?.textFieldView, + let index: Int = textFields.firstIndex(of: textFieldRetain), + index < textFields.count-1 else { + return false + } + + let nextTextField: UIView = textFields[index+1] + + let isAcceptAsFirstResponder: Bool = nextTextField.becomeFirstResponder() + + // If it refuses then becoming previous textFieldView as first responder again. (Bug ID: #96) + if !isAcceptAsFirstResponder { + showLog("Refuses to become first responder: \(nextTextField)") + } + + return isAcceptAsFirstResponder + } + + /** previousAction. */ + @objc internal func previousAction (_ barButton: IQBarButtonItem) { + + // If user wants to play input Click sound. + if playInputClicks { + // Play Input Click Sound. + UIDevice.current.playInputClick() + } + + guard canGoPrevious, + let textFieldRetain: UIView = activeConfiguration.textFieldViewInfo?.textFieldView else { + return + } + + let isAcceptAsFirstResponder: Bool = goPrevious() + + var invocation: IQInvocation? = barButton.invocation + var sender: UIView = textFieldRetain + + // Handling search bar special case + do { + if let searchBar: UIView = textFieldRetain.iq.textFieldSearchBar() { + invocation = searchBar.iq.toolbar.previousBarButton.invocation + sender = searchBar + } + } + + if isAcceptAsFirstResponder { + invocation?.invoke(from: sender) + } + } + + /** nextAction. */ + @objc internal func nextAction (_ barButton: IQBarButtonItem) { + + // If user wants to play input Click sound. + if playInputClicks { + // Play Input Click Sound. + UIDevice.current.playInputClick() + } + + guard canGoNext, + let textFieldRetain: UIView = activeConfiguration.textFieldViewInfo?.textFieldView else { + return + } + + let isAcceptAsFirstResponder: Bool = goNext() + + var invocation: IQInvocation? = barButton.invocation + var sender: UIView = textFieldRetain + + // Handling search bar special case + do { + if let searchBar: UIView = textFieldRetain.iq.textFieldSearchBar() { + invocation = searchBar.iq.toolbar.nextBarButton.invocation + sender = searchBar + } + } + + if isAcceptAsFirstResponder { + invocation?.invoke(from: sender) + } + } + + /** doneAction. Resigning current textField. */ + @objc internal func doneAction (_ barButton: IQBarButtonItem) { + + // If user wants to play input Click sound. + if playInputClicks { + // Play Input Click Sound. + UIDevice.current.playInputClick() + } + + guard let textFieldRetain: UIView = activeConfiguration.textFieldViewInfo?.textFieldView else { + return + } + + // Resign textFieldView. + let isResignedFirstResponder: Bool = resignFirstResponder() + + var invocation: IQInvocation? = barButton.invocation + var sender: UIView = textFieldRetain + + // Handling search bar special case + do { + if let searchBar: UIView = textFieldRetain.iq.textFieldSearchBar() { + invocation = searchBar.iq.toolbar.doneBarButton.invocation + sender = searchBar + } + } + + if isResignedFirstResponder { + invocation?.invoke(from: sender) + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+UIKeyboardNotification.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+UIKeyboardNotification.swift new file mode 100644 index 0000000..3850630 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+UIKeyboardNotification.swift @@ -0,0 +1,148 @@ +// +// IQKeyboardManager+UIKeyboardNotification.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +// MARK: UIKeyboard Notifications +@available(iOSApplicationExtension, unavailable) +internal extension IQKeyboardManager { + + func handleKeyboardTextFieldViewVisible() { + if self.activeConfiguration.rootControllerConfiguration == nil { // (Bug ID: #5) + + let rootConfiguration: IQRootControllerConfiguration? = self.activeConfiguration.rootControllerConfiguration + if let gestureConfiguration = self.rootConfigurationWhilePopGestureActive, + gestureConfiguration.rootController == rootConfiguration?.rootController { + self.activeConfiguration.rootControllerConfiguration = gestureConfiguration + } + + self.rootConfigurationWhilePopGestureActive = nil + + if let configuration = self.activeConfiguration.rootControllerConfiguration { + let classNameString: String = "\(type(of: configuration.rootController.self))" + self.showLog("Saving \(classNameString) beginning origin: \(configuration.beginOrigin)") + } + } + + setupTextFieldView() + + if !privateIsEnabled() { + restorePosition() + } else { + adjustPosition() + } + } + + func handleKeyboardTextFieldViewChanged() { + + setupTextFieldView() + + if !privateIsEnabled() { + restorePosition() + } else { + adjustPosition() + } + } + + func handleKeyboardTextFieldViewHide() { + + self.restorePosition() + self.banishTextFieldViewSetup() + + if let configuration = self.activeConfiguration.rootControllerConfiguration, + configuration.rootController.navigationController?.interactivePopGestureRecognizer?.state == .began { + self.rootConfigurationWhilePopGestureActive = configuration + } + + self.lastScrollViewConfiguration = nil + } +} + +@available(iOSApplicationExtension, unavailable) +internal extension IQKeyboardManager { + + func setupTextFieldView() { + + guard let textFieldView = activeConfiguration.textFieldViewInfo?.textFieldView else { + return + } + + do { + if let startingConfiguration = startingTextViewConfiguration, + startingConfiguration.hasChanged { + + if startingConfiguration.scrollView.contentInset != startingConfiguration.startingContentInset { + showLog("Restoring textView.contentInset to: \(startingConfiguration.startingContentInset)") + } + + activeConfiguration.animate(alongsideTransition: { + startingConfiguration.restore(for: textFieldView) + }) + } + startingTextViewConfiguration = nil + } + + if keyboardConfiguration.overrideAppearance, + let textInput: UITextInput = textFieldView as? UITextInput, + textInput.keyboardAppearance != keyboardConfiguration.appearance { + // Setting textField keyboard appearance and reloading inputViews. + if let textFieldView: UITextField = textFieldView as? UITextField { + textFieldView.keyboardAppearance = keyboardConfiguration.appearance + } else if let textFieldView: UITextView = textFieldView as? UITextView { + textFieldView.keyboardAppearance = keyboardConfiguration.appearance + } + textFieldView.reloadInputViews() + } + + // If autoToolbar enable, then add toolbar on all the UITextField/UITextView's if required. + reloadInputViews() + + resignFirstResponderGesture.isEnabled = privateResignOnTouchOutside() + textFieldView.window?.addGestureRecognizer(resignFirstResponderGesture) // (Enhancement ID: #14) + } + + func banishTextFieldViewSetup() { + + guard let textFieldView = activeConfiguration.textFieldViewInfo?.textFieldView else { + return + } + + // Removing gesture recognizer (Enhancement ID: #14) + textFieldView.window?.removeGestureRecognizer(resignFirstResponderGesture) + + do { + if let startingConfiguration = startingTextViewConfiguration, + startingConfiguration.hasChanged { + + if startingConfiguration.scrollView.contentInset != startingConfiguration.startingContentInset { + showLog("Restoring textView.contentInset to: \(startingConfiguration.startingContentInset)") + } + + activeConfiguration.animate(alongsideTransition: { + startingConfiguration.restore(for: textFieldView) + }) + } + startingTextViewConfiguration = nil + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+UITextFieldViewNotification.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+UITextFieldViewNotification.swift new file mode 100644 index 0000000..676a8bc --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+UITextFieldViewNotification.swift @@ -0,0 +1,46 @@ +// +// IQKeyboardManager+UITextFieldViewNotification.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +// MARK: UITextField/UITextView Notifications +@available(iOSApplicationExtension, unavailable) +@MainActor +internal extension IQKeyboardManager { + + @MainActor + private struct AssociatedKeys { + static var rootConfigWhilePopActive: Int = 0 + } + + var rootConfigurationWhilePopGestureActive: IQRootControllerConfiguration? { + get { + return objc_getAssociatedObject(self, + &AssociatedKeys.rootConfigWhilePopActive) as? IQRootControllerConfiguration + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.rootConfigWhilePopActive, + newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager.swift new file mode 100644 index 0000000..eeaca4b --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager.swift @@ -0,0 +1,331 @@ +// +// IQKeyboardManager.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit +import CoreGraphics +import QuartzCore + +// MARK: IQToolbar tags + +// swiftlint:disable line_length +// A generic version of KeyboardManagement. (OLD DOCUMENTATION) LINK +// https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html +// https://developer.apple.com/documentation/uikit/keyboards_and_input/adjusting_your_layout_with_keyboard_layout_guide +// swiftlint:enable line_length + +/** +Code-less drop-in universal library allows to prevent issues of keyboard sliding up and cover UITextField/UITextView. + Neither need to write any code nor any setup required and much more. +*/ +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc public final class IQKeyboardManager: NSObject { + + /** + Returns the default singleton instance. + */ + @objc public static let shared: IQKeyboardManager = .init() + + // MARK: UIKeyboard handling + + /** + Enable/disable managing distance between keyboard and textField. + Default is YES(Enabled when class loads in `+(void)load` method). + */ + @objc public var enable: Bool = false { + + didSet { + // If not enable, enable it. + if enable, !oldValue { + // If keyboard is currently showing. + if activeConfiguration.keyboardInfo.keyboardShowing { + adjustPosition() + } else { + restorePosition() + } + showLog("Enabled") + } else if !enable, oldValue { // If not disable, disable it. + restorePosition() + showLog("Disabled") + } + } + } + + /** + To set keyboard distance from textField. can't be less than zero. Default is 10.0. + */ + @objc public var keyboardDistanceFromTextField: CGFloat = 10.0 + + // MARK: IQToolbar handling + + /** + Automatic add the IQToolbar functionality. Default is YES. + */ + @objc public var enableAutoToolbar: Bool = true { + didSet { + reloadInputViews() + showLog("enableAutoToolbar: \(enableAutoToolbar ? "Yes" : "NO")") + } + } + + internal var activeConfiguration: IQActiveConfiguration = .init() + + /** + Configurations related to the toolbar display over the keyboard. + */ + @objc public let toolbarConfiguration: IQToolbarConfiguration = .init() + + /** + Configuration related to keyboard appearance + */ + @objc public let keyboardConfiguration: IQKeyboardConfiguration = .init() + + // MARK: UITextField/UITextView Next/Previous/Resign handling + + /** + Resigns Keyboard on touching outside of UITextField/View. Default is NO. + */ + @objc public var resignOnTouchOutside: Bool = false { + + didSet { + resignFirstResponderGesture.isEnabled = privateResignOnTouchOutside() + + showLog("resignOnTouchOutside: \(resignOnTouchOutside ? "Yes" : "NO")") + } + } + + /** TapGesture to resign keyboard on view's touch. + It's a readonly property and exposed only for adding/removing dependencies + if your added gesture does have collision with this one + */ + @objc public lazy var resignFirstResponderGesture: UITapGestureRecognizer = { + + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.tapRecognized(_:))) + tapGesture.cancelsTouchesInView = false + tapGesture.delegate = self + + return tapGesture + }() + + /*******************************************/ + + /** + Resigns currently first responder field. + */ + @discardableResult + @objc public func resignFirstResponder() -> Bool { + + guard let textFieldRetain: UIView = activeConfiguration.textFieldViewInfo?.textFieldView else { + return false + } + + // Resigning first responder + guard textFieldRetain.resignFirstResponder() else { + showLog("Refuses to resign first responder: \(textFieldRetain)") + // If it refuses then becoming it as first responder again. (Bug ID: #96) + // If it refuses to resign then becoming it first responder again for getting notifications callback. + textFieldRetain.becomeFirstResponder() + return false + } + return true + } + + // MARK: UISound handling + + /** + If YES, then it plays inputClick sound on next/previous/done click. + */ + @objc public var playInputClicks: Bool = true + + // MARK: UIAnimation handling + + /** + If YES, then calls 'setNeedsLayout' and 'layoutIfNeeded' on any frame update of to viewController's view. + */ + @objc public var layoutIfNeededOnUpdate: Bool = false + + // MARK: Class Level disabling methods + + /** + Disable distance handling within the scope of disabled distance handling viewControllers classes. + Within this scope, 'enabled' property is ignored. Class should be kind of UIViewController. + */ + @objc public var disabledDistanceHandlingClasses: [UIViewController.Type] = [] + + /** + Enable distance handling within the scope of enabled distance handling viewControllers classes. + Within this scope, 'enabled' property is ignored. Class should be kind of UIViewController. + If same Class is added in disabledDistanceHandlingClasses list, + then enabledDistanceHandlingClasses will be ignored. + */ + @objc public var enabledDistanceHandlingClasses: [UIViewController.Type] = [] + + /** + Disable automatic toolbar creation within the scope of disabled toolbar viewControllers classes. + Within this scope, 'enableAutoToolbar' property is ignored. Class should be kind of UIViewController. + */ + @objc public var disabledToolbarClasses: [UIViewController.Type] = [] + + /** + Enable automatic toolbar creation within the scope of enabled toolbar viewControllers classes. + Within this scope, 'enableAutoToolbar' property is ignored. Class should be kind of UIViewController. + If same Class is added in disabledToolbarClasses list, then enabledToolbarClasses will be ignore. + */ + @objc public var enabledToolbarClasses: [UIViewController.Type] = [] + + /** + Allowed subclasses of UIView to add all inner textField, + this will allow to navigate between textField contains in different superview. + Class should be kind of UIView. + */ + @objc public var toolbarPreviousNextAllowedClasses: [UIView.Type] = [] + + /** + Disabled classes to ignore resignOnTouchOutside' property, Class should be kind of UIViewController. + */ + @objc public var disabledTouchResignedClasses: [UIViewController.Type] = [] + + /** + Enabled classes to forcefully enable 'resignOnTouchOutside' property. + Class should be kind of UIViewController + . If same Class is added in disabledTouchResignedClasses list, then enabledTouchResignedClasses will be ignored. + */ + @objc public var enabledTouchResignedClasses: [UIViewController.Type] = [] + + /** + if resignOnTouchOutside is enabled then you can customize the behavior + to not recognize gesture touches on some specific view subclasses. + Class should be kind of UIView. Default is [UIControl, UINavigationBar] + */ + @objc public var touchResignedGestureIgnoreClasses: [UIView.Type] = [] + + // MARK: Third Party Library support + /// Add TextField/TextView Notifications customized Notifications. + /// For example while using YYTextView https://github.com/ibireme/YYText + + /**************************************************************************************/ + + // MARK: Initialization/De-initialization + + /* Singleton Object Initialization. */ + override init() { + + super.init() + + self.addActiveConfigurationObserver() + + // Creating gesture for resignOnTouchOutside. (Enhancement ID: #14) + resignFirstResponderGesture.isEnabled = resignOnTouchOutside + + disabledDistanceHandlingClasses.append(UITableViewController.self) + disabledDistanceHandlingClasses.append(UIInputViewController.self) + disabledDistanceHandlingClasses.append(UIAlertController.self) + + disabledToolbarClasses.append(UIAlertController.self) + disabledToolbarClasses.append(UIInputViewController.self) + + disabledTouchResignedClasses.append(UIAlertController.self) + disabledTouchResignedClasses.append(UIInputViewController.self) + + toolbarPreviousNextAllowedClasses.append(UITableView.self) + toolbarPreviousNextAllowedClasses.append(UICollectionView.self) + toolbarPreviousNextAllowedClasses.append(IQPreviousNextView.self) + + touchResignedGestureIgnoreClasses.append(UIControl.self) + touchResignedGestureIgnoreClasses.append(UINavigationBar.self) + + NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive(_:)), + name: UIApplication.didBecomeActiveNotification, object: nil) + + // (Bug ID: #550) + // Loading IQToolbar, IQTitleBarButtonItem, IQBarButtonItem to fix first time keyboard appearance delay + // If you experience exception breakpoint issue at below line then try these solutions + // https://stackoverflow.com/questions/27375640/all-exception-break-point-is-stopping-for-no-reason-on-simulator + DispatchQueue.main.async { + let textField: UIView = UITextField() + textField.iq.addDone(target: nil, action: #selector(self.doneAction(_:))) + textField.iq.addPreviousNextDone(target: nil, previousAction: #selector(self.previousAction(_:)), + nextAction: #selector(self.nextAction(_:)), + doneAction: #selector(self.doneAction(_:))) + } + } + + deinit { + // Disable the keyboard manager. + enable = false + } + + // MARK: Public Methods + + /* Refreshes textField/textView position if any external changes is explicitly made by user. */ + @objc public func reloadLayoutIfNeeded() { + + guard privateIsEnabled(), + activeConfiguration.keyboardInfo.keyboardShowing, + activeConfiguration.isReady else { + return + } + adjustPosition() + } +} + +@available(iOSApplicationExtension, unavailable) +extension IQKeyboardManager: UIGestureRecognizerDelegate { + + /** Resigning on tap gesture. (Enhancement ID: #14)*/ + @objc private func tapRecognized(_ gesture: UITapGestureRecognizer) { + + if gesture.state == .ended { + + // Resigning currently responder textField. + resignFirstResponder() + } + } + + /** Note: returning YES is guaranteed to allow simultaneous recognition. + returning NO is not guaranteed to prevent simultaneous recognition, + as the other gesture's delegate may return YES. + */ + @objc public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, + shouldRecognizeSimultaneouslyWith + otherGestureRecognizer: UIGestureRecognizer) -> Bool { + return false + } + + /** + To not detect touch events in a subclass of UIControl, + these may have added their own selector for specific work + */ + @objc public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, + shouldReceive touch: UITouch) -> Bool { + // (Bug ID: #145) + // Should not recognize gesture if the clicked view is either UIControl or UINavigationBar(<Back button etc...) + + for ignoreClass in touchResignedGestureIgnoreClasses where touch.view?.isKind(of: ignoreClass) ?? false { + return false + } + + return true + } + +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManagerCompatible/IQKeyboardManagerCompatible.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManagerCompatible/IQKeyboardManagerCompatible.swift new file mode 100644 index 0000000..d4bad3c --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManagerCompatible/IQKeyboardManagerCompatible.swift @@ -0,0 +1,59 @@ +// +// IQKeyboardManagerCompatible.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +/// Wrapper for IQKeyboardManager compatible types. This type provides an extension point for +/// convenience methods in IQKeyboardManager. +@available(iOSApplicationExtension, unavailable) +public struct IQKeyboardManagerWrapper<Base> { + public let base: Base + public init(_ base: Base) { + self.base = base + } +} + +// swiftlint:disable identifier_name +/// Represents an object type that is compatible with IQKeyboardManager. You can use `iq` property to get a +/// value in the namespace of IQKeyboardManager. +@available(iOSApplicationExtension, unavailable) +public protocol IQKeyboardManagerCompatible { + /// Type being extended. + associatedtype Base + + /// Instance IQKeyboardManager extension point. + var iq: IQKeyboardManagerWrapper<Base> { get set } +} + +// swiftlint:disable unused_setter_value +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManagerCompatible { + + /// Instance IQKeyboardManager extension point. + var iq: IQKeyboardManagerWrapper<Self> { + get { IQKeyboardManagerWrapper(self) } + set {} + } +} +// swiftlint:enable unused_setter_value +// swiftlint:enable identifier_name diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift new file mode 100644 index 0000000..e8f7188 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift @@ -0,0 +1,39 @@ +// +// IQPlaceholderable.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +public protocol IQPlaceholderable: AnyObject { + + var placeholder: String? { get set } + var attributedPlaceholder: NSAttributedString? { get set } +} + +@available(iOSApplicationExtension, unavailable) +extension UITextField: IQPlaceholderable { } + +@available(iOSApplicationExtension, unavailable) +extension IQTextView: IQPlaceholderable { } diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift new file mode 100644 index 0000000..b4e5216 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift @@ -0,0 +1,208 @@ +// +// IQTextView.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +/** @abstract UITextView with placeholder support */ +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc open class IQTextView: UITextView { + + @objc required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), + name: UITextView.textDidChangeNotification, object: self) + } + + @objc override public init(frame: CGRect, textContainer: NSTextContainer?) { + super.init(frame: frame, textContainer: textContainer) + NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), + name: UITextView.textDidChangeNotification, object: self) + } + + @objc override open func awakeFromNib() { + super.awakeFromNib() + NotificationCenter.default.addObserver(self, selector: #selector(self.refreshPlaceholder), + name: UITextView.textDidChangeNotification, object: self) + } + + private var placeholderInsets: UIEdgeInsets { + let top: CGFloat = self.textContainerInset.top + let left: CGFloat = self.textContainerInset.left + self.textContainer.lineFragmentPadding + let bottom: CGFloat = self.textContainerInset.bottom + let right: CGFloat = self.textContainerInset.right + self.textContainer.lineFragmentPadding + return UIEdgeInsets(top: top, left: left, bottom: bottom, right: right) + } + + private var placeholderExpectedFrame: CGRect { + let insets: UIEdgeInsets = self.placeholderInsets + let maxWidth: CGFloat = self.frame.width-insets.left-insets.right + let size: CGSize = CGSize(width: maxWidth, height: self.frame.height-insets.top-insets.bottom) + let expectedSize: CGSize = placeholderLabel.sizeThatFits(size) + + return CGRect(x: insets.left, y: insets.top, width: maxWidth, height: expectedSize.height) + } + + lazy var placeholderLabel: UILabel = { + let label = UILabel() + + label.autoresizingMask = [.flexibleWidth, .flexibleHeight] + label.lineBreakMode = .byWordWrapping + label.numberOfLines = 0 + label.font = self.font + label.textAlignment = self.textAlignment + label.backgroundColor = UIColor.clear + label.isAccessibilityElement = false + label.textColor = UIColor.placeholderText + label.alpha = 0 + self.addSubview(label) + + return label + }() + + /** @abstract To set textView's placeholder text color. */ + @IBInspectable open var placeholderTextColor: UIColor? { + + get { + return placeholderLabel.textColor + } + + set { + placeholderLabel.textColor = newValue + } + } + + /** @abstract To set textView's placeholder text. Default is nil. */ + @IBInspectable open var placeholder: String? { + + get { + return placeholderLabel.text + } + + set { + placeholderLabel.text = newValue + refreshPlaceholder() + } + } + + /** @abstract To set textView's placeholder attributed text. Default is nil. */ + open var attributedPlaceholder: NSAttributedString? { + get { + return placeholderLabel.attributedText + } + + set { + placeholderLabel.attributedText = newValue + refreshPlaceholder() + } + } + + @objc override open func layoutSubviews() { + super.layoutSubviews() + + placeholderLabel.frame = placeholderExpectedFrame + } + + @objc private func refreshPlaceholder() { + + let text: String = text ?? attributedText?.string ?? "" + if text.isEmpty { + placeholderLabel.alpha = 1 + } else { + placeholderLabel.alpha = 0 + } + } + + @objc override open var text: String! { + + didSet { + refreshPlaceholder() + } + } + + open override var attributedText: NSAttributedString! { + + didSet { + refreshPlaceholder() + } + } + + @objc override open var font: UIFont? { + + didSet { + + if let unwrappedFont: UIFont = font { + placeholderLabel.font = unwrappedFont + } else { + placeholderLabel.font = UIFont.systemFont(ofSize: 12) + } + } + } + + @objc override open var textAlignment: NSTextAlignment { + didSet { + placeholderLabel.textAlignment = textAlignment + } + } + + @objc override weak open var delegate: UITextViewDelegate? { + + get { + refreshPlaceholder() + return super.delegate + } + + set { + super.delegate = newValue + } + } + + @objc override open var intrinsicContentSize: CGSize { + guard !hasText else { + return super.intrinsicContentSize + } + + var newSize: CGSize = super.intrinsicContentSize + let placeholderInsets: UIEdgeInsets = self.placeholderInsets + newSize.height = placeholderExpectedFrame.height + placeholderInsets.top + placeholderInsets.bottom + + return newSize + } + + @objc override open func caretRect(for position: UITextPosition) -> CGRect { + var originalRect = super.caretRect(for: position) + + // When placeholder is visible and text alignment is centered + if placeholderLabel.alpha == 1 && self.textAlignment == .center { + // Calculate the width of the placeholder text + let textSize = placeholderLabel.text?.size(withAttributes: [.font: placeholderLabel.font ?? UIFont.systemFont(ofSize: UIFont.systemFontSize)]) ?? .zero + // Calculate the starting x position of the centered placeholder text + let centeredTextX = (self.bounds.size.width - textSize.width) / 2 + // Update the caret position to match the starting x position of the centered text + originalRect.origin.x = centeredTextX + } + + return originalRect + } + +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift new file mode 100644 index 0000000..52af9cc --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift @@ -0,0 +1,120 @@ +// +// IQBarButtonItem.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc open class IQBarButtonItem: UIBarButtonItem { + + internal static let flexibleBarButtonItem: IQBarButtonItem = IQBarButtonItem(barButtonSystemItem: .flexibleSpace, + target: nil, action: nil) + + @objc public override init() { + super.init() + initialize() + } + + @objc public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + initialize() + } + + private func initialize() { + + let states: [UIControl.State] = [.normal, .highlighted, .disabled, .focused] + + for state in states { + + setBackgroundImage(UIImage(), for: state, barMetrics: .default) + setBackgroundImage(UIImage(), for: state, style: .plain, barMetrics: .default) + setBackButtonBackgroundImage(UIImage(), for: state, barMetrics: .default) + } + + setTitlePositionAdjustment(UIOffset(), for: .default) + setBackgroundVerticalPositionAdjustment(0, for: .default) + setBackButtonBackgroundVerticalPositionAdjustment(0, for: .default) + } + + @objc override open var tintColor: UIColor? { + didSet { + + var textAttributes: [NSAttributedString.Key: Any] = [:] + textAttributes[.foregroundColor] = tintColor + + if let attributes: [NSAttributedString.Key: Any] = titleTextAttributes(for: .normal) { + for (key, value) in attributes { + textAttributes[key] = value + } + } + + setTitleTextAttributes(textAttributes, for: .normal) + } + } + + /** + 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 + */ + internal var isSystemItem: Bool = false + + /** + 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. + + @param target Target object. + @param action Target Selector. + */ + @objc open func setTarget(_ target: AnyObject?, action: Selector?) { + if let target: AnyObject = target, let action: Selector = action { + invocation = IQInvocation(target, action) + } else { + invocation = nil + } + } + + /** + Customized Invocation to be called when button is pressed. + invocation is internally created using setTarget:action: method. + */ + @objc open var invocation: IQInvocation? { + didSet { + // We have to put this condition here because if we override this function then + // We were getting "Cannot override '_' which has been marked unavailable" in Xcode 15 + if let titleBarButton = self as? IQTitleBarButtonItem { + + if let target = invocation?.target, let action = invocation?.action { + titleBarButton.isEnabled = true + titleBarButton.titleButton?.isEnabled = true + titleBarButton.titleButton?.addTarget(target, action: action, for: .touchUpInside) + } else { + titleBarButton.isEnabled = false + titleBarButton.titleButton?.isEnabled = false + titleBarButton.titleButton?.removeTarget(nil, action: nil, for: .touchUpInside) + } + } + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift new file mode 100644 index 0000000..2ba446a --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift @@ -0,0 +1,42 @@ +// +// IQInvocation.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc public final class IQInvocation: NSObject { + @objc public weak var target: AnyObject? + @objc public var action: Selector + + @objc public init(_ target: AnyObject, _ action: Selector) { + self.target = target + self.action = action + } + + @objc public func invoke(from: Any) { + if let target: AnyObject = target { + UIApplication.shared.sendAction(action, to: target, from: from, for: UIEvent()) + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift new file mode 100644 index 0000000..d841752 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift @@ -0,0 +1,29 @@ +// +// IQPreviousNextView.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc open class IQPreviousNextView: UIView { +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift new file mode 100644 index 0000000..9c969d3 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift @@ -0,0 +1,158 @@ +// +// IQTitleBarButtonItem.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc open class IQTitleBarButtonItem: IQBarButtonItem { + + @objc open var titleFont: UIFont? { + + didSet { + if let unwrappedFont: UIFont = titleFont { + titleButton?.titleLabel?.font = unwrappedFont + } else { + titleButton?.titleLabel?.font = UIFont.systemFont(ofSize: 13) + } + } + } + + @objc override open var title: String? { + didSet { + titleButton?.setTitle(title, for: .normal) + updateAccessibility() + } + } + + /** + titleColor to be used for displaying button text when displaying title (disabled state). + */ + @objc open var titleColor: UIColor? { + + didSet { + + if let color: UIColor = titleColor { + titleButton?.setTitleColor(color, for: .disabled) + } else { + titleButton?.setTitleColor(UIColor.lightGray, for: .disabled) + } + } + } + + /** + selectableTitleColor to be used for displaying button text when button is enabled. + */ + @objc open var selectableTitleColor: UIColor? { + + didSet { + + if let color: UIColor = selectableTitleColor { + titleButton?.setTitleColor(color, for: .normal) + } else { + titleButton?.setTitleColor(UIColor.systemBlue, for: .normal) + } + } + } + + internal var titleButton: UIButton? + private var _titleView: UIView? + + override init() { + super.init() + } + + @objc public convenience init(title: String?) { + + self.init(title: nil, style: .plain, target: nil, action: nil) + + _titleView = UIView() + _titleView?.backgroundColor = UIColor.clear + + titleButton = UIButton(type: .system) + titleButton?.isAccessibilityElement = false + titleButton?.isEnabled = false + titleButton?.titleLabel?.numberOfLines = 3 + titleButton?.setTitleColor(UIColor.lightGray, for: .disabled) + titleButton?.setTitleColor(UIColor.systemBlue, for: .normal) + titleButton?.backgroundColor = UIColor.clear + titleButton?.titleLabel?.textAlignment = .center + titleButton?.setTitle(title, for: .normal) + titleFont = UIFont.systemFont(ofSize: 13.0) + titleButton?.titleLabel?.font = self.titleFont + _titleView?.addSubview(titleButton!) + + let lowPriority: UILayoutPriority = UILayoutPriority(rawValue: UILayoutPriority.defaultLow.rawValue-1) + let highPriority: UILayoutPriority = UILayoutPriority(rawValue: UILayoutPriority.defaultHigh.rawValue-1) + + _titleView?.translatesAutoresizingMaskIntoConstraints = false + _titleView?.setContentHuggingPriority(lowPriority, for: .vertical) + _titleView?.setContentHuggingPriority(lowPriority, for: .horizontal) + _titleView?.setContentCompressionResistancePriority(highPriority, for: .vertical) + _titleView?.setContentCompressionResistancePriority(highPriority, for: .horizontal) + + titleButton?.translatesAutoresizingMaskIntoConstraints = false + titleButton?.setContentHuggingPriority(lowPriority, for: .vertical) + titleButton?.setContentHuggingPriority(lowPriority, for: .horizontal) + titleButton?.setContentCompressionResistancePriority(highPriority, for: .vertical) + titleButton?.setContentCompressionResistancePriority(highPriority, for: .horizontal) + + let top: NSLayoutConstraint = NSLayoutConstraint(item: titleButton!, attribute: .top, + relatedBy: .equal, + toItem: _titleView, attribute: .top, + multiplier: 1, constant: 0) + let bottom: NSLayoutConstraint = NSLayoutConstraint(item: titleButton!, attribute: .bottom, + relatedBy: .equal, + toItem: _titleView, attribute: .bottom, + multiplier: 1, constant: 0) + let leading: NSLayoutConstraint = NSLayoutConstraint(item: titleButton!, attribute: .leading, + relatedBy: .equal, + toItem: _titleView, attribute: .leading, + multiplier: 1, constant: 0) + let trailing: NSLayoutConstraint = NSLayoutConstraint(item: titleButton!, attribute: .trailing, + relatedBy: .equal, + toItem: _titleView, attribute: .trailing, + multiplier: 1, constant: 0) + + _titleView?.addConstraints([top, bottom, leading, trailing]) + + customView = _titleView + } + + @objc required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + private func updateAccessibility() { + if title == nil || title?.isEmpty == true { + isAccessibilityElement = false + accessibilityTraits = .none + } else if titleButton?.isEnabled == true { + isAccessibilityElement = true + accessibilityTraits = .button + } else { + isAccessibilityElement = true + accessibilityTraits = .staticText + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift new file mode 100644 index 0000000..65d692c --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift @@ -0,0 +1,181 @@ +// +// IQToolbar.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +/** @abstract IQToolbar for IQKeyboardManager. */ +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc open class IQToolbar: UIToolbar, UIInputViewAudioFeedback { + + override init(frame: CGRect) { + super.init(frame: frame) + + initialize() + } + + @objc required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + initialize() + } + + private func initialize() { + + sizeToFit() + + autoresizingMask = .flexibleWidth + self.isTranslucent = true + self.barTintColor = nil + + let positions: [UIBarPosition] = [.any, .bottom, .top, .topAttached] + + for position in positions { + + self.setBackgroundImage(nil, forToolbarPosition: position, barMetrics: .default) + self.setShadowImage(nil, forToolbarPosition: .any) + } + + // Background color + self.backgroundColor = nil + } + + /** + Additional bar buttons to show at the leading side. + */ + open var additionalLeadingItems: [UIBarButtonItem] = [] + + /** + Additional bar buttons to show at the trailing side. + */ + open var additionalTrailingItems: [UIBarButtonItem] = [] + + /** + Previous bar button of toolbar. + */ + private var privatePreviousBarButton: IQBarButtonItem? + @objc open var previousBarButton: IQBarButtonItem { + get { + if privatePreviousBarButton == nil { + privatePreviousBarButton = IQBarButtonItem(image: nil, style: .plain, target: nil, action: nil) + } + return privatePreviousBarButton! + } + + set (newValue) { + privatePreviousBarButton = newValue + } + } + + /** + Next bar button of toolbar. + */ + private var privateNextBarButton: IQBarButtonItem? + @objc open var nextBarButton: IQBarButtonItem { + get { + if privateNextBarButton == nil { + privateNextBarButton = IQBarButtonItem(image: nil, style: .plain, target: nil, action: nil) + } + return privateNextBarButton! + } + + set (newValue) { + privateNextBarButton = newValue + } + } + + /** + Title bar button of toolbar. + */ + private var privateTitleBarButton: IQTitleBarButtonItem? + @objc open var titleBarButton: IQTitleBarButtonItem { + get { + if privateTitleBarButton == nil { + privateTitleBarButton = IQTitleBarButtonItem(title: nil) + } + return privateTitleBarButton! + } + + set (newValue) { + privateTitleBarButton = newValue + } + } + + /** + Done bar button of toolbar. + */ + private var privateDoneBarButton: IQBarButtonItem? + @objc open var doneBarButton: IQBarButtonItem { + get { + if privateDoneBarButton == nil { + privateDoneBarButton = IQBarButtonItem(title: nil, style: .done, target: nil, action: nil) + } + return privateDoneBarButton! + } + + set (newValue) { + privateDoneBarButton = newValue + } + } + + /** + Fixed space bar button of toolbar. + */ + private var privateFixedSpaceBarButton: IQBarButtonItem? + @objc open var fixedSpaceBarButton: IQBarButtonItem { + get { + if privateFixedSpaceBarButton == nil { + privateFixedSpaceBarButton = IQBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) + } + privateFixedSpaceBarButton?.isSystemItem = true + privateFixedSpaceBarButton?.width = 6 + + return privateFixedSpaceBarButton! + } + + set (newValue) { + privateFixedSpaceBarButton = newValue + } + } + + @objc override open func sizeThatFits(_ size: CGSize) -> CGSize { + var sizeThatFit: CGSize = super.sizeThatFits(size) + sizeThatFit.height = 44 + return sizeThatFit + } + + @objc override open var tintColor: UIColor! { + + didSet { + if let unwrappedItems: [UIBarButtonItem] = items { + for item in unwrappedItems { + item.tintColor = tintColor + } + } + } + } + + @objc open var enableInputClicksWhenVisible: Bool { + return true + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift new file mode 100644 index 0000000..b9ae6b1 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift @@ -0,0 +1,319 @@ +// +// IQUIView+IQKeyboardToolbar.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +private struct AssociatedKeys { + static var toolbar: Int = 0 + static var hidePlaceholder: Int = 0 + static var placeholder: Int = 0 +} + +@available(iOSApplicationExtension, unavailable) +@MainActor +public extension IQKeyboardManagerWrapper where Base: UIView { + + // MARK: Toolbar + + /** + IQToolbar references for better customization control. + */ + var toolbar: IQToolbar { + var toolbar: IQToolbar? = base.inputAccessoryView as? IQToolbar + + if toolbar == nil { + toolbar = objc_getAssociatedObject(base, &AssociatedKeys.toolbar) as? IQToolbar + } + + if let unwrappedToolbar: IQToolbar = toolbar { + return unwrappedToolbar + } else { + + let width: CGFloat = base.window?.windowScene?.screen.bounds.width ?? 0 + + let frame = CGRect(origin: .zero, size: .init(width: width, height: 44)) + let newToolbar = IQToolbar(frame: frame) + + objc_setAssociatedObject(base, &AssociatedKeys.toolbar, newToolbar, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + + return newToolbar + } + } + + // MARK: Toolbar title + + /** + If `hideToolbarPlaceholder` is YES, then title will not be added to the toolbar. Default to NO. + */ + var hidePlaceholder: Bool { + get { + return objc_getAssociatedObject(base, &AssociatedKeys.hidePlaceholder) as? Bool ?? false + } + set(newValue) { + objc_setAssociatedObject(base, &AssociatedKeys.hidePlaceholder, + newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + toolbar.titleBarButton.title = drawingPlaceholder + } + } + + /** + `toolbarPlaceholder` to override default `placeholder` text when drawing text on toolbar. + */ + var placeholder: String? { + get { + return objc_getAssociatedObject(base, &AssociatedKeys.placeholder) as? String + } + set(newValue) { + objc_setAssociatedObject(base, &AssociatedKeys.placeholder, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + toolbar.titleBarButton.title = drawingPlaceholder + } + } + + /** + `drawingToolbarPlaceholder` will be actual text used to draw on toolbar. + This would either `placeholder` or `toolbarPlaceholder`. + */ + var drawingPlaceholder: String? { + + if hidePlaceholder { + return nil + } else if placeholder?.isEmpty == false { + return placeholder + } else if let placeholderable: IQPlaceholderable = base as? IQPlaceholderable { + + if let placeholder = placeholderable.attributedPlaceholder?.string, + !placeholder.isEmpty { + return placeholder + } else if let placeholder = placeholderable.placeholder { + return placeholder + } else { + return nil + } + } else { + return nil + } + } + + // MARK: Common + + // swiftlint:disable cyclomatic_complexity + // swiftlint:disable function_body_length + func addToolbar(target: AnyObject?, + previousConfiguration: IQBarButtonItemConfiguration? = nil, + nextConfiguration: IQBarButtonItemConfiguration? = nil, + rightConfiguration: IQBarButtonItemConfiguration? = nil, + title: String?, + titleAccessibilityLabel: String? = nil) { + + // If can't set InputAccessoryView. Then return + if base.responds(to: #selector(setter: UITextField.inputAccessoryView)) { + + // Creating a toolBar for phoneNumber keyboard + let toolbar: IQToolbar = toolbar + + var items: [UIBarButtonItem] = [] + + if let previousConfiguration: IQBarButtonItemConfiguration = previousConfiguration { + + let prev: IQBarButtonItem = previousConfiguration.apply(on: toolbar.previousBarButton, target: target) + toolbar.previousBarButton = prev + items.append(prev) + } + + if previousConfiguration != nil, nextConfiguration != nil { + + items.append(toolbar.fixedSpaceBarButton) + } + + if let nextConfiguration: IQBarButtonItemConfiguration = nextConfiguration { + + let next: IQBarButtonItem = nextConfiguration.apply(on: toolbar.nextBarButton, target: target) + toolbar.nextBarButton = next + items.append(next) + } + + if !toolbar.additionalLeadingItems.isEmpty { + items.append(contentsOf: toolbar.additionalLeadingItems) + } + + // Title bar button item + do { + // Flexible space + items.append(IQBarButtonItem.flexibleBarButtonItem) + + // Title button + toolbar.titleBarButton.title = title + toolbar.titleBarButton.accessibilityLabel = titleAccessibilityLabel + toolbar.titleBarButton.accessibilityIdentifier = titleAccessibilityLabel + + toolbar.titleBarButton.customView?.frame = .zero + + items.append(toolbar.titleBarButton) + + // Flexible space + items.append(IQBarButtonItem.flexibleBarButtonItem) + } + + if !toolbar.additionalTrailingItems.isEmpty { + items.append(contentsOf: toolbar.additionalTrailingItems) + } + + if let rightConfiguration: IQBarButtonItemConfiguration = rightConfiguration { + + let done: IQBarButtonItem = rightConfiguration.apply(on: toolbar.doneBarButton, target: target) + toolbar.doneBarButton = done + items.append(done) + } + + // Adding button to toolBar. + toolbar.items = items + + if let textInput: UITextInput = base as? UITextInput { + switch textInput.keyboardAppearance { + case .dark?: + toolbar.barStyle = .black + default: + toolbar.barStyle = .default + } + } + + // Setting toolbar to keyboard. + let reloadInputViews: Bool = base.inputAccessoryView != toolbar + if reloadInputViews { + if let textField: UITextField = base as? UITextField { + textField.inputAccessoryView = toolbar + } else if let textView: UITextView = base as? UITextView { + textView.inputAccessoryView = toolbar + } + base.reloadInputViews() + } + } + } + // swiftlint:enable function_body_length + // swiftlint:enable cyclomatic_complexity + + // MARK: Right + func addDone(target: AnyObject?, + action: Selector, + showPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + + let title: String? = showPlaceholder ? drawingPlaceholder : nil + + addDone(target: target, action: action, + title: title, titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addDone(target: AnyObject?, + action: Selector, + title: String?, titleAccessibilityLabel: String? = nil) { + + let rightConfiguration = IQBarButtonItemConfiguration(systemItem: .done, action: action) + + addToolbar(target: target, rightConfiguration: rightConfiguration, + title: title, titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addRightButton(target: AnyObject?, + configuration: IQBarButtonItemConfiguration, + showPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + let title: String? = showPlaceholder ? drawingPlaceholder : nil + addRightButton(target: target, configuration: configuration, title: title, + titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addRightButton(target: AnyObject?, + configuration: IQBarButtonItemConfiguration, + title: String?, titleAccessibilityLabel: String? = nil) { + addToolbar(target: target, rightConfiguration: configuration, title: title, + titleAccessibilityLabel: titleAccessibilityLabel) + } + + // MARK: Right/Left + func addRightLeft(target: AnyObject?, + rightConfiguration: IQBarButtonItemConfiguration, leftConfiguration: IQBarButtonItemConfiguration, + showPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + let title: String? = showPlaceholder ? drawingPlaceholder : nil + addRightLeft(target: target, + rightConfiguration: rightConfiguration, leftConfiguration: leftConfiguration, + title: title, titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addRightLeft(target: AnyObject?, + rightConfiguration: IQBarButtonItemConfiguration, leftConfiguration: IQBarButtonItemConfiguration, + title: String?, titleAccessibilityLabel: String? = nil) { + addToolbar(target: target, + previousConfiguration: leftConfiguration, rightConfiguration: rightConfiguration, + title: title, titleAccessibilityLabel: titleAccessibilityLabel) + } + + // MARK: Previous/Next/Right + + func addPreviousNextRight(target: AnyObject?, + previousConfiguration: IQBarButtonItemConfiguration? = nil, + nextConfiguration: IQBarButtonItemConfiguration? = nil, + rightConfiguration: IQBarButtonItemConfiguration?, + showPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + + let title: String? = showPlaceholder ? drawingPlaceholder : nil + addPreviousNextRight(target: target, + previousConfiguration: previousConfiguration, nextConfiguration: nextConfiguration, + rightConfiguration: rightConfiguration, + title: title, titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addPreviousNextRight(target: AnyObject?, + previousConfiguration: IQBarButtonItemConfiguration? = nil, + nextConfiguration: IQBarButtonItemConfiguration? = nil, + rightConfiguration: IQBarButtonItemConfiguration?, + title: String?, titleAccessibilityLabel: String? = nil) { + + addToolbar(target: target, + previousConfiguration: previousConfiguration, nextConfiguration: nextConfiguration, + rightConfiguration: rightConfiguration, + title: title, titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addPreviousNextDone(target: AnyObject?, previousAction: Selector, nextAction: Selector, doneAction: Selector, + showPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + let title: String? = showPlaceholder ? drawingPlaceholder : nil + addPreviousNextDone(target: target, previousAction: previousAction, nextAction: nextAction, + doneAction: doneAction, + title: title, titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addPreviousNextDone(target: AnyObject?, + previousAction: Selector, nextAction: Selector, doneAction: Selector, + title: String?, titleAccessibilityLabel: String? = nil) { + + let previousConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardPreviousImage, + action: previousAction) + let nextConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardNextImage, action: nextAction) + let rightConfiguration = IQBarButtonItemConfiguration(systemItem: .done, action: doneAction) + + addToolbar(target: target, previousConfiguration: previousConfiguration, + nextConfiguration: nextConfiguration, rightConfiguration: rightConfiguration, + title: title, titleAccessibilityLabel: titleAccessibilityLabel) + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbarDeprecated.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbarDeprecated.swift new file mode 100644 index 0000000..9437935 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbarDeprecated.swift @@ -0,0 +1,228 @@ +// +// IQUIView+IQKeyboardToolbarDeprecated.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +// swiftlint:disable unused_setter_value +// swiftlint:disable line_length +// swiftlint:disable function_parameter_count +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc public extension UIView { + + @available(*, unavailable, renamed: "iq.toolbar") + var keyboardToolbar: IQToolbar { + get { fatalError() } + set {} + } + + @available(*, unavailable, renamed: "iq.hidePlaceholder") + var shouldHideToolbarPlaceholder: Bool { + get { false } + set {} + } + + @available(*, unavailable, renamed: "iq.placeholder") + var toolbarPlaceholder: String? { + get { nil } + set {} + } + + @available(*, unavailable, renamed: "iq.drawingPlaceholder") + var drawingToolbarPlaceholder: String? { + get { nil } + set {} + } + + @available(*, unavailable, renamed: "iq.addToolbar(target:previousConfiguration:nextConfiguration:rightConfiguration:title:titleAccessibilityLabel:)") + func addKeyboardToolbarWithTarget(target: AnyObject?, + titleText: String?, + titleAccessibilityLabel: String? = nil, + rightBarButtonConfiguration: IQBarButtonItemConfiguration?, + previousBarButtonConfiguration: IQBarButtonItemConfiguration? = nil, + nextBarButtonConfiguration: IQBarButtonItemConfiguration? = nil) { + } + + @available(*, unavailable, renamed: "iq.addDone(target:action:showPlaceholder:titleAccessibilityLabel:)") + func addDoneOnKeyboardWithTarget(_ target: AnyObject?, + action: Selector, + shouldShowPlaceholder: Bool = false, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addDone(target:action:title:titleAccessibilityLabel:)") + func addDoneOnKeyboardWithTarget(_ target: AnyObject?, + action: Selector, + titleText: String?, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addRightButton(target:configuration:showPlaceholder:titleAccessibilityLabel:)") + func addRightButtonOnKeyboardWithImage(_ image: UIImage, + target: AnyObject?, + action: Selector, + shouldShowPlaceholder: Bool = false, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addRightButton(target:configuration:title:titleAccessibilityLabel:)") + func addRightButtonOnKeyboardWithImage(_ image: UIImage, + target: AnyObject?, + action: Selector, + titleText: String?, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addRightButton(target:configuration:showPlaceholder:titleAccessibilityLabel:)") + func addRightButtonOnKeyboardWithText(_ text: String, + target: AnyObject?, + action: Selector, + shouldShowPlaceholder: Bool = false, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addRightButton(target:configuration:title:titleAccessibilityLabel:)") + func addRightButtonOnKeyboardWithText(_ text: String, + target: AnyObject?, + action: Selector, + titleText: String?, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addRightLeft(target:rightConfiguration:leftConfiguration:showPlaceholder:titleAccessibilityLabel:)") + func addCancelDoneOnKeyboardWithTarget(_ target: AnyObject?, + cancelAction: Selector, + doneAction: Selector, + shouldShowPlaceholder: Bool = false, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addRightLeft(target:rightConfiguration:leftConfiguration:showPlaceholder:titleAccessibilityLabel:)") + func addRightLeftOnKeyboardWithTarget(_ target: AnyObject?, + leftButtonTitle: String, + rightButtonTitle: String, + leftButtonAction: Selector, + rightButtonAction: Selector, + shouldShowPlaceholder: Bool = false, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addRightLeft(target:rightConfiguration:leftConfiguration:showPlaceholder:titleAccessibilityLabel:)") + func addRightLeftOnKeyboardWithTarget(_ target: AnyObject?, + leftButtonImage: UIImage, + rightButtonImage: UIImage, + leftButtonAction: Selector, + rightButtonAction: Selector, + shouldShowPlaceholder: Bool = false, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addRightLeft(target:rightConfiguration:leftConfiguration:title:titleAccessibilityLabel:)") + func addCancelDoneOnKeyboardWithTarget(_ target: AnyObject?, + cancelAction: Selector, + doneAction: Selector, + titleText: String?, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addRightLeft(target:rightConfiguration:leftConfiguration:title:titleAccessibilityLabel:)") + func addRightLeftOnKeyboardWithTarget(_ target: AnyObject?, + leftButtonTitle: String, + rightButtonTitle: String, + leftButtonAction: Selector, + rightButtonAction: Selector, + titleText: String?, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addRightLeft(target:rightConfiguration:leftConfiguration:title:titleAccessibilityLabel:)") + func addRightLeftOnKeyboardWithTarget(_ target: AnyObject?, + leftButtonImage: UIImage, + rightButtonImage: UIImage, + leftButtonAction: Selector, + rightButtonAction: Selector, + titleText: String?, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addPreviousNextDone(target:previousAction:nextAction:doneAction:showPlaceholder:titleAccessibilityLabel:)") + func addPreviousNextDone(_ target: AnyObject?, + previousAction: Selector, + nextAction: Selector, + doneAction: Selector, + shouldShowPlaceholder: Bool = false, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addPreviousNextDone(target:previousAction:nextAction:doneAction:title:titleAccessibilityLabel:)") + func addPreviousNextDoneOnKeyboardWithTarget(_ target: AnyObject?, + previousAction: Selector, + nextAction: Selector, + doneAction: Selector, + titleText: String?, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addPreviousNextRight(target:previousConfiguration:nextConfiguration:rightConfiguration:showPlaceholder:titleAccessibilityLabel:)") + func addPreviousNextRightOnKeyboardWithTarget(_ target: AnyObject?, + rightButtonImage: UIImage, + previousAction: Selector, + nextAction: Selector, + rightButtonAction: Selector, + shouldShowPlaceholder: Bool = false, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addPreviousNextRight(target:previousConfiguration:nextConfiguration:rightConfiguration:showPlaceholder:titleAccessibilityLabel:)") + func addPreviousNextRightOnKeyboardWithTarget(_ target: AnyObject?, + rightButtonTitle: String, + previousAction: Selector, + nextAction: Selector, + rightButtonAction: Selector, + shouldShowPlaceholder: Bool = false, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addPreviousNextRight(target:previousConfiguration:nextConfiguration:rightConfiguration:title:titleAccessibilityLabel:)") + func addPreviousNextRightOnKeyboardWithTarget(_ target: AnyObject?, + rightButtonImage: UIImage, + previousAction: Selector, + nextAction: Selector, + rightButtonAction: Selector, + titleText: String?, + titleAccessibilityLabel: String? = nil) { + } + + @available(*, unavailable, renamed: "iq.addPreviousNextRight(target:previousConfiguration:nextConfiguration:rightConfiguration:title:titleAccessibilityLabel:)") + func addPreviousNextRightOnKeyboardWithTarget(_ target: AnyObject?, + rightButtonTitle: String, + previousAction: Selector, + nextAction: Selector, + rightButtonAction: Selector, + titleText: String?, + titleAccessibilityLabel: String? = nil) { + } +} +// swiftlint:enable unused_setter_value +// swiftlint:enable line_length +// swiftlint:enable function_parameter_count diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/IQKeyboardListener.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/IQKeyboardListener.swift new file mode 100644 index 0000000..b0e53a3 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/IQKeyboardListener.swift @@ -0,0 +1,115 @@ +// +// IQKeyboardListener.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +public class IQKeyboardListener { + + private var sizeObservers: [AnyHashable: SizeCompletion] = [:] + + private(set) var keyboardInfo: IQKeyboardInfo { + didSet { + if keyboardInfo != oldValue { + sendEvent() + } + } + } + + public var keyboardShowing: Bool { + keyboardInfo.keyboardShowing + } + + public var frame: CGRect { + keyboardInfo.frame + } + + public init() { + keyboardInfo = IQKeyboardInfo(notification: nil, name: .didHide) + // Registering for keyboard notification. + NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), + name: UIResponder.keyboardWillShowNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidShow(_:)), + name: UIResponder.keyboardDidShowNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(_:)), + name: UIResponder.keyboardWillHideNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidHide(_:)), + name: UIResponder.keyboardDidHideNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillChangeFrame(_:)), + name: UIResponder.keyboardWillChangeFrameNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidChangeFrame(_:)), + name: UIResponder.keyboardDidChangeFrameNotification, object: nil) + } + + @objc private func keyboardWillShow(_ notification: Notification) { + keyboardInfo = IQKeyboardInfo(notification: notification, name: .willShow) + } + + @objc private func keyboardDidShow(_ notification: Notification) { + keyboardInfo = IQKeyboardInfo(notification: notification, name: .didShow) + } + + @objc private func keyboardWillHide(_ notification: Notification?) { + keyboardInfo = IQKeyboardInfo(notification: notification, name: .willHide) + } + + @objc private func keyboardDidHide(_ notification: Notification) { + keyboardInfo = IQKeyboardInfo(notification: notification, name: .didHide) + } + + @objc private func keyboardWillChangeFrame(_ notification: Notification) { + keyboardInfo = IQKeyboardInfo(notification: notification, name: .willChangeFrame) + } + + @objc private func keyboardDidChangeFrame(_ notification: Notification) { + keyboardInfo = IQKeyboardInfo(notification: notification, name: .didChangeFrame) + } + + public func animate(alongsideTransition transition: @escaping () -> Void, completion: (() -> Void)? = nil) { + keyboardInfo.animate(alongsideTransition: transition, completion: completion) + } +} + +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardListener { + + typealias SizeCompletion = (_ name: IQKeyboardInfo.Name, _ size: CGSize) -> Void + + func registerSizeChange(identifier: AnyHashable, changeHandler: @escaping SizeCompletion) { + sizeObservers[identifier] = changeHandler + } + + func unregisterSizeChange(identifier: AnyHashable) { + sizeObservers[identifier] = nil + } + + private func sendEvent() { + + let size: CGSize = keyboardInfo.frame.size + + for block in sizeObservers.values { + block(keyboardInfo.name, size) + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/IQTextFieldViewListener.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/IQTextFieldViewListener.swift new file mode 100644 index 0000000..7718e81 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/IQTextFieldViewListener.swift @@ -0,0 +1,126 @@ +// +// IQTextFieldViewListener.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +public class IQTextFieldViewListener { + + private var textFieldViewObservers: [AnyHashable: TextFieldViewCompletion] = [:] + +#if swift(>=5.7) + private(set) var lastTextFieldViewInfo: IQTextFieldViewInfo? +#endif + + private(set) var textFieldViewInfo: IQTextFieldViewInfo? + + public var textFieldView: UIView? { + return textFieldViewInfo?.textFieldView + } + + public init() { + // Registering for keyboard notification. + NotificationCenter.default.addObserver(self, selector: #selector(self.didBeginEditing(_:)), + name: UITextField.textDidBeginEditingNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.didEndEditing(_:)), + name: UITextField.textDidEndEditingNotification, object: nil) + + NotificationCenter.default.addObserver(self, selector: #selector(self.didBeginEditing(_:)), + name: UITextView.textDidBeginEditingNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.didEndEditing(_:)), + name: UITextView.textDidEndEditingNotification, object: nil) + } + + @objc private func didBeginEditing(_ notification: Notification) { + guard let info: IQTextFieldViewInfo = IQTextFieldViewInfo(notification: notification, + name: .beginEditing) else { + return + } + +#if swift(>=5.7) + + if #available(iOS 16.0, *), + let lastTextFieldViewInfo = lastTextFieldViewInfo, + let textView: UITextView = lastTextFieldViewInfo.textFieldView as? UITextView, + textView.findInteraction?.isFindNavigatorVisible == true { + // // This means the this didBeginEditing call comes due to find interaction + textFieldViewInfo = lastTextFieldViewInfo + sendEvent(info: lastTextFieldViewInfo) + } else if textFieldViewInfo != info { + textFieldViewInfo = info + lastTextFieldViewInfo = nil + sendEvent(info: info) + } else { + lastTextFieldViewInfo = nil + } +#else + if textFieldViewInfo != info { + textFieldViewInfo = info + sendEvent(info: info) + } +#endif + } + + @objc private func didEndEditing(_ notification: Notification) { + guard let info: IQTextFieldViewInfo = IQTextFieldViewInfo(notification: notification, name: .endEditing) else { + return + } + + if textFieldViewInfo != info { +#if swift(>=5.7) + if #available(iOS 16.0, *), + let textView: UITextView = info.textFieldView as? UITextView, + textView.isFindInteractionEnabled { + lastTextFieldViewInfo = textFieldViewInfo + } else { + lastTextFieldViewInfo = nil + } +#endif + textFieldViewInfo = info + sendEvent(info: info) + textFieldViewInfo = nil + } + } +} + +@available(iOSApplicationExtension, unavailable) +public extension IQTextFieldViewListener { + + typealias TextFieldViewCompletion = (_ info: IQTextFieldViewInfo) -> Void + + func registerTextFieldViewChange(identifier: AnyHashable, changeHandler: @escaping TextFieldViewCompletion) { + textFieldViewObservers[identifier] = changeHandler + } + + func unregisterSizeChange(identifier: AnyHashable) { + textFieldViewObservers[identifier] = nil + } + + private func sendEvent(info: IQTextFieldViewInfo) { + + for block in textFieldViewObservers.values { + block(info) + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/Info/IQKeyboardInfo.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/Info/IQKeyboardInfo.swift new file mode 100644 index 0000000..b06a473 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/Info/IQKeyboardInfo.swift @@ -0,0 +1,135 @@ +// +// IQKeyboardInfo.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +public struct IQKeyboardInfo: Equatable { + nonisolated public static func == (lhs: Self, rhs: Self) -> Bool { + lhs.frame.equalTo(rhs.frame) + } + + @objc public enum Name: Int { + case willShow + case didShow + case willHide + case didHide + case willChangeFrame + case didChangeFrame + } + + public let name: Name + + /** To save keyboard frame. */ + public let frame: CGRect + + /** To save keyboard animation duration. */ + public let animationDuration: TimeInterval + + /** To mimic the keyboard animation */ + public let animationCurve: UIView.AnimationCurve + + public var keyboardShowing: Bool { + frame.height > 0 + } + + public init(notification: Notification?, name: Name) { + self.name = name + + let screenBounds: CGRect + if let screen: UIScreen = notification?.object as? UIScreen { + screenBounds = screen.bounds + } else { + screenBounds = UIScreen.main.bounds + } + + if let info: [AnyHashable: Any] = notification?.userInfo { + + // Getting keyboard animation. + if let curveValue: Int = info[UIResponder.keyboardAnimationCurveUserInfoKey] as? Int, + let curve: UIView.AnimationCurve = UIView.AnimationCurve(rawValue: curveValue) { + animationCurve = curve + } else { + animationCurve = .easeOut + } + + // Getting keyboard animation duration + if let duration: TimeInterval = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval, + duration != 0.0 { + animationDuration = duration + } else { + animationDuration = 0.25 + } + + // Getting UIKeyboardSize. + if var kbFrame: CGRect = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect { + + // If this is floating keyboard + if kbFrame.width < screenBounds.width, + kbFrame.maxY < screenBounds.height { + kbFrame.size = CGSize(width: kbFrame.size.width, height: 0) + } else { + // (Bug ID: #469) (Bug ID: #381) (Bug ID: #1506) + // Calculating actual keyboard covered size respect to window, + // keyboard frame may be different when hardware keyboard is attached + let keyboardHeight = CGFloat.maximum(screenBounds.height - kbFrame.minY, 0) + kbFrame.size = CGSize(width: kbFrame.size.width, height: keyboardHeight) + } + + frame = kbFrame + } else { + frame = CGRect(x: 0, y: screenBounds.height, width: screenBounds.width, height: 0) + } + } else { + animationCurve = .easeOut + animationDuration = 0.25 + frame = CGRect(x: 0, y: screenBounds.height, width: screenBounds.width, height: 0) + } + } + + public func animate(alongsideTransition transition: @escaping () -> Void, completion: (() -> Void)? = nil) { + +// if let timing = UIView.AnimationCurve.RawValue(exactly: animationCurve.rawValue), +// let curve = UIView.AnimationCurve(rawValue: timing) { +// let animator = UIViewPropertyAnimator(duration: animationDuration, curve: curve) { +// transition() +// } +// animator.addCompletion { _ in +// completion?() +// } +// animator.isUserInteractionEnabled = true +// animator.startAnimation() +// } else { + var animationOptions: UIView.AnimationOptions = .init(rawValue: UInt(animationCurve.rawValue << 16)) + animationOptions.formUnion(.allowUserInteraction) + animationOptions.formUnion(.beginFromCurrentState) + UIView.animate(withDuration: animationDuration, delay: 0, + options: animationOptions, + animations: transition, + completion: { _ in + completion?() + }) +// } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/Info/IQTextFieldViewInfo.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/Info/IQTextFieldViewInfo.swift new file mode 100644 index 0000000..eb0eaf6 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/LIsteners/Info/IQTextFieldViewInfo.swift @@ -0,0 +1,57 @@ +// +// IQTextFieldViewInfo.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +public struct IQTextFieldViewInfo: Equatable { + + nonisolated public static func == (lhs: Self, rhs: Self) -> Bool { + return lhs.textFieldView == rhs.textFieldView && + lhs.name == rhs.name + } + + @MainActor + @objc public enum Name: Int { + case beginEditing + case endEditing + } + + public let name: Name + + public let textFieldView: UIView + + public init?(notification: Notification?, name: Name) { + guard let view: UIView = notification?.object as? UIView else { + return nil + } + + guard !view.iq.isAlertViewTextField() else { + return nil + } + + self.name = name + textFieldView = view + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/PrivacyInfo.xcprivacy b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..9021190 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>NSPrivacyAccessedAPITypes</key> + <array/> + <key>NSPrivacyTrackingDomains</key> + <array/> + <key>NSPrivacyCollectedDataTypes</key> + <array/> + <key>NSPrivacyTracking</key> + <false/> +</dict> +</plist> diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler+TextFieldDelegate.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler+TextFieldDelegate.swift new file mode 100644 index 0000000..8cc195f --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler+TextFieldDelegate.swift @@ -0,0 +1,154 @@ +// +// IQKeyboardReturnKeyHandler+TextFieldDelegate.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +// MARK: UITextFieldDelegate +@available(iOSApplicationExtension, unavailable) +extension IQKeyboardReturnKeyHandler: UITextFieldDelegate { + + @objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { + + if delegate == nil { + + if let unwrapDelegate: UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { + if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldBeginEditing(_:))) { + return unwrapDelegate.textFieldShouldBeginEditing?(textField) ?? false + } + } + } + + return true + } + + @objc public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { + + if delegate == nil { + + if let unwrapDelegate: UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { + if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldEndEditing(_:))) { + return unwrapDelegate.textFieldShouldEndEditing?(textField) ?? false + } + } + } + + return true + } + + @objc public func textFieldDidBeginEditing(_ textField: UITextField) { + updateReturnKeyTypeOnTextField(textField) + + var aDelegate: UITextFieldDelegate? = delegate + + if aDelegate == nil { + + if let model: IQTextFieldViewInfoModel = textFieldViewCachedInfo(textField) { + aDelegate = model.textFieldDelegate + } + } + + aDelegate?.textFieldDidBeginEditing?(textField) + } + + @objc public func textFieldDidEndEditing(_ textField: UITextField) { + + var aDelegate: UITextFieldDelegate? = delegate + + if aDelegate == nil { + + if let model: IQTextFieldViewInfoModel = textFieldViewCachedInfo(textField) { + aDelegate = model.textFieldDelegate + } + } + + aDelegate?.textFieldDidEndEditing?(textField) + } + + @objc public func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) { + + var aDelegate: UITextFieldDelegate? = delegate + + if aDelegate == nil { + + if let model: IQTextFieldViewInfoModel = textFieldViewCachedInfo(textField) { + aDelegate = model.textFieldDelegate + } + } + + aDelegate?.textFieldDidEndEditing?(textField, reason: reason) + } + + @objc public func textField(_ textField: UITextField, + shouldChangeCharactersIn range: NSRange, + replacementString string: String) -> Bool { + + if delegate == nil { + + if let unwrapDelegate: UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { + let selector: Selector = #selector(UITextFieldDelegate.textField(_:shouldChangeCharactersIn: + replacementString:)) + if unwrapDelegate.responds(to: selector) { + return unwrapDelegate.textField?(textField, + shouldChangeCharactersIn: range, + replacementString: string) ?? false + } + } + } + return true + } + + @objc public func textFieldShouldClear(_ textField: UITextField) -> Bool { + + if delegate == nil { + + if let unwrapDelegate: UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { + if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldClear(_:))) { + return unwrapDelegate.textFieldShouldClear?(textField) ?? false + } + } + } + + return true + } + + @objc public func textFieldShouldReturn(_ textField: UITextField) -> Bool { + + var isReturn: Bool = true + + if delegate == nil { + + if let unwrapDelegate: UITextFieldDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { + if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldReturn(_:))) { + isReturn = unwrapDelegate.textFieldShouldReturn?(textField) ?? false + } + } + } + + if isReturn { + goToNextResponderOrResign(textField) + return true + } else { + return goToNextResponderOrResign(textField) + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler+TextViewDelegate.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler+TextViewDelegate.swift new file mode 100644 index 0000000..6519cc3 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler+TextViewDelegate.swift @@ -0,0 +1,347 @@ +// +// IQKeyboardReturnKeyHandler+TextViewDelegate.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +// MARK: UITextViewDelegate +@available(iOSApplicationExtension, unavailable) +extension IQKeyboardReturnKeyHandler: UITextViewDelegate { + + @objc public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool { + + if delegate == nil { + + if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate { + if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textViewShouldBeginEditing(_:))) { + return unwrapDelegate.textViewShouldBeginEditing?(textView) ?? false + } + } + } + + return true + } + + @objc public func textViewShouldEndEditing(_ textView: UITextView) -> Bool { + + if delegate == nil { + + if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate { + if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textViewShouldEndEditing(_:))) { + return unwrapDelegate.textViewShouldEndEditing?(textView) ?? false + } + } + } + + return true + } + + @objc public func textViewDidBeginEditing(_ textView: UITextView) { + updateReturnKeyTypeOnTextField(textView) + + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model: IQTextFieldViewInfoModel = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textViewDidBeginEditing?(textView) + } + + @objc public func textViewDidEndEditing(_ textView: UITextView) { + + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model: IQTextFieldViewInfoModel = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textViewDidEndEditing?(textView) + } + + @objc public func textView(_ textView: UITextView, + shouldChangeTextIn range: NSRange, + replacementText text: String) -> Bool { + + var isReturn = true + + if delegate == nil { + + if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate { + let selector: Selector = #selector(UITextViewDelegate.textView(_:shouldChangeTextIn:replacementText:)) + if unwrapDelegate.responds(to: selector) { + isReturn = (unwrapDelegate.textView?(textView, + shouldChangeTextIn: range, + replacementText: text)) ?? false + } + } + } + + if isReturn, text == "\n" { + isReturn = goToNextResponderOrResign(textView) + } + + return isReturn + } + + @objc public func textViewDidChange(_ textView: UITextView) { + + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model: IQTextFieldViewInfoModel = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textViewDidChange?(textView) + } + + @objc public func textViewDidChangeSelection(_ textView: UITextView) { + + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model: IQTextFieldViewInfoModel = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textViewDidChangeSelection?(textView) + } + + @objc public func textView(_ aTextView: UITextView, + shouldInteractWith URL: URL, + in characterRange: NSRange, + interaction: UITextItemInteraction) -> Bool { + + if delegate == nil { + + if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { + let selector: Selector = #selector(textView as + (UITextView, URL, NSRange, UITextItemInteraction) -> Bool) + if unwrapDelegate.responds(to: selector) { + return unwrapDelegate.textView?(aTextView, + shouldInteractWith: URL, + in: characterRange, + interaction: interaction) ?? false + } + } + } + + return true + } + + @objc public func textView(_ aTextView: UITextView, + shouldInteractWith textAttachment: NSTextAttachment, + in characterRange: NSRange, + interaction: UITextItemInteraction) -> Bool { + + if delegate == nil { + + if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { + let selector: Selector = #selector(textView as + (UITextView, NSTextAttachment, NSRange, UITextItemInteraction) + -> Bool) + if unwrapDelegate.responds(to: selector) { + return unwrapDelegate.textView?(aTextView, + shouldInteractWith: textAttachment, + in: characterRange, + interaction: interaction) ?? false + } + } + } + + return true + } + + @available(iOS, deprecated: 10.0) + @objc public func textView(_ aTextView: UITextView, + shouldInteractWith URL: URL, + in characterRange: NSRange) -> Bool { + + if delegate == nil { + + if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { + if unwrapDelegate.responds(to: #selector(textView as (UITextView, URL, NSRange) -> Bool)) { + return unwrapDelegate.textView?(aTextView, + shouldInteractWith: URL, + in: characterRange) ?? false + } + } + } + + return true + } + + @available(iOS, deprecated: 10.0) + @objc public func textView(_ aTextView: UITextView, + shouldInteractWith textAttachment: NSTextAttachment, + in characterRange: NSRange) -> Bool { + + if delegate == nil { + + if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { + if unwrapDelegate.responds(to: #selector(textView as (UITextView, NSTextAttachment, NSRange) -> Bool)) { + return unwrapDelegate.textView?(aTextView, + shouldInteractWith: textAttachment, + in: characterRange) ?? false + } + } + } + + return true + } +} + +#if swift(>=5.7) +@available(iOS 16.0, *) +@available(iOSApplicationExtension, unavailable) +extension IQKeyboardReturnKeyHandler { + public func textView(_ aTextView: UITextView, + editMenuForTextIn range: NSRange, + suggestedActions: [UIMenuElement]) -> UIMenu? { + if delegate == nil { + + if let unwrapDelegate: UITextViewDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { + + let selector: Selector = #selector(textView as + (UITextView, NSRange, [UIMenuElement]) -> UIMenu?) + if unwrapDelegate.responds(to: selector) { + return unwrapDelegate.textView?(aTextView, + editMenuForTextIn: range, + suggestedActions: suggestedActions) + } + } + } + + return nil + } + + public func textView(_ aTextView: UITextView, willPresentEditMenuWith animator: UIEditMenuInteractionAnimating) { + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model: IQTextFieldViewInfoModel = textFieldViewCachedInfo(aTextView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textView?(aTextView, willPresentEditMenuWith: animator) + } + + public func textView(_ aTextView: UITextView, willDismissEditMenuWith animator: UIEditMenuInteractionAnimating) { + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model: IQTextFieldViewInfoModel = textFieldViewCachedInfo(aTextView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textView?(aTextView, willDismissEditMenuWith: animator) + } +} +#endif + +#if swift(>=5.9) +@available(iOS 17.0, *) +@available(iOSApplicationExtension, unavailable) +extension IQKeyboardReturnKeyHandler { + + public func textView(_ aTextView: UITextView, + primaryActionFor textItem: UITextItem, + defaultAction: UIAction) -> UIAction? { + if delegate == nil { + + if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { + if unwrapDelegate.responds(to: #selector(textView as (UITextView, UITextItem, UIAction) -> UIAction?)) { + return unwrapDelegate.textView?(aTextView, + primaryActionFor: textItem, + defaultAction: defaultAction) + } + } + } + + return nil + } + + public func textView(_ aTextView: UITextView, + menuConfigurationFor textItem: UITextItem, + defaultMenu: UIMenu) -> UITextItem.MenuConfiguration? { + if delegate == nil { + + if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { + let selector: Selector = #selector(textView as (UITextView, UITextItem, UIMenu) + -> UITextItem.MenuConfiguration?) + if unwrapDelegate.responds(to: selector) { + return unwrapDelegate.textView?(aTextView, + menuConfigurationFor: textItem, + defaultMenu: defaultMenu) + } + } + } + + return nil + } + + public func textView(_ textView: UITextView, + textItemMenuWillDisplayFor textItem: UITextItem, + animator: UIContextMenuInteractionAnimating) { + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textView?(textView, textItemMenuWillDisplayFor: textItem, animator: animator) + } + + public func textView(_ textView: UITextView, + textItemMenuWillEndFor textItem: UITextItem, + animator: UIContextMenuInteractionAnimating) { + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textView?(textView, textItemMenuWillEndFor: textItem, animator: animator) + } +} +#endif diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler.swift new file mode 100644 index 0000000..f1a4efe --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler.swift @@ -0,0 +1,261 @@ +// +// IQKeyboardReturnKeyHandler.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +/** +Manages the return key to work like next/done in a view hierarchy. +*/ +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc public final class IQKeyboardReturnKeyHandler: NSObject { + + // MARK: Settings + + /** + Delegate of textField/textView. + */ + @objc public weak var delegate: (UITextFieldDelegate & UITextViewDelegate)? + + /** + Set the last textfield return key type. Default is UIReturnKeyDefault. + */ + @objc public var lastTextFieldReturnKeyType: UIReturnKeyType = UIReturnKeyType.default { + + didSet { + for model in textFieldInfoCache { + if let view: UIView = model.textFieldView { + updateReturnKeyTypeOnTextField(view) + } + } + } + } + + // MARK: Initialization/De-initialization + + @objc public override init() { + super.init() + } + + /** + Add all the textFields available in UIViewController's view. + */ + @objc public init(controller: UIViewController) { + super.init() + + addResponderFromView(controller.view) + } + + deinit { + +// for model in textFieldInfoCache { +// model.restore() +// } + + textFieldInfoCache.removeAll() + } + + // MARK: Private variables + private var textFieldInfoCache: [IQTextFieldViewInfoModel] = [] + + // MARK: Private Functions + internal func textFieldViewCachedInfo(_ textField: UIView) -> IQTextFieldViewInfoModel? { + + for model in textFieldInfoCache { + + if let view: UIView = model.textFieldView { + if view == textField { + return model + } + } + } + + return nil + } + + internal func updateReturnKeyTypeOnTextField(_ view: UIView) { + var superConsideredView: UIView? + + // If find any consider responderView in it's upper hierarchy then will get deepResponderView. (Bug ID: #347) + for allowedClasse in IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses { + + superConsideredView = view.iq.superviewOf(type: allowedClasse) + + if superConsideredView != nil { + break + } + } + + var textFields: [UIView] = [] + + // If there is a tableView in view's hierarchy, then fetching all it's subview that responds. + if let unwrappedTableView: UIView = superConsideredView { // (Enhancement ID: #22) + textFields = unwrappedTableView.iq.deepResponderViews() + } else { // Otherwise fetching all the siblings + + textFields = view.iq.responderSiblings() + + // Sorting textFields according to behavior + switch IQKeyboardManager.shared.toolbarConfiguration.manageBehavior { + // If needs to sort it by tag + case .byTag: textFields = textFields.sortedByTag() + // If needs to sort it by Position + case .byPosition: textFields = textFields.sortedByPosition() + default: break + } + } + + if let lastView: UIView = textFields.last { + + if let textField: UITextField = view as? UITextField { + + // If it's the last textField in responder view, else next + textField.returnKeyType = (view == lastView) ? lastTextFieldReturnKeyType: UIReturnKeyType.next + } else if let textView: UITextView = view as? UITextView { + + // If it's the last textField in responder view, else next + textView.returnKeyType = (view == lastView) ? lastTextFieldReturnKeyType: UIReturnKeyType.next + } + } + } + + // MARK: Registering/Unregistering textFieldView + + /** + Should pass UITextField/UITextView instance. Assign textFieldView delegate to self, change it's returnKeyType. + + @param view UITextField/UITextView object to register. + */ + @objc public func addTextFieldView(_ view: UIView) { + + if let textField: UITextField = view as? UITextField { + let model = IQTextFieldViewInfoModel(textField: textField) + textFieldInfoCache.append(model) + textField.delegate = self + + } else if let textView: UITextView = view as? UITextView { + let model = IQTextFieldViewInfoModel(textView: textView) + textFieldInfoCache.append(model) + textView.delegate = self + } + } + + /** + Should pass UITextField/UITextView instance. Restore it's textFieldView delegate and it's returnKeyType. + + @param view UITextField/UITextView object to unregister. + */ + @objc public func removeTextFieldView(_ view: UIView) { + + if let model: IQTextFieldViewInfoModel = textFieldViewCachedInfo(view) { + model.restore() + + if let index: Int = textFieldInfoCache.firstIndex(where: { $0.textFieldView == view}) { + textFieldInfoCache.remove(at: index) + } + } + } + + /** + Add all the UITextField/UITextView responderView's. + + @param view UIView object to register all it's responder subviews. + */ + @objc public func addResponderFromView(_ view: UIView) { + + let textFields: [UIView] = view.iq.deepResponderViews() + + for textField in textFields { + + addTextFieldView(textField) + } + } + + /** + Remove all the UITextField/UITextView responderView's. + + @param view UIView object to unregister all it's responder subviews. + */ + @objc public func removeResponderFromView(_ view: UIView) { + + let textFields: [UIView] = view.iq.deepResponderViews() + + for textField in textFields { + + removeTextFieldView(textField) + } + } + + @discardableResult + internal func goToNextResponderOrResign(_ view: UIView) -> Bool { + + var superConsideredView: UIView? + + // If find any consider responderView in it's upper hierarchy then will get deepResponderView. (Bug ID: #347) + for allowedClass in IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses { + + superConsideredView = view.iq.superviewOf(type: allowedClass) + + if superConsideredView != nil { + break + } + } + + var textFields: [UIView] = [] + + // If there is a tableView in view's hierarchy, then fetching all it's subview that responds. + if let unwrappedTableView: UIView = superConsideredView { // (Enhancement ID: #22) + textFields = unwrappedTableView.iq.deepResponderViews() + } else { // Otherwise fetching all the siblings + + textFields = view.iq.responderSiblings() + + // Sorting textFields according to behavior + switch IQKeyboardManager.shared.toolbarConfiguration.manageBehavior { + // If needs to sort it by tag + case .byTag: textFields = textFields.sortedByTag() + // If needs to sort it by Position + case .byPosition: textFields = textFields.sortedByPosition() + default: + break + } + } + + // Getting index of current textField. + if let index: Int = textFields.firstIndex(of: view) { + // If it is not last textField. then it's next object becomeFirstResponder. + if index < (textFields.count - 1) { + + let nextTextField: UIView = textFields[index+1] + nextTextField.becomeFirstResponder() + return false + } else { + + view.resignFirstResponder() + return true + } + } else { + return true + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQTextFieldViewInfoModel.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQTextFieldViewInfoModel.swift new file mode 100644 index 0000000..562c99c --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/ReturnKeyHandler/IQTextFieldViewInfoModel.swift @@ -0,0 +1,56 @@ +// +// IQTextFieldViewInfoModel.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +internal final class IQTextFieldViewInfoModel: NSObject { + + weak var textFieldDelegate: UITextFieldDelegate? + weak var textViewDelegate: UITextViewDelegate? + weak var textFieldView: UIView? + let originalReturnKeyType: UIReturnKeyType + + init(textField: UITextField) { + self.textFieldView = textField + self.textFieldDelegate = textField.delegate + self.originalReturnKeyType = textField.returnKeyType + } + + init(textView: UITextView) { + self.textFieldView = textView + self.textViewDelegate = textView.delegate + self.originalReturnKeyType = textView.returnKeyType + } + + func restore() { + if let textField = textFieldView as? UITextField { + textField.returnKeyType = originalReturnKeyType + textField.delegate = textFieldDelegate + } else if let textView = textFieldView as? UITextView { + textView.returnKeyType = originalReturnKeyType + textView.delegate = textViewDelegate + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQNSArray+Sort.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQNSArray+Sort.swift new file mode 100644 index 0000000..24c542a --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQNSArray+Sort.swift @@ -0,0 +1,57 @@ +// +// IQNSArray+Sort.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +/** +UIView.subviews sorting category. +*/ +@available(iOSApplicationExtension, unavailable) +@MainActor +internal extension Array where Element: UIView { + + /** + Returns the array by sorting the UIView's by their tag property. + */ + func sortedByTag() -> [Element] { + + return sorted(by: { (obj1: Element, obj2: Element) -> Bool in + + return (obj1.tag < obj2.tag) + }) + } + + /** + Returns the array by sorting the UIView's by their tag property. + */ + func sortedByPosition() -> [Element] { + + return sorted(by: { (obj1: Element, obj2: Element) -> Bool in + if obj1.frame.minY != obj2.frame.minY { + return obj1.frame.minY < obj2.frame.minY + } else { + return obj1.frame.minX < obj2.frame.minX + } + }) + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUICollectionView+Additions.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUICollectionView+Additions.swift new file mode 100644 index 0000000..7da92ea --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUICollectionView+Additions.swift @@ -0,0 +1,48 @@ +// +// IQUICollectionView+Additions.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +internal extension UICollectionView { + + func previousIndexPath(of indexPath: IndexPath) -> IndexPath? { + var previousRow: Int = indexPath.row - 1 + var previousSection: Int = indexPath.section + + // Fixing indexPath + if previousRow < 0 { + previousSection -= 1 + if previousSection >= 0 { + previousRow = self.numberOfItems(inSection: previousSection) - 1 + } + } + + if previousRow >= 0, previousSection >= 0 { + return IndexPath(item: previousRow, section: previousSection) + } else { + return nil + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUIScrollView+Additions.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUIScrollView+Additions.swift new file mode 100644 index 0000000..8b8753f --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUIScrollView+Additions.swift @@ -0,0 +1,116 @@ +// +// IQUIScrollView+Additions.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +private struct AssociatedKeys { + static var ignoreScrollingAdjustment: Int = 0 + static var ignoreContentInsetAdjustment: Int = 0 + static var restoreContentOffset: Int = 0 +} + +// swiftlint:disable identifier_name +// swiftlint:disable unused_setter_value +@available(iOSApplicationExtension, unavailable) +extension UIScrollView: IQKeyboardManagerCompatible { + + // This property is explicitly written otherwise we were having + // compilation error when archiving + public var iq: IQKeyboardManagerWrapper<UIView> { + get { IQKeyboardManagerWrapper(self) } + set {} + } +} +// swiftlint:enable unused_setter_value +// swiftlint:enable identifier_name + +@available(iOSApplicationExtension, unavailable) +@MainActor +public extension IQKeyboardManagerWrapper where Base: UIScrollView { + + /** + If YES, then scrollview will ignore scrolling (simply not scroll it) for adjusting textfield position. + Default is NO. + */ + var ignoreScrollingAdjustment: Bool { + get { + return objc_getAssociatedObject(base, &AssociatedKeys.ignoreScrollingAdjustment) as? Bool ?? false + } + set(newValue) { + objc_setAssociatedObject(base, &AssociatedKeys.ignoreScrollingAdjustment, + newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** + If YES, then scrollview will ignore content inset adjustment (simply not updating it) when keyboard is shown. + Default is NO. + */ + var ignoreContentInsetAdjustment: Bool { + get { + return objc_getAssociatedObject(base, &AssociatedKeys.ignoreContentInsetAdjustment) as? Bool ?? false + } + set(newValue) { + objc_setAssociatedObject(base, &AssociatedKeys.ignoreContentInsetAdjustment, + newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** + To set customized distance from keyboard for textField/textView. Can't be less than zero + */ + var restoreContentOffset: Bool { + get { + return objc_getAssociatedObject(base, &AssociatedKeys.restoreContentOffset) as? Bool ?? false + } + set(newValue) { + objc_setAssociatedObject(base, &AssociatedKeys.restoreContentOffset, + newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } +} + +// swiftlint:disable unused_setter_value +@available(iOSApplicationExtension, unavailable) +@objc public extension UIScrollView { + @available(*, unavailable, renamed: "iq.ignoreScrollingAdjustment") + var shouldIgnoreScrollingAdjustment: Bool { + get { false } + set { } + } + + @available(*, unavailable, renamed: "iq.ignoreContentInsetAdjustment") + var shouldIgnoreContentInsetAdjustment: Bool { + get { false } + set { } + } + + @available(*, unavailable, renamed: "iq.restoreContentOffset") + var shouldRestoreScrollViewContentOffset: Bool { + get { false } + set { } + } +} +// swiftlint:enable unused_setter_value diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUITableView+Additions.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUITableView+Additions.swift new file mode 100644 index 0000000..022a94d --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUITableView+Additions.swift @@ -0,0 +1,48 @@ +// +// IQUITableView+Additions.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +internal extension UITableView { + + func previousIndexPath(of indexPath: IndexPath) -> IndexPath? { + var previousRow: Int = indexPath.row - 1 + var previousSection: Int = indexPath.section + + // Fixing indexPath + if previousRow < 0 { + previousSection -= 1 + if previousSection >= 0 { + previousRow = self.numberOfRows(inSection: previousSection) - 1 + } + } + + if previousRow >= 0, previousSection >= 0 { + return IndexPath(row: previousRow, section: previousSection) + } else { + return nil + } + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUITextFieldView+Additions.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUITextFieldView+Additions.swift new file mode 100644 index 0000000..d108f96 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUITextFieldView+Additions.swift @@ -0,0 +1,137 @@ +// +// IQUITextFieldView+Additions.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +private struct AssociatedKeys { + static var distanceFromKeyboard: Int = 0 + static var ignoreSwitchingByNextPrevious: Int = 0 + static var enableMode: Int = 0 + static var resignOnTouchOutsideMode: Int = 0 +} + +@available(iOSApplicationExtension, unavailable) +extension UIView: IQKeyboardManagerCompatible { + + public static let defaultKeyboardDistance: CGFloat = CGFloat.greatestFiniteMagnitude +} + +@available(iOSApplicationExtension, unavailable) +@available(*, unavailable, renamed: "UIView.defaultKeyboardDistance") +public let kIQUseDefaultKeyboardDistance = CGFloat.greatestFiniteMagnitude + +/** +UIView category for managing UITextField/UITextView +*/ +@available(iOSApplicationExtension, unavailable) +@MainActor +public extension IQKeyboardManagerWrapper where Base: UIView { + + /** + To set customized distance from keyboard for textField/textView. Can't be less than zero + */ + var distanceFromKeyboard: CGFloat { + get { + if let value = objc_getAssociatedObject(base, &AssociatedKeys.distanceFromKeyboard) as? CGFloat { + return value + } else { + return UIView.defaultKeyboardDistance + } + } + set(newValue) { + objc_setAssociatedObject(base, &AssociatedKeys.distanceFromKeyboard, + newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** + If ignoreSwitchingByNextPrevious is true then library will ignore this textField/textView + while moving to other textField/textView using keyboard toolbar next previous buttons. + Default is false + */ + var ignoreSwitchingByNextPrevious: Bool { + get { + return objc_getAssociatedObject(base, &AssociatedKeys.ignoreSwitchingByNextPrevious) as? Bool ?? false + } + set(newValue) { + objc_setAssociatedObject(base, &AssociatedKeys.ignoreSwitchingByNextPrevious, + newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** + Override Enable/disable managing distance between keyboard and textField behavior for this particular textField. + */ + var enableMode: IQEnableMode { + get { + return objc_getAssociatedObject(base, &AssociatedKeys.enableMode) as? IQEnableMode ?? .default + } + set(newValue) { + objc_setAssociatedObject(base, &AssociatedKeys.enableMode, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** + Override resigns Keyboard on touching outside of UITextField/View behavior for this particular textField. + */ + var resignOnTouchOutsideMode: IQEnableMode { + get { + return objc_getAssociatedObject(base, &AssociatedKeys.resignOnTouchOutsideMode) as? IQEnableMode ?? .default + } + set(newValue) { + objc_setAssociatedObject(base, &AssociatedKeys.resignOnTouchOutsideMode, + newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } +} + +// swiftlint:disable unused_setter_value +@available(iOSApplicationExtension, unavailable) +@objc public extension UIView { + @available(*, unavailable, renamed: "iq.distanceFromKeyboard") + var keyboardDistanceFromTextField: CGFloat { + get { 0 } + set { } + } + + @available(*, unavailable, renamed: "iq.ignoreSwitchingByNextPrevious") + var ignoreSwitchingByNextPrevious: Bool { + get { false } + set { } + } + + @available(*, unavailable, renamed: "iq.enableMode") + var enableMode: IQEnableMode { + get { .default } + set { } + } + + @available(*, unavailable, renamed: "iq.resignOnTouchOutsideMode") + var shouldResignOnTouchOutsideMode: IQEnableMode { + get { .default } + set { } + } +} +// swiftlint:enable unused_setter_value diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUIView+Hierarchy.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUIView+Hierarchy.swift new file mode 100644 index 0000000..907f51f --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUIView+Hierarchy.swift @@ -0,0 +1,354 @@ +// +// IQUIView+Hierarchy.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +/** +UIView hierarchy category. +*/ + +@available(iOSApplicationExtension, unavailable) +@MainActor +public extension IQKeyboardManagerWrapper where Base: UIView { + + // MARK: viewControllers + + /** + Returns the UIViewController object that manages the receiver. + */ + func viewContainingController() -> UIViewController? { + + var nextResponder: UIResponder? = base + + repeat { + nextResponder = nextResponder?.next + + if let viewController: UIViewController = nextResponder as? UIViewController { + return viewController + } + + } while nextResponder != nil + + return nil + } + + /** + Returns the topMost UIViewController object in hierarchy. + */ + func topMostController() -> UIViewController? { + + var controllersHierarchy: [UIViewController] = [] + + if var topController: UIViewController = base.window?.rootViewController { + controllersHierarchy.append(topController) + + while let presented: UIViewController = topController.presentedViewController { + + topController = presented + + controllersHierarchy.append(presented) + } + + var matchController: UIResponder? = viewContainingController() + + while let mController: UIViewController = matchController as? UIViewController, + !controllersHierarchy.contains(mController) { + + repeat { + matchController = matchController?.next + + } while matchController != nil && matchController is UIViewController == false + } + + return matchController as? UIViewController + + } else { + return viewContainingController() + } + } + + /** + Returns the UIViewController object that is actually the parent of this object. + Most of the time it's the viewController object which actually contains it, + but result may be different if it's viewController is added as childViewController of another viewController. + */ + func parentContainerViewController() -> UIViewController? { + + var matchController: UIViewController? = viewContainingController() + var parentContainerViewController: UIViewController? + + if var navController: UINavigationController = matchController?.navigationController { + + while let parentNav: UINavigationController = navController.navigationController { + navController = parentNav + } + + var parentController: UIViewController = navController + + while let parent: UIViewController = parentController.parent, + !(parent is UINavigationController) && + !(parent is UITabBarController) && + !(parent is UISplitViewController) { + + parentController = parent + } + + if navController == parentController { + parentContainerViewController = navController.topViewController + } else { + parentContainerViewController = parentController + } + } else if let tabController: UITabBarController = matchController?.tabBarController { + let selectedController = tabController.selectedViewController + if let navController: UINavigationController = selectedController as? UINavigationController { + parentContainerViewController = navController.topViewController + } else { + parentContainerViewController = tabController.selectedViewController + } + } else { + while let parent: UIViewController = matchController?.parent, + !(parent is UINavigationController) && + !(parent is UITabBarController) && + !(parent is UISplitViewController) { + + matchController = parent + } + + parentContainerViewController = matchController + } + + if let controller: UIViewController = parentContainerViewController?.iq_parentContainerViewController() { + return controller + } else { + return parentContainerViewController + } + } + + // MARK: Superviews/Subviews/Siblings + + /** + Returns the superView of provided class type. + + + @param classType class type of the object which is to be search in above hierarchy and return + + @param belowView view object in upper hierarchy where method should stop searching and return nil +*/ + func superviewOf<T: UIView>(type classType: T.Type, belowView: UIView? = nil) -> T? { + + var superView: UIView? = base.superview + + while let unwrappedSuperView: UIView = superView { + + if unwrappedSuperView.isKind(of: classType) { + + // If it's UIScrollView, then validating for special cases + if unwrappedSuperView is UIScrollView { + + let classNameString: String = "\(type(of: unwrappedSuperView.self))" + + // If it's not UITableViewWrapperView class, + // this is internal class which is actually manage in UITableview. + // The speciality of this class is that it's superview is UITableView. + // If it's not UITableViewCellScrollView class, + // this is internal class which is actually manage in UITableviewCell. + // The speciality of this class is that it's superview is UITableViewCell. + // If it's not _UIQueuingScrollView class, + // actually we validate for _ prefix which usually used by Apple internal classes + if !(unwrappedSuperView.superview is UITableView), + !(unwrappedSuperView.superview is UITableViewCell), + !classNameString.hasPrefix("_") { + return superView as? T + } + } else { + return superView as? T + } + } else if unwrappedSuperView == belowView { + return nil + } + + superView = unwrappedSuperView.superview + } + + return nil + } +} + +@available(iOSApplicationExtension, unavailable) +@MainActor +internal extension IQKeyboardManagerWrapper where Base: UIView { + + /** + Returns all siblings of the receiver which canBecomeFirstResponder. + */ + func responderSiblings() -> [UIView] { + + // Array of (UITextField/UITextView's). + var tempTextFields: [UIView] = [] + + // Getting all siblings + if let siblings: [UIView] = base.superview?.subviews { + for textField in siblings { + if textField == base || !textField.iq.ignoreSwitchingByNextPrevious, + textField.iq.canBecomeFirstResponder() { + tempTextFields.append(textField) + } + } + } + + return tempTextFields + } + + /** + Returns all deep subViews of the receiver which canBecomeFirstResponder. + */ + func deepResponderViews() -> [UIView] { + + // Array of (UITextField/UITextView's). + var textfields: [UIView] = [] + + for textField in base.subviews { + + if textField == base || !textField.iq.ignoreSwitchingByNextPrevious, + textField.iq.canBecomeFirstResponder() { + textfields.append(textField) + } + // Sometimes there are hidden or disabled views and textField inside them still recorded, + // so we added some more validations here (Bug ID: #458) + // Uncommented else (Bug ID: #625) + else if textField.subviews.count != 0, base.isUserInteractionEnabled, !base.isHidden, base.alpha != 0.0 { + for deepView in textField.iq.deepResponderViews() { + textfields.append(deepView) + } + } + } + + // subviews are returning in opposite order. Sorting according the frames 'y'. + return textfields.sorted(by: { (view1: UIView, view2: UIView) -> Bool in + + let frame1: CGRect = view1.convert(view1.bounds, to: base) + let frame2: CGRect = view2.convert(view2.bounds, to: base) + + if frame1.minY != frame2.minY { + return frame1.minY < frame2.minY + } else { + return frame1.minX < frame2.minX + } + }) + } + + private func canBecomeFirstResponder() -> Bool { + + var canBecomeFirstResponder: Bool = false + + if base.conforms(to: UITextInput.self) { + // Setting toolbar to keyboard. + if let textView: UITextView = base as? UITextView { + canBecomeFirstResponder = textView.isEditable + } else if let textField: UITextField = base as? UITextField { + canBecomeFirstResponder = textField.isEnabled + } + } + + if canBecomeFirstResponder { + canBecomeFirstResponder = base.isUserInteractionEnabled && + !base.isHidden && + base.alpha != 0.0 && + !isAlertViewTextField() && + textFieldSearchBar() == nil + } + + return canBecomeFirstResponder + } + + // MARK: Special TextFields + + /** + Returns searchBar if receiver object is UISearchBarTextField, otherwise return nil. + */ + func textFieldSearchBar() -> UISearchBar? { + + var responder: UIResponder? = base.next + + while let bar: UIResponder = responder { + + if let searchBar: UISearchBar = bar as? UISearchBar { + return searchBar + } else if bar is UIViewController { + break + } + + responder = bar.next + } + + return nil + } + + /** + Returns YES if the receiver object is UIAlertSheetTextField, otherwise return NO. + */ + func isAlertViewTextField() -> Bool { + + var alertViewController: UIResponder? = viewContainingController() + + var isAlertViewTextField: Bool = false + + while let controller: UIResponder = alertViewController, !isAlertViewTextField { + + if controller is UIAlertController { + isAlertViewTextField = true + break + } + + alertViewController = controller.next + } + + return isAlertViewTextField + } + + func depth() -> Int { + var depth: Int = 0 + + if let superView: UIView = base.superview { + depth = superView.iq.depth()+1 + } + + return depth + } +} + +@available(iOSApplicationExtension, unavailable) +@objc public extension UIView { + + @available(*, unavailable, renamed: "iq.viewContainingController()") + func viewContainingController() -> UIViewController? { nil } + + @available(*, unavailable, renamed: "iq.topMostController()") + func topMostController() -> UIViewController? { nil } + + @available(*, unavailable, renamed: "iq.parentContainerViewController()") + func parentContainerViewController() -> UIViewController? { nil } + + @available(*, unavailable, renamed: "iq.superviewOf(type:belowView:)") + func superviewOfClassType(_ classType: UIView.Type, belowView: UIView? = nil) -> UIView? { nil } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUIViewController+Additions.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUIViewController+Additions.swift new file mode 100644 index 0000000..7bd0792 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/IQUIViewController+Additions.swift @@ -0,0 +1,48 @@ +// +// IQUIViewController+Additions.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +@available(iOSApplicationExtension, unavailable) +@MainActor +@objc extension UIViewController { + + /** + 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. + */ + open func iq_parentContainerViewController() -> UIViewController? { + return self + } +} + +@available(iOSApplicationExtension, unavailable) +@objc extension UIViewController { + @available(*, unavailable, renamed: "iq_parentContainerViewController()") + open func parentIQContainerViewController() -> UIViewController? { + return self + } +} diff --git a/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/UIImage+NextPrevious.swift b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/UIImage+NextPrevious.swift new file mode 100644 index 0000000..fe1d1a1 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/UIKitExtensions/UIImage+NextPrevious.swift @@ -0,0 +1,60 @@ +// +// UIImage+NextPrevious.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-24 Iftekhar Qurashi. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +/** + UIImage category methods to get next/prev images + */ +@available(iOSApplicationExtension, unavailable) +@objc public extension UIImage { + + static let keyboardPreviousImage: UIImage = { + // swiftlint:disable line_length + let base64Data: String = "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" + // swiftlint:enable line_length + + // Support for RTL languages like Arabic, Persia etc... (Bug ID: #448) + if let data: Data = Data(base64Encoded: base64Data, options: .ignoreUnknownCharacters), + let image = UIImage(data: data, scale: 3)?.imageFlippedForRightToLeftLayoutDirection() { + return image + } + + return UIImage() + }() + + static let keyboardNextImage: UIImage = { + + // swiftlint:disable line_length + let base64Data: String = "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" + // swiftlint:enable line_length + + // Support for RTL languages like Arabic, Persia etc... (Bug ID: #448) + if let data: Data = Data(base64Encoded: base64Data, options: .ignoreUnknownCharacters), + let image = UIImage(data: data, scale: 3)?.imageFlippedForRightToLeftLayoutDirection() { + return image + } + + return UIImage() + }() +} diff --git a/Pods/IQKeyboardManagerSwift/LICENSE.md b/Pods/IQKeyboardManagerSwift/LICENSE.md new file mode 100644 index 0000000..0c652ed --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013-2023 Iftekhar Qurashi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Pods/IQKeyboardManagerSwift/README.md b/Pods/IQKeyboardManagerSwift/README.md new file mode 100644 index 0000000..01f6f96 --- /dev/null +++ b/Pods/IQKeyboardManagerSwift/README.md @@ -0,0 +1,220 @@ +<p align="center"> + <img src="https://raw.githubusercontent.com/hackiftekhar/IQKeyboardManager/master/Demo/Resources/icon.png" alt="Icon"/> +</p> +<H1 align="center">IQKeyboardManager</H1> +<p align="center"> + <img src="https://img.shields.io/github/license/hackiftekhar/IQKeyboardManager.svg" + alt="GitHub license"/> + + +[](https://travis-ci.org/hackiftekhar/IQKeyboardManager) + + +While developing iOS apps, we often run into issues where the iPhone keyboard slides up and covers the `UITextField/UITextView`. `IQKeyboardManager` allows you to prevent this issue of keyboard sliding up and covering `UITextField/UITextView` without needing you to write any code or make any additional setup. To use `IQKeyboardManager` you simply need to add source files to your project. + + +#### Key Features + +1) `**CODELESS**, Zero Lines of Code` + +2) `Works Automatically` + +3) `No More UIScrollView` + +4) `No More Subclasses` + +5) `No More Manual Work` + +6) `No More #imports` + +`IQKeyboardManager` works on all orientations, and with the toolbar. It also has nice optional features allowing you to customize the distance from the text field, behaviour of previous, next and done buttons in the keyboard toolbar, play sound when the user navigates through the form and more. + + +## Screenshot +[](http://youtu.be/6nhLw6hju2A) +[](http://youtu.be/6nhLw6hju2A) +[](http://youtu.be/6nhLw6hju2A) +[](http://youtu.be/6nhLw6hju2A) +[](http://youtu.be/6nhLw6hju2A) + +## GIF animation +[](http://youtu.be/6nhLw6hju2A) + +## Video + +<a href="http://youtu.be/WAYc2Qj-OQg" target="_blank"><img src="http://img.youtube.com/vi/WAYc2Qj-OQg/0.jpg" +alt="IQKeyboardManager Demo Video" width="480" height="360" border="10" /></a> + +## Tutorial video by @rebeloper ([#1135](https://github.com/hackiftekhar/IQKeyboardManager/issues/1135)) + +@rebeloper demonstrated two videos on how to implement **IQKeyboardManager** at it's core: + +<a href="https://www.youtube.com/playlist?list=PL_csAAO9PQ8aTL87XnueOXi3RpWE2m_8v" target="_blank"><img src="https://raw.githubusercontent.com/hackiftekhar/IQKeyboardManager/master/Screenshot/ThirdPartyYoutubeTutorial.jpg" +alt="Youtube Tutorial Playlist"/></a> + +https://www.youtube.com/playlist?list=PL_csAAO9PQ8aTL87XnueOXi3RpWE2m_8v + +## Warning + +- **If you're planning to build SDK/library/framework and want to handle UITextField/UITextView with IQKeyboardManager then you're totally going the wrong way.** I would never suggest to add **IQKeyboardManager** as **dependency/adding/shipping** with any third-party library. Instead of adding **IQKeyboardManager** you should implement your own solution to achieve same kind of results. **IQKeyboardManager** is totally designed for projects to help developers for their convenience, it's not designed for **adding/dependency/shipping** with any **third-party library**, because **doing this could block adoption by other developers for their projects as well (who are not using IQKeyboardManager and have implemented their custom solution to handle UITextField/UITextView in the project).** +- If **IQKeyboardManager** conflicts with other **third-party library**, then it's **developer responsibility** to **enable/disable IQKeyboardManager** when **presenting/dismissing** third-party library UI. Third-party libraries are not responsible to handle IQKeyboardManager. + +## Requirements +[]() + +| | Language | Minimum iOS Target | Minimum Xcode Version | +|------------------------|----------|--------------------|-----------------------| +| IQKeyboardManager | Obj-C | iOS 11.0 | Xcode 13 | +| IQKeyboardManagerSwift | Swift | iOS 13.0 | Xcode 13 | +| Demo Project | | | Xcode 15 | + +#### Swift versions support + +| Swift | Xcode | IQKeyboardManagerSwift | +|-------------------|-------|------------------------| +| 5.9, 5.8, 5.7, 5.6| 15 | >= 7.0.0 | +| 5.5, 5.4, 5.3, 5.2, 5.1, 5.0, 4.2| 11 | >= 6.5.7 | +| 5.1, 5.0, 4.2, 4.0, 3.2, 3.0| 11 | >= 6.5.0 | +| 5.0,4.2, 4.0, 3.2, 3.0| 10.2 | >= 6.2.1 | +| 4.2, 4.0, 3.2, 3.0| 10.0 | >= 6.0.4 | +| 4.0, 3.2, 3.0 | 9.0 | 5.0.0 | + +## 7.0.0 version notes +- In this major release, a lot of variables and functions have been moved here and there. We have mentioned most of the major things in the MIGRATION GUIDE. So please take a look to make changes in your project when upgrading to this version. +- The 7.0.0 version adopted the latest Swift Concurrency/Actor feature and only available iOS 13.0 and above. +- Internal keyboard management handling have been updated with a different and better approach than legacy versions. However when adopting 7.0.0, please verify if it is working as expected in your apps, if there are any serious problems with 7.0.0 please open an issue with all the details and switch back to legacy version temporarily. + +Installation +========================== + +#### Installation with CocoaPods + +[](http://cocoadocs.org/docsets/IQKeyboardManager) + +***IQKeyboardManager (Objective-C):*** IQKeyboardManager is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: ([#9](https://github.com/hackiftekhar/IQKeyboardManager/issues/9)) + +```ruby +pod 'IQKeyboardManager' #iOS13 and later +``` + +***IQKeyboardManager (Swift):*** IQKeyboardManagerSwift is available through [CocoaPods](http://cocoapods.org). To install +it, simply add the following line to your Podfile: ([#236](https://github.com/hackiftekhar/IQKeyboardManager/issues/236)) + +*Swift 5.9, 5.8, 5.7, 5.6, 5.5 (Xcode 15)* + +```ruby +pod 'IQKeyboardManagerSwift' +``` + +*Or you can choose the version you need based on Swift support table from [Requirements](README.md#requirements)* + +```ruby +pod 'IQKeyboardManagerSwift', '6.3.0' +``` + +In AppDelegate.swift, just import IQKeyboardManagerSwift framework and enable IQKeyboardManager. + +```swift +import IQKeyboardManagerSwift + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + IQKeyboardManager.shared.enable = true + + return true + } +} +``` + +#### Installation with Carthage + +[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. + +You can install Carthage with [Homebrew](http://brew.sh/) using the following command: + +```bash +$ brew update +$ brew install carthage +``` + +To integrate `IQKeyboardManger` or `IQKeyboardManagerSwift` into your Xcode project using Carthage, add the following line to your `Cartfile`: + +```ogdl +github "hackiftekhar/IQKeyboardManager" +``` + +Run `carthage` to build the frameworks and drag the appropriate framework (`IQKeyboardManager.framework` or `IQKeyboardManagerSwift.framework`) into your Xcode project based on your need. Make sure to add only one framework and not both. + + +#### Installation with Source Code + +[]() + + + +***IQKeyboardManager (Objective-C):*** Just ***drag and drop*** `IQKeyboardManager` directory from demo project to your project. That's it. + +***IQKeyboardManager (Swift):*** ***Drag and drop*** `IQKeyboardManagerSwift` directory from demo project to your project + +In AppDelegate.swift, just enable IQKeyboardManager. + +```swift +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + IQKeyboardManager.shared.enable = true + + return true + } +} +``` + +#### Installation with Swift Package Manager + +[Swift Package Manager(SPM)](https://swift.org/package-manager/) is Apple's dependency manager tool. It is now supported in Xcode 11. So it can be used in all appleOS types of projects. It can be used alongside other tools like CocoaPods and Carthage as well. + +To install IQKeyboardManagerSwift package via Xcode + + * Go to File -> Swift Packages -> Add Package Dependency... + * Then search for https://github.com/hackiftekhar/IQKeyboardManager.git + * And choose the version you want + +Migration Guide +========================== +- [IQKeyboardManager 6.0.0 Migration Guide](https://github.com/hackiftekhar/IQKeyboardManager/wiki/IQKeyboardManager-6.0.0-Migration-Guide) +- [IQKeyboardManager 7.0.0 Migration Guide](https://github.com/hackiftekhar/IQKeyboardManager/wiki/IQKeyboardManager-7.0.0-Migration-Guide) + +Other Links +========================== + +- [Known Issues](https://github.com/hackiftekhar/IQKeyboardManager/wiki/Known-Issues) +- [Manual Management Tweaks](https://github.com/hackiftekhar/IQKeyboardManager/wiki/Manual-Management) +- [Properties and functions usage](https://github.com/hackiftekhar/IQKeyboardManager/wiki/Properties-&-Functions) + +## Flow Diagram +[](https://raw.githubusercontent.com/hackiftekhar/IQKeyboardManager/master/Screenshot/IQKeyboardManagerFlowDiagram.jpg) + +If you would like to see detailed Flow diagram then check [Detailed Flow Diagram](https://raw.githubusercontent.com/hackiftekhar/IQKeyboardManager/v3.3.0/Screenshot/IQKeyboardManagerCFD.jpg). + + +LICENSE +--- +Distributed under the MIT License. + +Contributions +--- +Any contribution is more than welcome! You can contribute through pull requests and issues on GitHub. + +Author +--- +If you wish to contact me, email at: hack.iftekhar@gmail.com diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index 913eedd..e3f77d7 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -1,16 +1,20 @@ PODS: + - IQKeyboardManagerSwift (7.0.3) - LanguageManager-iOS (1.2.7) DEPENDENCIES: + - IQKeyboardManagerSwift - LanguageManager-iOS SPEC REPOS: trunk: + - IQKeyboardManagerSwift - LanguageManager-iOS SPEC CHECKSUMS: + IQKeyboardManagerSwift: f9c5dc36cba16ddd2e51fa7d51c34a2e083029b5 LanguageManager-iOS: 6b2dbb3793445827114708f0759b76e96932d7c8 -PODFILE CHECKSUM: b552b1df80271db8c0ce748b0da6dd348ea0f82d +PODFILE CHECKSUM: 144b9dcd597bb6f7ec4e403aff5675d2db4f19f1 COCOAPODS: 1.14.3 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index c535641..265cb63 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -7,73 +7,213 @@ objects = { /* Begin PBXBuildFile section */ - 0718CCD0E19136B8DB2A7D4C6585E3ED /* LanguageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76C3AD529D7D4EE4869591BF3965031B /* LanguageManager.swift */; }; - 10D1A87F45AFB52D2B34D9ABA1A86105 /* UIImageView+Direction.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD4005C2FC9E5447CF8F35CFDF18F517 /* UIImageView+Direction.swift */; }; - 3E21C9612D00C6B92D3FCE3589917729 /* UIView+Direction.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD718E6CB3EA4175288EFD1790ABE180 /* UIView+Direction.swift */; }; - 48A4D5E4D954CB4212E540A92570BBF0 /* UIView+Swizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1EB585FB79943D0D18D7F79322CD60 /* UIView+Swizzling.swift */; }; - 4A525A4C45A6519919550C49896FCE30 /* Pods-MiniScanner-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E8A070B594D65627DD64F5ABC65D271 /* Pods-MiniScanner-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6418A8A5D32E73D898AB155952180B0C /* LanguageManager-iOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D1BEBD5F5E11A9D5238E1D4F0C3DBB /* LanguageManager-iOS-dummy.m */; }; - 64484197CAEC8EED5DA42F253B6B342F /* Pods-MiniScanner-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 123ADF4A6B2F1DEBA5B7482D4983B685 /* Pods-MiniScanner-dummy.m */; }; - 6D55C34EF7CE4718D8B2FE6CE95C5674 /* DefaultsKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49E1F485A63A2B53CB08135A73181730 /* DefaultsKeys.swift */; }; - 6F875A0983E3FB0E0CC0BDA6376F73E8 /* String+Localiz.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DCBFDDD0C4940F9BDA4210B9FC4013D /* String+Localiz.swift */; }; - 852E6AB133CF7BDE7DE7D836AE201868 /* Languages.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F0CAC9E7319EF75A58C536C7ABC1C2 /* Languages.swift */; }; - 9E704111CAAACBF64155A576FC337323 /* LanguageManager-iOS-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 6124DDB354EE4056C15AF1DC9BDDF9F7 /* LanguageManager-iOS-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A20B3459E909921BC2C959C88BE242C7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; - AF715064CF6458D3D89BB563DFDB00C6 /* UIButton+Direction.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBB81FFD7C4FB528DA38696A9C3AA42 /* UIButton+Direction.swift */; }; - CC897E71556348377B4C31307E208C80 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; - D2A598E7174826A7B04036E7AC8AA3B6 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91343805CF84C0BAD5E26535BF5997A9 /* Storage.swift */; }; - F7C3A4FED58118F9ADC5B4AF9A10B9FC /* ViewDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8654CFEB66C546C2FE3322C42342254C /* ViewDirection.swift */; }; + 0615219BFD2EBBE27FF41C2C8816791E /* IQTextFieldViewInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 517D7F8D28A92A90BE828A2B6F463359 /* IQTextFieldViewInfo.swift */; }; + 0718CCD0E19136B8DB2A7D4C6585E3ED /* LanguageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821ACCC32DDA25E12CEB2F6F8D3726E3 /* LanguageManager.swift */; }; + 08822D4E49DB8618D27BAEDED7911733 /* IQKeyboardManager+Internal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE76EF896CB4170CBABC6E7512AEFA5 /* IQKeyboardManager+Internal.swift */; }; + 08C234F2981017EEF271582022F339F3 /* IQUIView+IQKeyboardToolbarDeprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074AE9C63795CE067E1C72CDBE945B73 /* IQUIView+IQKeyboardToolbarDeprecated.swift */; }; + 09936CDBB25F81CCBD0688CA34E025A1 /* Pods-MiniScanner-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 123ADF4A6B2F1DEBA5B7482D4983B685 /* Pods-MiniScanner-dummy.m */; }; + 0A4DB572ACD97EC492C4E93A0FFB2E47 /* IQTextFieldViewListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F6FBD9D86BA55694389EB0CD29B11B3 /* IQTextFieldViewListener.swift */; }; + 103FE4EEFF1BE8BAD0FA047987AFED74 /* IQUIView+Hierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C5E20C1DBC4A5FF8B8511CCF4D0BF31 /* IQUIView+Hierarchy.swift */; }; + 10D1A87F45AFB52D2B34D9ABA1A86105 /* UIImageView+Direction.swift in Sources */ = {isa = PBXBuildFile; fileRef = F97980DD7B51F2D18383716A1996D415 /* UIImageView+Direction.swift */; }; + 14063E1AF70EDDC9F33C8E08DCA0BEF3 /* IQPreviousNextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5AEED26E78E4244A163FCBF7FE9E8E2 /* IQPreviousNextView.swift */; }; + 154362EFC8EC0F61F54E24B09266DEB1 /* IQKeyboardReturnKeyHandler+TextFieldDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEBBFCA67A8342E7E8633D54FB526A70 /* IQKeyboardReturnKeyHandler+TextFieldDelegate.swift */; }; + 1C3881B0113D3219398154E16AA4413C /* IQKeyboardReturnKeyHandler+TextViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64268BE3E3D15E6B9A3CA1D02825D5BC /* IQKeyboardReturnKeyHandler+TextViewDelegate.swift */; }; + 23D11E770DF137CBF802A30E2B19C054 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79CF7D56C5D50C18B2EA0ED106D998C7 /* Foundation.framework */; }; + 24C699F9653980B77F44634EF44641C1 /* IQKeyboardInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8C277F89F53CC68CAA556E39994EB6A /* IQKeyboardInfo.swift */; }; + 3050954B1D31D76708C7573A0A410951 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79CF7D56C5D50C18B2EA0ED106D998C7 /* Foundation.framework */; }; + 3452528F3B9B79AD67D45FEA174F71E4 /* IQUICollectionView+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89ED4E0603BF1044DE5F139BBC2BE349 /* IQUICollectionView+Additions.swift */; }; + 34BDB069A96125DAF2FEF6FF93A3F6AF /* IQToolbarPlaceholderConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DAFDC4724628327C2D9E23816F637D7 /* IQToolbarPlaceholderConfiguration.swift */; }; + 3573FA382FBE08F99039CED491DB9FF0 /* IQKeyboardManagerSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = A4ED0E00AAB8CACA3F6000E75530AFB2 /* IQKeyboardManagerSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 38CBE3196BDD577B5E72BC65508A77F8 /* IQTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0586AA806C9438959268322091016DF1 /* IQTextView.swift */; }; + 3E21C9612D00C6B92D3FCE3589917729 /* UIView+Direction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C71AA2CEB1CA6AA98A0875E57BC289F /* UIView+Direction.swift */; }; + 4017CF2B3EE45E7E579E68E6FCFBF732 /* IQKeyboardManager+UIKeyboardNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA2FE52F8360A77D2DC409CB89836048 /* IQKeyboardManager+UIKeyboardNotification.swift */; }; + 42B931814C7B25871333D5DA9A0E2A41 /* IQKeyboardReturnKeyHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5AA613051563C2E57D792135A350BD /* IQKeyboardReturnKeyHandler.swift */; }; + 48A4D5E4D954CB4212E540A92570BBF0 /* UIView+Swizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CEB1EE4CDFE8247E3EBD87AEAFF7812 /* UIView+Swizzling.swift */; }; + 4B6666D6D3C57CF29C9767A9CF94CB4C /* Pods-MiniScanner-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E8A070B594D65627DD64F5ABC65D271 /* Pods-MiniScanner-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4CDBAE55660ED186441E9E4EDE6B3D31 /* IQKeyboardManagerSwift-IQKeyboardManagerSwift in Resources */ = {isa = PBXBuildFile; fileRef = 8D8069D3964814114ACEC3084C010B59 /* IQKeyboardManagerSwift-IQKeyboardManagerSwift */; }; + 54BAE903D82C39392943869866252D93 /* IQNSArray+Sort.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D75E27CA01DD3A3D13F7942719A75E7 /* IQNSArray+Sort.swift */; }; + 597994C3AE8908B1E462BC03AC8C23FB /* IQKeyboardManagerCompatible.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD0CA37F495B55663C4845F92F8C9BED /* IQKeyboardManagerCompatible.swift */; }; + 5F0469C5B154DC20B844EA2A9B7F8D42 /* IQPlaceholderable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB82F0DC638C418E9156FE1254F4233 /* IQPlaceholderable.swift */; }; + 5F62DAE67CF97B7C42471EA91B79AA9A /* IQTextFieldViewInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E81825ECD551E0611FFB5F8D0B7BC9D /* IQTextFieldViewInfoModel.swift */; }; + 6418A8A5D32E73D898AB155952180B0C /* LanguageManager-iOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F859DF7872022F09706156C5EB2968D /* LanguageManager-iOS-dummy.m */; }; + 670310D98A231B664F5C424035D37B24 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = E9C8EEC4FCA4DFC3C660B514F2F43A03 /* PrivacyInfo.xcprivacy */; }; + 674C6B2E317E657D8EAD3CC73F608540 /* IQKeyboardManager+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D011DB87268C132C9849BCE1C2B0A6 /* IQKeyboardManager+Debug.swift */; }; + 6D55C34EF7CE4718D8B2FE6CE95C5674 /* DefaultsKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EBDDB959E9E6ACF17E9A1407FC3F7E2 /* DefaultsKeys.swift */; }; + 6F875A0983E3FB0E0CC0BDA6376F73E8 /* String+Localiz.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA547A0350A8B9E070A709916D9517F1 /* String+Localiz.swift */; }; + 701904768C60A3F9060518DD58EC2882 /* IQToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57E2E81635BF125FB406A269ED33B812 /* IQToolbar.swift */; }; + 733CF7F19636AFF4A97708DFDE0AE53C /* IQKeyboardManagerSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3093517495679B177EFC5F1443A6F09E /* IQKeyboardManagerSwift-dummy.m */; }; + 7586D1882B962E1E31C28CC6396668B3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04D60AC13D33197690A05C641925DDDA /* UIKit.framework */; }; + 8086BD2DB5F1A0CC88E4F3386570A21C /* IQUITextFieldView+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD0FD60A5A5AC2BA854999D1E27CFFA0 /* IQUITextFieldView+Additions.swift */; }; + 82950EE4BDD57F74749742A3E1566073 /* IQKeyboardManager+UITextFieldViewNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFF6CB63AE119B421AA38F50662937F2 /* IQKeyboardManager+UITextFieldViewNotification.swift */; }; + 852E6AB133CF7BDE7DE7D836AE201868 /* Languages.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8213085A8B95D8D81A5DA1CCD48176DB /* Languages.swift */; }; + 8ED2E941DF0803C8AA331D0D8C722615 /* IQBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAEC79518E786E0A7BC09629C4AE79C3 /* IQBarButtonItem.swift */; }; + 8FDA28363A5E49017498FD69AAA8F59F /* IQKeyboardListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CBB070ABBD305023F05B427546A9285 /* IQKeyboardListener.swift */; }; + 907FCA3049CAAF64B579D08D339D118D /* IQBarButtonItemConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F2A273B75770A5ACE51A2E41CB8EFDC /* IQBarButtonItemConfiguration.swift */; }; + 94F893223EB4C1C0F829C17900114AFA /* IQUIScrollView+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC0D18E78426D786741B2D8FEE317281 /* IQUIScrollView+Additions.swift */; }; + 98A4D0D5928A35C7DB3D9272187789A8 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 840FA0B75AF62912A30DDC66B647ED98 /* CoreGraphics.framework */; }; + 9A00A25ED34A7687C62B02EBB76C1248 /* IQKeyboardConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A715620FE6AB187DFE7D76C4DC7E36DC /* IQKeyboardConfiguration.swift */; }; + 9E704111CAAACBF64155A576FC337323 /* LanguageManager-iOS-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = CC4D05FC11DD49E34C628FD4533A2568 /* LanguageManager-iOS-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9F78D56352F7D932DCEBE416C668C7BA /* IQKeyboardManager+ToolbarActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A94ED97A899EC2924B83CE2423C76E22 /* IQKeyboardManager+ToolbarActions.swift */; }; + A5E69CC013C4311C8AF52C7F7AB095C9 /* IQUITableView+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65C3408050C64D7CA6084E442F3BA3C9 /* IQUITableView+Additions.swift */; }; + AE7D065E1D48171258FD8F07F7CD592C /* IQKeyboardManagerConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E595780AD0EFFE9BC40B77C5313F58 /* IQKeyboardManagerConstants.swift */; }; + AF715064CF6458D3D89BB563DFDB00C6 /* UIButton+Direction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1DA999AC304E70850586EE4582767FA /* UIButton+Direction.swift */; }; + B1A786B1A2F11EBD1BF77305EEB710F5 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A42DBD2F42D55606EEBA514009498B87 /* QuartzCore.framework */; }; + B1BFC54288364884DDEAE75027BABE1A /* IQActiveConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FDB8EF96877DD0C01B2233EBA5702C8 /* IQActiveConfiguration.swift */; }; + B9CF878085ABA2991A9C6F12F9B9DAB3 /* IQTitleBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F84FF8DF1044B930A2FF5FD953A06A3 /* IQTitleBarButtonItem.swift */; }; + CC897E71556348377B4C31307E208C80 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79CF7D56C5D50C18B2EA0ED106D998C7 /* Foundation.framework */; }; + CC96488C33BFB3BCEE4A665A438CAC36 /* IQUIViewController+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE4138031533EEDC8A9902D7E99D501C /* IQUIViewController+Additions.swift */; }; + D2A598E7174826A7B04036E7AC8AA3B6 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FA5A3035995F2918AACEDBCAA7A2D35 /* Storage.swift */; }; + D3D1F63C30E95311B687FA924B872C15 /* IQKeyboardManager+Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345569BAFF7969027C26148BDCD67089 /* IQKeyboardManager+Deprecated.swift */; }; + D8322CBE73400EE4382D1A042D2D53D3 /* IQUIView+IQKeyboardToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2542B36B0E3593C4EE735B12326CEB3E /* IQUIView+IQKeyboardToolbar.swift */; }; + D88C2EA8ACCC0DE031D9E7A768062E2C /* IQKeyboardManager+Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FD998ABAEDD160FD4D5C8324BD5294E /* IQKeyboardManager+Toolbar.swift */; }; + DE3B5070A41194C21898D92DBFFCBE4C /* IQRootControllerConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F51BCA558A49D1481A562418DAA177 /* IQRootControllerConfiguration.swift */; }; + E483FA24409A56AAEDF8A1DEC5F55F16 /* UIImage+NextPrevious.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7371550074335F8BA7CA7223EC67EC3E /* UIImage+NextPrevious.swift */; }; + E8770A941545BB190D76BF7E5262797D /* IQToolbarConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B4AC356E7C67614B8739A99BF589079 /* IQToolbarConfiguration.swift */; }; + EBB5F245DBEEB13D48F09E0DD75A6C95 /* IQKeyboardManager+Position.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BA86CB5FEFDEFCB074FECBF22548E30 /* IQKeyboardManager+Position.swift */; }; + F681FB74C756E0AAFFDC0D414EBD8FA0 /* IQScrollViewConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC3307623E184928D1EB8BF17330A5B /* IQScrollViewConfiguration.swift */; }; + F7C3A4FED58118F9ADC5B4AF9A10B9FC /* ViewDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2946B406AC9EA1328621F52978CFBB27 /* ViewDirection.swift */; }; + F9DE1A3C506E506F4DA4B7714359E8D1 /* IQKeyboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85BCC11955CE1DABDDDF22CE6868E687 /* IQKeyboardManager.swift */; }; + FDEFBFB34E35A4BB332264E0CACCF5D8 /* IQInvocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 415D9AA15EF688EB94C14ED9A8F7672C /* IQInvocation.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 4DD7884B512AC0A832BF2E14C2F07FC2 /* PBXContainerItemProxy */ = { + 08906A1E152B2EBD296D726C4A00627E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B490E7485944099E16C9CBD79119D1D4; + remoteInfo = IQKeyboardManagerSwift; + }; + AA24290BD2F66F452D4FA8715BB9C199 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = 75F1EA88CB9544AB5CBE20DEC9A011AE; remoteInfo = "LanguageManager-iOS"; }; + F68B8DE02DB8CE82221ED42882AEACDB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 982A68D37F5DCBC1FC1FDC0BB2F0EB8E; + remoteInfo = "IQKeyboardManagerSwift-IQKeyboardManagerSwift"; + }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 04D60AC13D33197690A05C641925DDDA /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; + 0586AA806C9438959268322091016DF1 /* IQTextView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQTextView.swift; path = IQKeyboardManagerSwift/IQTextView/IQTextView.swift; sourceTree = "<group>"; }; + 074AE9C63795CE067E1C72CDBE945B73 /* IQUIView+IQKeyboardToolbarDeprecated.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIView+IQKeyboardToolbarDeprecated.swift"; path = "IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbarDeprecated.swift"; sourceTree = "<group>"; }; + 0D21025AC0DFA4E915F75D3EB6ED0BC2 /* IQKeyboardManagerSwift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "IQKeyboardManagerSwift-Info.plist"; sourceTree = "<group>"; }; 0E8A070B594D65627DD64F5ABC65D271 /* Pods-MiniScanner-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-MiniScanner-umbrella.h"; sourceTree = "<group>"; }; + 0EBDDB959E9E6ACF17E9A1407FC3F7E2 /* DefaultsKeys.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DefaultsKeys.swift; path = "LanguageManager-iOS/Classes/Constants/DefaultsKeys.swift"; sourceTree = "<group>"; }; 123ADF4A6B2F1DEBA5B7482D4983B685 /* Pods-MiniScanner-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-MiniScanner-dummy.m"; sourceTree = "<group>"; }; + 1BA86CB5FEFDEFCB074FECBF22548E30 /* IQKeyboardManager+Position.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Position.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Position.swift"; sourceTree = "<group>"; }; + 1C5679EFA26B0E4E1992CAA7C928899A /* LanguageManager-iOS-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "LanguageManager-iOS-Info.plist"; sourceTree = "<group>"; }; + 1DB82F0DC638C418E9156FE1254F4233 /* IQPlaceholderable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQPlaceholderable.swift; path = IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift; sourceTree = "<group>"; }; + 1FDB8EF96877DD0C01B2233EBA5702C8 /* IQActiveConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQActiveConfiguration.swift; path = IQKeyboardManagerSwift/Configuration/IQActiveConfiguration.swift; sourceTree = "<group>"; }; 21A62BB316C6336F03408E50D730FD01 /* Pods-MiniScanner.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-MiniScanner.modulemap"; sourceTree = "<group>"; }; - 229E7A3D5222D6F61C14A0F5D81ED987 /* LanguageManager-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "LanguageManager-iOS.release.xcconfig"; sourceTree = "<group>"; }; - 260B9319B575951CF8E8007D061EAE1C /* LanguageManager-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "LanguageManager-iOS.debug.xcconfig"; sourceTree = "<group>"; }; - 262BB6CF17E9AE775EAB68F69517D6D3 /* LanguageManager-iOS.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "LanguageManager-iOS.modulemap"; sourceTree = "<group>"; }; + 22FF8311D744FA0C5E23B24C7AE67B1D /* IQKeyboardManagerSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = IQKeyboardManagerSwift.release.xcconfig; sourceTree = "<group>"; }; + 2542B36B0E3593C4EE735B12326CEB3E /* IQUIView+IQKeyboardToolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIView+IQKeyboardToolbar.swift"; path = "IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift"; sourceTree = "<group>"; }; + 28C0DECFE80A050466E59F2C181B9EFC /* IQKeyboardManagerSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = IQKeyboardManagerSwift.modulemap; sourceTree = "<group>"; }; + 2946B406AC9EA1328621F52978CFBB27 /* ViewDirection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ViewDirection.swift; path = "LanguageManager-iOS/Classes/Constants/ViewDirection.swift"; sourceTree = "<group>"; }; + 2B4AC356E7C67614B8739A99BF589079 /* IQToolbarConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQToolbarConfiguration.swift; path = IQKeyboardManagerSwift/Configuration/IQToolbarConfiguration.swift; sourceTree = "<group>"; }; + 2F2A273B75770A5ACE51A2E41CB8EFDC /* IQBarButtonItemConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQBarButtonItemConfiguration.swift; path = IQKeyboardManagerSwift/Configuration/IQBarButtonItemConfiguration.swift; sourceTree = "<group>"; }; + 3093517495679B177EFC5F1443A6F09E /* IQKeyboardManagerSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "IQKeyboardManagerSwift-dummy.m"; sourceTree = "<group>"; }; 3438B9790556194C521D4C9806D29C85 /* Pods-MiniScanner */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-MiniScanner"; path = Pods_MiniScanner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 369DE03EA683F0F0E8F6CE4CC611561E /* LanguageManager-iOS-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "LanguageManager-iOS-Info.plist"; sourceTree = "<group>"; }; + 345569BAFF7969027C26148BDCD67089 /* IQKeyboardManager+Deprecated.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Deprecated.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Deprecated.swift"; sourceTree = "<group>"; }; + 3AE76EF896CB4170CBABC6E7512AEFA5 /* IQKeyboardManager+Internal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Internal.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Internal.swift"; sourceTree = "<group>"; }; 3B6258C4E2C1059AABC67D66F9314FE8 /* Pods-MiniScanner-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-MiniScanner-acknowledgements.markdown"; sourceTree = "<group>"; }; - 49E1F485A63A2B53CB08135A73181730 /* DefaultsKeys.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DefaultsKeys.swift; path = "LanguageManager-iOS/Classes/Constants/DefaultsKeys.swift"; sourceTree = "<group>"; }; - 5DCBFDDD0C4940F9BDA4210B9FC4013D /* String+Localiz.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+Localiz.swift"; path = "LanguageManager-iOS/Classes/Helpers/Extensions/String+Localiz.swift"; sourceTree = "<group>"; }; - 6124DDB354EE4056C15AF1DC9BDDF9F7 /* LanguageManager-iOS-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "LanguageManager-iOS-umbrella.h"; sourceTree = "<group>"; }; + 3CEB1EE4CDFE8247E3EBD87AEAFF7812 /* UIView+Swizzling.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIView+Swizzling.swift"; path = "LanguageManager-iOS/Classes/Helpers/Extensions/UIView+Swizzling.swift"; sourceTree = "<group>"; }; + 3E81825ECD551E0611FFB5F8D0B7BC9D /* IQTextFieldViewInfoModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQTextFieldViewInfoModel.swift; path = IQKeyboardManagerSwift/ReturnKeyHandler/IQTextFieldViewInfoModel.swift; sourceTree = "<group>"; }; + 3FD998ABAEDD160FD4D5C8324BD5294E /* IQKeyboardManager+Toolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Toolbar.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Toolbar.swift"; sourceTree = "<group>"; }; + 415D9AA15EF688EB94C14ED9A8F7672C /* IQInvocation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQInvocation.swift; path = IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift; sourceTree = "<group>"; }; + 447CF01CBF4066825019B2CBB67AEBDF /* LanguageManager-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "LanguageManager-iOS.release.xcconfig"; sourceTree = "<group>"; }; + 46C8738ABBC60F8B9E148126B4956F55 /* LanguageManager-iOS-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "LanguageManager-iOS-prefix.pch"; sourceTree = "<group>"; }; + 4CF6F91F9C3F1332F80F8D41322A26D0 /* ResourceBundle-IQKeyboardManagerSwift-IQKeyboardManagerSwift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-IQKeyboardManagerSwift-IQKeyboardManagerSwift-Info.plist"; sourceTree = "<group>"; }; + 4F859DF7872022F09706156C5EB2968D /* LanguageManager-iOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "LanguageManager-iOS-dummy.m"; sourceTree = "<group>"; }; + 517D7F8D28A92A90BE828A2B6F463359 /* IQTextFieldViewInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQTextFieldViewInfo.swift; path = IQKeyboardManagerSwift/LIsteners/Info/IQTextFieldViewInfo.swift; sourceTree = "<group>"; }; + 54F51BCA558A49D1481A562418DAA177 /* IQRootControllerConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQRootControllerConfiguration.swift; path = IQKeyboardManagerSwift/Configuration/IQRootControllerConfiguration.swift; sourceTree = "<group>"; }; + 57E2E81635BF125FB406A269ED33B812 /* IQToolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQToolbar.swift; path = IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift; sourceTree = "<group>"; }; + 5C5AA613051563C2E57D792135A350BD /* IQKeyboardReturnKeyHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardReturnKeyHandler.swift; path = IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler.swift; sourceTree = "<group>"; }; + 5CBB070ABBD305023F05B427546A9285 /* IQKeyboardListener.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardListener.swift; path = IQKeyboardManagerSwift/LIsteners/IQKeyboardListener.swift; sourceTree = "<group>"; }; + 64268BE3E3D15E6B9A3CA1D02825D5BC /* IQKeyboardReturnKeyHandler+TextViewDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardReturnKeyHandler+TextViewDelegate.swift"; path = "IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler+TextViewDelegate.swift"; sourceTree = "<group>"; }; 6473C16F43F7217C13AEA5FBA6C8247F /* LanguageManager-iOS */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "LanguageManager-iOS"; path = LanguageManager_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - 76C3AD529D7D4EE4869591BF3965031B /* LanguageManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LanguageManager.swift; path = "LanguageManager-iOS/Classes/Main/LanguageManager.swift"; sourceTree = "<group>"; }; + 65C3408050C64D7CA6084E442F3BA3C9 /* IQUITableView+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUITableView+Additions.swift"; path = "IQKeyboardManagerSwift/UIKitExtensions/IQUITableView+Additions.swift"; sourceTree = "<group>"; }; + 6DAFDC4724628327C2D9E23816F637D7 /* IQToolbarPlaceholderConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQToolbarPlaceholderConfiguration.swift; path = IQKeyboardManagerSwift/Configuration/IQToolbarPlaceholderConfiguration.swift; sourceTree = "<group>"; }; + 6DC3307623E184928D1EB8BF17330A5B /* IQScrollViewConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQScrollViewConfiguration.swift; path = IQKeyboardManagerSwift/Configuration/IQScrollViewConfiguration.swift; sourceTree = "<group>"; }; + 6F84FF8DF1044B930A2FF5FD953A06A3 /* IQTitleBarButtonItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQTitleBarButtonItem.swift; path = IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift; sourceTree = "<group>"; }; + 7371550074335F8BA7CA7223EC67EC3E /* UIImage+NextPrevious.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIImage+NextPrevious.swift"; path = "IQKeyboardManagerSwift/UIKitExtensions/UIImage+NextPrevious.swift"; sourceTree = "<group>"; }; 798C61760B9BC4B07BC60D42FCC09855 /* Pods-MiniScanner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-MiniScanner.release.xcconfig"; sourceTree = "<group>"; }; + 79CF7D56C5D50C18B2EA0ED106D998C7 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 7CC191E7994C3C7161A6641B457C9166 /* Pods-MiniScanner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-MiniScanner.debug.xcconfig"; sourceTree = "<group>"; }; - 84D1BEBD5F5E11A9D5238E1D4F0C3DBB /* LanguageManager-iOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "LanguageManager-iOS-dummy.m"; sourceTree = "<group>"; }; - 8654CFEB66C546C2FE3322C42342254C /* ViewDirection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ViewDirection.swift; path = "LanguageManager-iOS/Classes/Constants/ViewDirection.swift"; sourceTree = "<group>"; }; + 7FA5A3035995F2918AACEDBCAA7A2D35 /* Storage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Storage.swift; path = "LanguageManager-iOS/Classes/Helpers/Storage.swift"; sourceTree = "<group>"; }; + 8213085A8B95D8D81A5DA1CCD48176DB /* Languages.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Languages.swift; path = "LanguageManager-iOS/Classes/Constants/Languages.swift"; sourceTree = "<group>"; }; + 821ACCC32DDA25E12CEB2F6F8D3726E3 /* LanguageManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LanguageManager.swift; path = "LanguageManager-iOS/Classes/Main/LanguageManager.swift"; sourceTree = "<group>"; }; + 840FA0B75AF62912A30DDC66B647ED98 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; + 85BCC11955CE1DABDDDF22CE6868E687 /* IQKeyboardManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManager.swift; path = IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager.swift; sourceTree = "<group>"; }; 89194C84FD5E62D9D2C9F2157676FF5C /* Pods-MiniScanner-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-MiniScanner-acknowledgements.plist"; sourceTree = "<group>"; }; - 91343805CF84C0BAD5E26535BF5997A9 /* Storage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Storage.swift; path = "LanguageManager-iOS/Classes/Helpers/Storage.swift"; sourceTree = "<group>"; }; + 89ED4E0603BF1044DE5F139BBC2BE349 /* IQUICollectionView+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUICollectionView+Additions.swift"; path = "IQKeyboardManagerSwift/UIKitExtensions/IQUICollectionView+Additions.swift"; sourceTree = "<group>"; }; + 8C71AA2CEB1CA6AA98A0875E57BC289F /* UIView+Direction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIView+Direction.swift"; path = "LanguageManager-iOS/Classes/Helpers/Extensions/UIView+Direction.swift"; sourceTree = "<group>"; }; + 8D75E27CA01DD3A3D13F7942719A75E7 /* IQNSArray+Sort.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQNSArray+Sort.swift"; path = "IQKeyboardManagerSwift/UIKitExtensions/IQNSArray+Sort.swift"; sourceTree = "<group>"; }; + 8D8069D3964814114ACEC3084C010B59 /* IQKeyboardManagerSwift-IQKeyboardManagerSwift */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "IQKeyboardManagerSwift-IQKeyboardManagerSwift"; path = IQKeyboardManagerSwift.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 8F6FBD9D86BA55694389EB0CD29B11B3 /* IQTextFieldViewListener.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQTextFieldViewListener.swift; path = IQKeyboardManagerSwift/LIsteners/IQTextFieldViewListener.swift; sourceTree = "<group>"; }; + 9C5E20C1DBC4A5FF8B8511CCF4D0BF31 /* IQUIView+Hierarchy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIView+Hierarchy.swift"; path = "IQKeyboardManagerSwift/UIKitExtensions/IQUIView+Hierarchy.swift"; sourceTree = "<group>"; }; 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + A42DBD2F42D55606EEBA514009498B87 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; + A4ED0E00AAB8CACA3F6000E75530AFB2 /* IQKeyboardManagerSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "IQKeyboardManagerSwift-umbrella.h"; sourceTree = "<group>"; }; + A5A355868A86C403B3B57F24A848F501 /* IQKeyboardManagerSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "IQKeyboardManagerSwift-prefix.pch"; sourceTree = "<group>"; }; + A715620FE6AB187DFE7D76C4DC7E36DC /* IQKeyboardConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardConfiguration.swift; path = IQKeyboardManagerSwift/Configuration/IQKeyboardConfiguration.swift; sourceTree = "<group>"; }; + A8E950A16D00F649C54FFB30F81D7842 /* IQKeyboardManagerSwift */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = IQKeyboardManagerSwift; path = IQKeyboardManagerSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A94ED97A899EC2924B83CE2423C76E22 /* IQKeyboardManager+ToolbarActions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+ToolbarActions.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+ToolbarActions.swift"; sourceTree = "<group>"; }; + AFF6CB63AE119B421AA38F50662937F2 /* IQKeyboardManager+UITextFieldViewNotification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+UITextFieldViewNotification.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+UITextFieldViewNotification.swift"; sourceTree = "<group>"; }; + B1DA999AC304E70850586EE4582767FA /* UIButton+Direction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Direction.swift"; path = "LanguageManager-iOS/Classes/Helpers/Extensions/UIButton+Direction.swift"; sourceTree = "<group>"; }; B2968141E72EA49CC006DD4020E3386D /* Pods-MiniScanner-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-MiniScanner-frameworks.sh"; sourceTree = "<group>"; }; - BB1EB585FB79943D0D18D7F79322CD60 /* UIView+Swizzling.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIView+Swizzling.swift"; path = "LanguageManager-iOS/Classes/Helpers/Extensions/UIView+Swizzling.swift"; sourceTree = "<group>"; }; - BBBB81FFD7C4FB528DA38696A9C3AA42 /* UIButton+Direction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Direction.swift"; path = "LanguageManager-iOS/Classes/Helpers/Extensions/UIButton+Direction.swift"; sourceTree = "<group>"; }; - BD4005C2FC9E5447CF8F35CFDF18F517 /* UIImageView+Direction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIImageView+Direction.swift"; path = "LanguageManager-iOS/Classes/Helpers/Extensions/UIImageView+Direction.swift"; sourceTree = "<group>"; }; - BD718E6CB3EA4175288EFD1790ABE180 /* UIView+Direction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIView+Direction.swift"; path = "LanguageManager-iOS/Classes/Helpers/Extensions/UIView+Direction.swift"; sourceTree = "<group>"; }; - E4F0CAC9E7319EF75A58C536C7ABC1C2 /* Languages.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Languages.swift; path = "LanguageManager-iOS/Classes/Constants/Languages.swift"; sourceTree = "<group>"; }; + BA2FE52F8360A77D2DC409CB89836048 /* IQKeyboardManager+UIKeyboardNotification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+UIKeyboardNotification.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+UIKeyboardNotification.swift"; sourceTree = "<group>"; }; + BA547A0350A8B9E070A709916D9517F1 /* String+Localiz.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+Localiz.swift"; path = "LanguageManager-iOS/Classes/Helpers/Extensions/String+Localiz.swift"; sourceTree = "<group>"; }; + C4E595780AD0EFFE9BC40B77C5313F58 /* IQKeyboardManagerConstants.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManagerConstants.swift; path = IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift; sourceTree = "<group>"; }; + C5AEED26E78E4244A163FCBF7FE9E8E2 /* IQPreviousNextView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQPreviousNextView.swift; path = IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift; sourceTree = "<group>"; }; + CC4D05FC11DD49E34C628FD4533A2568 /* LanguageManager-iOS-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "LanguageManager-iOS-umbrella.h"; sourceTree = "<group>"; }; + D0D011DB87268C132C9849BCE1C2B0A6 /* IQKeyboardManager+Debug.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Debug.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager/IQKeyboardManager+Debug.swift"; sourceTree = "<group>"; }; + D5DEB8326457EA62DEC0C48A2B4CD8AA /* LanguageManager-iOS.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "LanguageManager-iOS.modulemap"; sourceTree = "<group>"; }; + D8C277F89F53CC68CAA556E39994EB6A /* IQKeyboardInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardInfo.swift; path = IQKeyboardManagerSwift/LIsteners/Info/IQKeyboardInfo.swift; sourceTree = "<group>"; }; + DD0FD60A5A5AC2BA854999D1E27CFFA0 /* IQUITextFieldView+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUITextFieldView+Additions.swift"; path = "IQKeyboardManagerSwift/UIKitExtensions/IQUITextFieldView+Additions.swift"; sourceTree = "<group>"; }; + E9C8EEC4FCA4DFC3C660B514F2F43A03 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = IQKeyboardManagerSwift/PrivacyInfo.xcprivacy; sourceTree = "<group>"; }; + ED153F395FC11B265453987CD5F97492 /* LanguageManager-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "LanguageManager-iOS.debug.xcconfig"; sourceTree = "<group>"; }; ED8E7C0ED656254925E918D5509B655C /* Pods-MiniScanner-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-MiniScanner-Info.plist"; sourceTree = "<group>"; }; - F4DF5D970CBDDD74A26B1FFADEC0369F /* LanguageManager-iOS-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "LanguageManager-iOS-prefix.pch"; sourceTree = "<group>"; }; + EEBBFCA67A8342E7E8633D54FB526A70 /* IQKeyboardReturnKeyHandler+TextFieldDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardReturnKeyHandler+TextFieldDelegate.swift"; path = "IQKeyboardManagerSwift/ReturnKeyHandler/IQKeyboardReturnKeyHandler+TextFieldDelegate.swift"; sourceTree = "<group>"; }; + F97980DD7B51F2D18383716A1996D415 /* UIImageView+Direction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIImageView+Direction.swift"; path = "LanguageManager-iOS/Classes/Helpers/Extensions/UIImageView+Direction.swift"; sourceTree = "<group>"; }; + F97F62F12C7D10E03540793DDD57009B /* IQKeyboardManagerSwift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = IQKeyboardManagerSwift.debug.xcconfig; sourceTree = "<group>"; }; + FAEC79518E786E0A7BC09629C4AE79C3 /* IQBarButtonItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQBarButtonItem.swift; path = IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift; sourceTree = "<group>"; }; + FC0D18E78426D786741B2D8FEE317281 /* IQUIScrollView+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIScrollView+Additions.swift"; path = "IQKeyboardManagerSwift/UIKitExtensions/IQUIScrollView+Additions.swift"; sourceTree = "<group>"; }; + FD0CA37F495B55663C4845F92F8C9BED /* IQKeyboardManagerCompatible.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManagerCompatible.swift; path = IQKeyboardManagerSwift/IQKeyboardManagerCompatible/IQKeyboardManagerCompatible.swift; sourceTree = "<group>"; }; + FE4138031533EEDC8A9902D7E99D501C /* IQUIViewController+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIViewController+Additions.swift"; path = "IQKeyboardManagerSwift/UIKitExtensions/IQUIViewController+Additions.swift"; sourceTree = "<group>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 1FFF1AD677D25574B8A7374F5CA7F8D7 /* Frameworks */ = { + 3130A51D7DFF19A4DA7649752464E8ED /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 98A4D0D5928A35C7DB3D9272187789A8 /* CoreGraphics.framework in Frameworks */, + 23D11E770DF137CBF802A30E2B19C054 /* Foundation.framework in Frameworks */, + B1A786B1A2F11EBD1BF77305EEB710F5 /* QuartzCore.framework in Frameworks */, + 7586D1882B962E1E31C28CC6396668B3 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8181E2665F51FD7A659B08B2AD775BAA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A2F22B93888754A7DF5F74ED4B572E1B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A20B3459E909921BC2C959C88BE242C7 /* Foundation.framework in Frameworks */, + 3050954B1D31D76708C7573A0A410951 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -88,90 +228,162 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 2DBE059E42E3C9D4261BFE1075C913EB /* Pods */ = { + 1517BE1B9476BC36DA77D9D6370B9093 /* Resources */ = { + isa = PBXGroup; + children = ( + E9C8EEC4FCA4DFC3C660B514F2F43A03 /* PrivacyInfo.xcprivacy */, + ); + name = Resources; + sourceTree = "<group>"; + }; + 19746984F7078B76BDE5AB11C2BE3B60 /* Products */ = { + isa = PBXGroup; + children = ( + A8E950A16D00F649C54FFB30F81D7842 /* IQKeyboardManagerSwift */, + 8D8069D3964814114ACEC3084C010B59 /* IQKeyboardManagerSwift-IQKeyboardManagerSwift */, + 6473C16F43F7217C13AEA5FBA6C8247F /* LanguageManager-iOS */, + 3438B9790556194C521D4C9806D29C85 /* Pods-MiniScanner */, + ); + name = Products; + sourceTree = "<group>"; + }; + 1C9CDF2CD7BF08A25723B10B9A173C0C /* Pods */ = { isa = PBXGroup; children = ( - 438113CAA065394280E48B252880DFF2 /* LanguageManager-iOS */, + 216745C0B58F7883065166E3E0A897BC /* IQKeyboardManagerSwift */, + E4219A16D89A1708CCE232F0E441E9E4 /* LanguageManager-iOS */, ); name = Pods; sourceTree = "<group>"; }; - 438113CAA065394280E48B252880DFF2 /* LanguageManager-iOS */ = { + 216745C0B58F7883065166E3E0A897BC /* IQKeyboardManagerSwift */ = { isa = PBXGroup; children = ( - 49E1F485A63A2B53CB08135A73181730 /* DefaultsKeys.swift */, - 76C3AD529D7D4EE4869591BF3965031B /* LanguageManager.swift */, - E4F0CAC9E7319EF75A58C536C7ABC1C2 /* Languages.swift */, - 91343805CF84C0BAD5E26535BF5997A9 /* Storage.swift */, - 5DCBFDDD0C4940F9BDA4210B9FC4013D /* String+Localiz.swift */, - BBBB81FFD7C4FB528DA38696A9C3AA42 /* UIButton+Direction.swift */, - BD4005C2FC9E5447CF8F35CFDF18F517 /* UIImageView+Direction.swift */, - BD718E6CB3EA4175288EFD1790ABE180 /* UIView+Direction.swift */, - BB1EB585FB79943D0D18D7F79322CD60 /* UIView+Swizzling.swift */, - 8654CFEB66C546C2FE3322C42342254C /* ViewDirection.swift */, - 5CECBC0D2A5BDAB0FD79B22FACD52DA7 /* Support Files */, + 1FDB8EF96877DD0C01B2233EBA5702C8 /* IQActiveConfiguration.swift */, + FAEC79518E786E0A7BC09629C4AE79C3 /* IQBarButtonItem.swift */, + 2F2A273B75770A5ACE51A2E41CB8EFDC /* IQBarButtonItemConfiguration.swift */, + 415D9AA15EF688EB94C14ED9A8F7672C /* IQInvocation.swift */, + A715620FE6AB187DFE7D76C4DC7E36DC /* IQKeyboardConfiguration.swift */, + D8C277F89F53CC68CAA556E39994EB6A /* IQKeyboardInfo.swift */, + 5CBB070ABBD305023F05B427546A9285 /* IQKeyboardListener.swift */, + 85BCC11955CE1DABDDDF22CE6868E687 /* IQKeyboardManager.swift */, + D0D011DB87268C132C9849BCE1C2B0A6 /* IQKeyboardManager+Debug.swift */, + 345569BAFF7969027C26148BDCD67089 /* IQKeyboardManager+Deprecated.swift */, + 3AE76EF896CB4170CBABC6E7512AEFA5 /* IQKeyboardManager+Internal.swift */, + 1BA86CB5FEFDEFCB074FECBF22548E30 /* IQKeyboardManager+Position.swift */, + 3FD998ABAEDD160FD4D5C8324BD5294E /* IQKeyboardManager+Toolbar.swift */, + A94ED97A899EC2924B83CE2423C76E22 /* IQKeyboardManager+ToolbarActions.swift */, + BA2FE52F8360A77D2DC409CB89836048 /* IQKeyboardManager+UIKeyboardNotification.swift */, + AFF6CB63AE119B421AA38F50662937F2 /* IQKeyboardManager+UITextFieldViewNotification.swift */, + FD0CA37F495B55663C4845F92F8C9BED /* IQKeyboardManagerCompatible.swift */, + C4E595780AD0EFFE9BC40B77C5313F58 /* IQKeyboardManagerConstants.swift */, + 5C5AA613051563C2E57D792135A350BD /* IQKeyboardReturnKeyHandler.swift */, + EEBBFCA67A8342E7E8633D54FB526A70 /* IQKeyboardReturnKeyHandler+TextFieldDelegate.swift */, + 64268BE3E3D15E6B9A3CA1D02825D5BC /* IQKeyboardReturnKeyHandler+TextViewDelegate.swift */, + 8D75E27CA01DD3A3D13F7942719A75E7 /* IQNSArray+Sort.swift */, + 1DB82F0DC638C418E9156FE1254F4233 /* IQPlaceholderable.swift */, + C5AEED26E78E4244A163FCBF7FE9E8E2 /* IQPreviousNextView.swift */, + 54F51BCA558A49D1481A562418DAA177 /* IQRootControllerConfiguration.swift */, + 6DC3307623E184928D1EB8BF17330A5B /* IQScrollViewConfiguration.swift */, + 517D7F8D28A92A90BE828A2B6F463359 /* IQTextFieldViewInfo.swift */, + 3E81825ECD551E0611FFB5F8D0B7BC9D /* IQTextFieldViewInfoModel.swift */, + 8F6FBD9D86BA55694389EB0CD29B11B3 /* IQTextFieldViewListener.swift */, + 0586AA806C9438959268322091016DF1 /* IQTextView.swift */, + 6F84FF8DF1044B930A2FF5FD953A06A3 /* IQTitleBarButtonItem.swift */, + 57E2E81635BF125FB406A269ED33B812 /* IQToolbar.swift */, + 2B4AC356E7C67614B8739A99BF589079 /* IQToolbarConfiguration.swift */, + 6DAFDC4724628327C2D9E23816F637D7 /* IQToolbarPlaceholderConfiguration.swift */, + 89ED4E0603BF1044DE5F139BBC2BE349 /* IQUICollectionView+Additions.swift */, + FC0D18E78426D786741B2D8FEE317281 /* IQUIScrollView+Additions.swift */, + 65C3408050C64D7CA6084E442F3BA3C9 /* IQUITableView+Additions.swift */, + DD0FD60A5A5AC2BA854999D1E27CFFA0 /* IQUITextFieldView+Additions.swift */, + 9C5E20C1DBC4A5FF8B8511CCF4D0BF31 /* IQUIView+Hierarchy.swift */, + 2542B36B0E3593C4EE735B12326CEB3E /* IQUIView+IQKeyboardToolbar.swift */, + 074AE9C63795CE067E1C72CDBE945B73 /* IQUIView+IQKeyboardToolbarDeprecated.swift */, + FE4138031533EEDC8A9902D7E99D501C /* IQUIViewController+Additions.swift */, + 7371550074335F8BA7CA7223EC67EC3E /* UIImage+NextPrevious.swift */, + 1517BE1B9476BC36DA77D9D6370B9093 /* Resources */, + B14FB62810B4B86CF960BE6F6F9FF856 /* Support Files */, ); - name = "LanguageManager-iOS"; - path = "LanguageManager-iOS"; + name = IQKeyboardManagerSwift; + path = IQKeyboardManagerSwift; sourceTree = "<group>"; }; - 4D4CEF8B268059E0EAA55587E7875E88 /* Products */ = { + 67EA5FFBCFCDDED6A445407A917EE0A1 /* Targets Support Files */ = { isa = PBXGroup; children = ( - 6473C16F43F7217C13AEA5FBA6C8247F /* LanguageManager-iOS */, - 3438B9790556194C521D4C9806D29C85 /* Pods-MiniScanner */, + EC99F10DC5C191754BE16B2F6AC739A8 /* Pods-MiniScanner */, ); - name = Products; + name = "Targets Support Files"; sourceTree = "<group>"; }; - 578452D2E740E91742655AC8F1636D1F /* iOS */ = { + B14FB62810B4B86CF960BE6F6F9FF856 /* Support Files */ = { isa = PBXGroup; children = ( - 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */, + 28C0DECFE80A050466E59F2C181B9EFC /* IQKeyboardManagerSwift.modulemap */, + 3093517495679B177EFC5F1443A6F09E /* IQKeyboardManagerSwift-dummy.m */, + 0D21025AC0DFA4E915F75D3EB6ED0BC2 /* IQKeyboardManagerSwift-Info.plist */, + A5A355868A86C403B3B57F24A848F501 /* IQKeyboardManagerSwift-prefix.pch */, + A4ED0E00AAB8CACA3F6000E75530AFB2 /* IQKeyboardManagerSwift-umbrella.h */, + F97F62F12C7D10E03540793DDD57009B /* IQKeyboardManagerSwift.debug.xcconfig */, + 22FF8311D744FA0C5E23B24C7AE67B1D /* IQKeyboardManagerSwift.release.xcconfig */, + 4CF6F91F9C3F1332F80F8D41322A26D0 /* ResourceBundle-IQKeyboardManagerSwift-IQKeyboardManagerSwift-Info.plist */, ); - name = iOS; + name = "Support Files"; + path = "../Target Support Files/IQKeyboardManagerSwift"; sourceTree = "<group>"; }; - 5CECBC0D2A5BDAB0FD79B22FACD52DA7 /* Support Files */ = { + B27A879E075CE0048B8E592B3B333D64 /* Support Files */ = { isa = PBXGroup; children = ( - 262BB6CF17E9AE775EAB68F69517D6D3 /* LanguageManager-iOS.modulemap */, - 84D1BEBD5F5E11A9D5238E1D4F0C3DBB /* LanguageManager-iOS-dummy.m */, - 369DE03EA683F0F0E8F6CE4CC611561E /* LanguageManager-iOS-Info.plist */, - F4DF5D970CBDDD74A26B1FFADEC0369F /* LanguageManager-iOS-prefix.pch */, - 6124DDB354EE4056C15AF1DC9BDDF9F7 /* LanguageManager-iOS-umbrella.h */, - 260B9319B575951CF8E8007D061EAE1C /* LanguageManager-iOS.debug.xcconfig */, - 229E7A3D5222D6F61C14A0F5D81ED987 /* LanguageManager-iOS.release.xcconfig */, + D5DEB8326457EA62DEC0C48A2B4CD8AA /* LanguageManager-iOS.modulemap */, + 4F859DF7872022F09706156C5EB2968D /* LanguageManager-iOS-dummy.m */, + 1C5679EFA26B0E4E1992CAA7C928899A /* LanguageManager-iOS-Info.plist */, + 46C8738ABBC60F8B9E148126B4956F55 /* LanguageManager-iOS-prefix.pch */, + CC4D05FC11DD49E34C628FD4533A2568 /* LanguageManager-iOS-umbrella.h */, + ED153F395FC11B265453987CD5F97492 /* LanguageManager-iOS.debug.xcconfig */, + 447CF01CBF4066825019B2CBB67AEBDF /* LanguageManager-iOS.release.xcconfig */, ); name = "Support Files"; path = "../Target Support Files/LanguageManager-iOS"; sourceTree = "<group>"; }; - 67EA5FFBCFCDDED6A445407A917EE0A1 /* Targets Support Files */ = { + BA4F31F07263C99FC76E66D632A59F09 /* Frameworks */ = { isa = PBXGroup; children = ( - EC99F10DC5C191754BE16B2F6AC739A8 /* Pods-MiniScanner */, + F9D206BABE81E6BF0B9B23880B238CC7 /* iOS */, ); - name = "Targets Support Files"; + name = Frameworks; sourceTree = "<group>"; }; CF1408CF629C7361332E53B88F7BD30C = { isa = PBXGroup; children = ( 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, - D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */, - 2DBE059E42E3C9D4261BFE1075C913EB /* Pods */, - 4D4CEF8B268059E0EAA55587E7875E88 /* Products */, + BA4F31F07263C99FC76E66D632A59F09 /* Frameworks */, + 1C9CDF2CD7BF08A25723B10B9A173C0C /* Pods */, + 19746984F7078B76BDE5AB11C2BE3B60 /* Products */, 67EA5FFBCFCDDED6A445407A917EE0A1 /* Targets Support Files */, ); sourceTree = "<group>"; }; - D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = { + E4219A16D89A1708CCE232F0E441E9E4 /* LanguageManager-iOS */ = { isa = PBXGroup; children = ( - 578452D2E740E91742655AC8F1636D1F /* iOS */, + 0EBDDB959E9E6ACF17E9A1407FC3F7E2 /* DefaultsKeys.swift */, + 821ACCC32DDA25E12CEB2F6F8D3726E3 /* LanguageManager.swift */, + 8213085A8B95D8D81A5DA1CCD48176DB /* Languages.swift */, + 7FA5A3035995F2918AACEDBCAA7A2D35 /* Storage.swift */, + BA547A0350A8B9E070A709916D9517F1 /* String+Localiz.swift */, + B1DA999AC304E70850586EE4582767FA /* UIButton+Direction.swift */, + F97980DD7B51F2D18383716A1996D415 /* UIImageView+Direction.swift */, + 8C71AA2CEB1CA6AA98A0875E57BC289F /* UIView+Direction.swift */, + 3CEB1EE4CDFE8247E3EBD87AEAFF7812 /* UIView+Swizzling.swift */, + 2946B406AC9EA1328621F52978CFBB27 /* ViewDirection.swift */, + B27A879E075CE0048B8E592B3B333D64 /* Support Files */, ); - name = Frameworks; + name = "LanguageManager-iOS"; + path = "LanguageManager-iOS"; sourceTree = "<group>"; }; EC99F10DC5C191754BE16B2F6AC739A8 /* Pods-MiniScanner */ = { @@ -191,6 +403,17 @@ path = "Target Support Files/Pods-MiniScanner"; sourceTree = "<group>"; }; + F9D206BABE81E6BF0B9B23880B238CC7 /* iOS */ = { + isa = PBXGroup; + children = ( + 840FA0B75AF62912A30DDC66B647ED98 /* CoreGraphics.framework */, + 79CF7D56C5D50C18B2EA0ED106D998C7 /* Foundation.framework */, + A42DBD2F42D55606EEBA514009498B87 /* QuartzCore.framework */, + 04D60AC13D33197690A05C641925DDDA /* UIKit.framework */, + ); + name = iOS; + sourceTree = "<group>"; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -202,11 +425,19 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 605D18A3E1F2C5A519716B3E3574E87E /* Headers */ = { + 4DDD6C590954CC9327842078D4FD718D /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 4A525A4C45A6519919550C49896FCE30 /* Pods-MiniScanner-umbrella.h in Headers */, + 4B6666D6D3C57CF29C9767A9CF94CB4C /* Pods-MiniScanner-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 77150D3DA409E22AAAE3AC967B0FDC17 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 3573FA382FBE08F99039CED491DB9FF0 /* IQKeyboardManagerSwift-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -215,17 +446,18 @@ /* Begin PBXNativeTarget section */ 4372AB6A3C495222906A1ABFD39A4463 /* Pods-MiniScanner */ = { isa = PBXNativeTarget; - buildConfigurationList = 6F6CE1FB7DDC767B55B89C1A2DFBC636 /* Build configuration list for PBXNativeTarget "Pods-MiniScanner" */; + buildConfigurationList = 04D5557B7DEECE0FC64F5301035A4CC3 /* Build configuration list for PBXNativeTarget "Pods-MiniScanner" */; buildPhases = ( - 605D18A3E1F2C5A519716B3E3574E87E /* Headers */, - 8A2C45DB9ED445D641C1976833472DC7 /* Sources */, - 1FFF1AD677D25574B8A7374F5CA7F8D7 /* Frameworks */, - 41C60577E673C501BA87D47FD416DC0D /* Resources */, + 4DDD6C590954CC9327842078D4FD718D /* Headers */, + F9C75295AA740325086A3FCA7458D3EE /* Sources */, + A2F22B93888754A7DF5F74ED4B572E1B /* Frameworks */, + B2D3F813B90BA06914DE6D3D710B9BFA /* Resources */, ); buildRules = ( ); dependencies = ( - 1E2DC51A6663DD85438DF52518053178 /* PBXTargetDependency */, + 70B394A376C36F5FD5FB14290629A6AF /* PBXTargetDependency */, + 9E5E0442EF5E505708CA6D618C31E468 /* PBXTargetDependency */, ); name = "Pods-MiniScanner"; productName = Pods_MiniScanner; @@ -250,6 +482,42 @@ productReference = 6473C16F43F7217C13AEA5FBA6C8247F /* LanguageManager-iOS */; productType = "com.apple.product-type.framework"; }; + 982A68D37F5DCBC1FC1FDC0BB2F0EB8E /* IQKeyboardManagerSwift-IQKeyboardManagerSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = F355D0811AB05A75A0C8E6107F95470A /* Build configuration list for PBXNativeTarget "IQKeyboardManagerSwift-IQKeyboardManagerSwift" */; + buildPhases = ( + 8FE0832F0DF382FA18A5D3CADD1B6351 /* Sources */, + 8181E2665F51FD7A659B08B2AD775BAA /* Frameworks */, + 1F6536881239A8473B02B921C14549E4 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "IQKeyboardManagerSwift-IQKeyboardManagerSwift"; + productName = IQKeyboardManagerSwift; + productReference = 8D8069D3964814114ACEC3084C010B59 /* IQKeyboardManagerSwift-IQKeyboardManagerSwift */; + productType = "com.apple.product-type.bundle"; + }; + B490E7485944099E16C9CBD79119D1D4 /* IQKeyboardManagerSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = 397157E58CC1977C23EB745CC0C04035 /* Build configuration list for PBXNativeTarget "IQKeyboardManagerSwift" */; + buildPhases = ( + 77150D3DA409E22AAAE3AC967B0FDC17 /* Headers */, + 335F86AE3E21D4BDAD21A4F79F2DA8F9 /* Sources */, + 3130A51D7DFF19A4DA7649752464E8ED /* Frameworks */, + 4A72A323CCD420112722EDFB4439C184 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DFFDC8AC6E79C759B3548C41CB3F7C76 /* PBXTargetDependency */, + ); + name = IQKeyboardManagerSwift; + productName = IQKeyboardManagerSwift; + productReference = A8E950A16D00F649C54FFB30F81D7842 /* IQKeyboardManagerSwift */; + productType = "com.apple.product-type.framework"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -268,10 +536,12 @@ en, ); mainGroup = CF1408CF629C7361332E53B88F7BD30C; - productRefGroup = 4D4CEF8B268059E0EAA55587E7875E88 /* Products */; + productRefGroup = 19746984F7078B76BDE5AB11C2BE3B60 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( + B490E7485944099E16C9CBD79119D1D4 /* IQKeyboardManagerSwift */, + 982A68D37F5DCBC1FC1FDC0BB2F0EB8E /* IQKeyboardManagerSwift-IQKeyboardManagerSwift */, 75F1EA88CB9544AB5CBE20DEC9A011AE /* LanguageManager-iOS */, 4372AB6A3C495222906A1ABFD39A4463 /* Pods-MiniScanner */, ); @@ -279,6 +549,14 @@ /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 1F6536881239A8473B02B921C14549E4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 670310D98A231B664F5C424035D37B24 /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 3B58EC4259531E84AFA63D59D1133D3E /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -286,7 +564,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 41C60577E673C501BA87D47FD416DC0D /* Resources */ = { + 4A72A323CCD420112722EDFB4439C184 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CDBAE55660ED186441E9E4EDE6B3D31 /* IQKeyboardManagerSwift-IQKeyboardManagerSwift in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B2D3F813B90BA06914DE6D3D710B9BFA /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -296,11 +582,61 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 8A2C45DB9ED445D641C1976833472DC7 /* Sources */ = { + 335F86AE3E21D4BDAD21A4F79F2DA8F9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B1BFC54288364884DDEAE75027BABE1A /* IQActiveConfiguration.swift in Sources */, + 8ED2E941DF0803C8AA331D0D8C722615 /* IQBarButtonItem.swift in Sources */, + 907FCA3049CAAF64B579D08D339D118D /* IQBarButtonItemConfiguration.swift in Sources */, + FDEFBFB34E35A4BB332264E0CACCF5D8 /* IQInvocation.swift in Sources */, + 9A00A25ED34A7687C62B02EBB76C1248 /* IQKeyboardConfiguration.swift in Sources */, + 24C699F9653980B77F44634EF44641C1 /* IQKeyboardInfo.swift in Sources */, + 8FDA28363A5E49017498FD69AAA8F59F /* IQKeyboardListener.swift in Sources */, + F9DE1A3C506E506F4DA4B7714359E8D1 /* IQKeyboardManager.swift in Sources */, + 674C6B2E317E657D8EAD3CC73F608540 /* IQKeyboardManager+Debug.swift in Sources */, + D3D1F63C30E95311B687FA924B872C15 /* IQKeyboardManager+Deprecated.swift in Sources */, + 08822D4E49DB8618D27BAEDED7911733 /* IQKeyboardManager+Internal.swift in Sources */, + EBB5F245DBEEB13D48F09E0DD75A6C95 /* IQKeyboardManager+Position.swift in Sources */, + D88C2EA8ACCC0DE031D9E7A768062E2C /* IQKeyboardManager+Toolbar.swift in Sources */, + 9F78D56352F7D932DCEBE416C668C7BA /* IQKeyboardManager+ToolbarActions.swift in Sources */, + 4017CF2B3EE45E7E579E68E6FCFBF732 /* IQKeyboardManager+UIKeyboardNotification.swift in Sources */, + 82950EE4BDD57F74749742A3E1566073 /* IQKeyboardManager+UITextFieldViewNotification.swift in Sources */, + 597994C3AE8908B1E462BC03AC8C23FB /* IQKeyboardManagerCompatible.swift in Sources */, + AE7D065E1D48171258FD8F07F7CD592C /* IQKeyboardManagerConstants.swift in Sources */, + 733CF7F19636AFF4A97708DFDE0AE53C /* IQKeyboardManagerSwift-dummy.m in Sources */, + 42B931814C7B25871333D5DA9A0E2A41 /* IQKeyboardReturnKeyHandler.swift in Sources */, + 154362EFC8EC0F61F54E24B09266DEB1 /* IQKeyboardReturnKeyHandler+TextFieldDelegate.swift in Sources */, + 1C3881B0113D3219398154E16AA4413C /* IQKeyboardReturnKeyHandler+TextViewDelegate.swift in Sources */, + 54BAE903D82C39392943869866252D93 /* IQNSArray+Sort.swift in Sources */, + 5F0469C5B154DC20B844EA2A9B7F8D42 /* IQPlaceholderable.swift in Sources */, + 14063E1AF70EDDC9F33C8E08DCA0BEF3 /* IQPreviousNextView.swift in Sources */, + DE3B5070A41194C21898D92DBFFCBE4C /* IQRootControllerConfiguration.swift in Sources */, + F681FB74C756E0AAFFDC0D414EBD8FA0 /* IQScrollViewConfiguration.swift in Sources */, + 0615219BFD2EBBE27FF41C2C8816791E /* IQTextFieldViewInfo.swift in Sources */, + 5F62DAE67CF97B7C42471EA91B79AA9A /* IQTextFieldViewInfoModel.swift in Sources */, + 0A4DB572ACD97EC492C4E93A0FFB2E47 /* IQTextFieldViewListener.swift in Sources */, + 38CBE3196BDD577B5E72BC65508A77F8 /* IQTextView.swift in Sources */, + B9CF878085ABA2991A9C6F12F9B9DAB3 /* IQTitleBarButtonItem.swift in Sources */, + 701904768C60A3F9060518DD58EC2882 /* IQToolbar.swift in Sources */, + E8770A941545BB190D76BF7E5262797D /* IQToolbarConfiguration.swift in Sources */, + 34BDB069A96125DAF2FEF6FF93A3F6AF /* IQToolbarPlaceholderConfiguration.swift in Sources */, + 3452528F3B9B79AD67D45FEA174F71E4 /* IQUICollectionView+Additions.swift in Sources */, + 94F893223EB4C1C0F829C17900114AFA /* IQUIScrollView+Additions.swift in Sources */, + A5E69CC013C4311C8AF52C7F7AB095C9 /* IQUITableView+Additions.swift in Sources */, + 8086BD2DB5F1A0CC88E4F3386570A21C /* IQUITextFieldView+Additions.swift in Sources */, + 103FE4EEFF1BE8BAD0FA047987AFED74 /* IQUIView+Hierarchy.swift in Sources */, + D8322CBE73400EE4382D1A042D2D53D3 /* IQUIView+IQKeyboardToolbar.swift in Sources */, + 08C234F2981017EEF271582022F339F3 /* IQUIView+IQKeyboardToolbarDeprecated.swift in Sources */, + CC96488C33BFB3BCEE4A665A438CAC36 /* IQUIViewController+Additions.swift in Sources */, + E483FA24409A56AAEDF8A1DEC5F55F16 /* UIImage+NextPrevious.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8FE0832F0DF382FA18A5D3CADD1B6351 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 64484197CAEC8EED5DA42F253B6B342F /* Pods-MiniScanner-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -322,22 +658,44 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + F9C75295AA740325086A3FCA7458D3EE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 09936CDBB25F81CCBD0688CA34E025A1 /* Pods-MiniScanner-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 1E2DC51A6663DD85438DF52518053178 /* PBXTargetDependency */ = { + 70B394A376C36F5FD5FB14290629A6AF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = IQKeyboardManagerSwift; + target = B490E7485944099E16C9CBD79119D1D4 /* IQKeyboardManagerSwift */; + targetProxy = 08906A1E152B2EBD296D726C4A00627E /* PBXContainerItemProxy */; + }; + 9E5E0442EF5E505708CA6D618C31E468 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = "LanguageManager-iOS"; target = 75F1EA88CB9544AB5CBE20DEC9A011AE /* LanguageManager-iOS */; - targetProxy = 4DD7884B512AC0A832BF2E14C2F07FC2 /* PBXContainerItemProxy */; + targetProxy = AA24290BD2F66F452D4FA8715BB9C199 /* PBXContainerItemProxy */; + }; + DFFDC8AC6E79C759B3548C41CB3F7C76 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "IQKeyboardManagerSwift-IQKeyboardManagerSwift"; + target = 982A68D37F5DCBC1FC1FDC0BB2F0EB8E /* IQKeyboardManagerSwift-IQKeyboardManagerSwift */; + targetProxy = F68B8DE02DB8CE82221ED42882AEACDB /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 39440596D0B39AE8ECC2717121684FEC /* Release */ = { + 035F84A1BCB1A82A26F689D69C9D9305 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 229E7A3D5222D6F61C14A0F5D81ED987 /* LanguageManager-iOS.release.xcconfig */; + baseConfigurationReference = 7CC191E7994C3C7161A6641B457C9166 /* Pods-MiniScanner.debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -346,35 +704,67 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/LanguageManager-iOS/LanguageManager-iOS-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/LanguageManager-iOS/LanguageManager-iOS-Info.plist"; + INFOPLIST_FILE = "Target Support Files/Pods-MiniScanner/Pods-MiniScanner-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MODULEMAP_FILE = "Target Support Files/LanguageManager-iOS/LanguageManager-iOS.modulemap"; - PRODUCT_MODULE_NAME = LanguageManager_iOS; - PRODUCT_NAME = LanguageManager_iOS; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-MiniScanner/Pods-MiniScanner.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; + name = Debug; + }; + 06630286ACD25B254ED4B6A940E09315 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F97F62F12C7D10E03540793DDD57009B /* IQKeyboardManagerSwift.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/IQKeyboardManagerSwift"; + IBSC_MODULE = IQKeyboardManagerSwift; + INFOPLIST_FILE = "Target Support Files/IQKeyboardManagerSwift/ResourceBundle-IQKeyboardManagerSwift-IQKeyboardManagerSwift-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + PRODUCT_NAME = IQKeyboardManagerSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 216CD1C47D4C136E982A8F1B2092B21C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 22FF8311D744FA0C5E23B24C7AE67B1D /* IQKeyboardManagerSwift.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/IQKeyboardManagerSwift"; + IBSC_MODULE = IQKeyboardManagerSwift; + INFOPLIST_FILE = "Target Support Files/IQKeyboardManagerSwift/ResourceBundle-IQKeyboardManagerSwift-IQKeyboardManagerSwift-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + PRODUCT_NAME = IQKeyboardManagerSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; name = Release; }; - 695DE66A04B5C2E768CF22F8AE139AFB /* Debug */ = { + 39440596D0B39AE8ECC2717121684FEC /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7CC191E7994C3C7161A6641B457C9166 /* Pods-MiniScanner.debug.xcconfig */; + baseConfigurationReference = 447CF01CBF4066825019B2CBB67AEBDF /* LanguageManager-iOS.release.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -383,30 +773,30 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-MiniScanner/Pods-MiniScanner-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/LanguageManager-iOS/LanguageManager-iOS-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/LanguageManager-iOS/LanguageManager-iOS-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-MiniScanner/Pods-MiniScanner.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + MODULEMAP_FILE = "Target Support Files/LanguageManager-iOS/LanguageManager-iOS.modulemap"; + PRODUCT_MODULE_NAME = LanguageManager_iOS; + PRODUCT_NAME = LanguageManager_iOS; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; + name = Release; }; - 7F0A375D6344ACFC096C1061D7F3628B /* Release */ = { + 7E523A73C8A76E5E9774BEAAEEA1D69D /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 798C61760B9BC4B07BC60D42FCC09855 /* Pods-MiniScanner.release.xcconfig */; buildSettings = { @@ -574,7 +964,7 @@ }; A73A28CEE205ACFB6072250615C7D39D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 260B9319B575951CF8E8007D061EAE1C /* LanguageManager-iOS.debug.xcconfig */; + baseConfigurationReference = ED153F395FC11B265453987CD5F97492 /* LanguageManager-iOS.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -606,9 +996,98 @@ }; name = Debug; }; + B3CF11682A60F02B60820C17EE93D35E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F97F62F12C7D10E03540793DDD57009B /* IQKeyboardManagerSwift.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.modulemap"; + PRODUCT_MODULE_NAME = IQKeyboardManagerSwift; + PRODUCT_NAME = IQKeyboardManagerSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.9; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + C15C4E31ADF19556825A2743AEF62A77 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 22FF8311D744FA0C5E23B24C7AE67B1D /* IQKeyboardManagerSwift.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.modulemap"; + PRODUCT_MODULE_NAME = IQKeyboardManagerSwift; + PRODUCT_NAME = IQKeyboardManagerSwift; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.9; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 04D5557B7DEECE0FC64F5301035A4CC3 /* Build configuration list for PBXNativeTarget "Pods-MiniScanner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 035F84A1BCB1A82A26F689D69C9D9305 /* Debug */, + 7E523A73C8A76E5E9774BEAAEEA1D69D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 397157E58CC1977C23EB745CC0C04035 /* Build configuration list for PBXNativeTarget "IQKeyboardManagerSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B3CF11682A60F02B60820C17EE93D35E /* Debug */, + C15C4E31ADF19556825A2743AEF62A77 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 3E005A95330A065B56DC3405DE620CD6 /* Build configuration list for PBXNativeTarget "LanguageManager-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -627,11 +1106,11 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 6F6CE1FB7DDC767B55B89C1A2DFBC636 /* Build configuration list for PBXNativeTarget "Pods-MiniScanner" */ = { + F355D0811AB05A75A0C8E6107F95470A /* Build configuration list for PBXNativeTarget "IQKeyboardManagerSwift-IQKeyboardManagerSwift" */ = { isa = XCConfigurationList; buildConfigurations = ( - 695DE66A04B5C2E768CF22F8AE139AFB /* Debug */, - 7F0A375D6344ACFC096C1061D7F3628B /* Release */, + 06630286ACD25B254ED4B6A940E09315 /* Debug */, + 216CD1C47D4C136E982A8F1B2092B21C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Pods/Pods.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/IQKeyboardManagerSwift-IQKeyboardManagerSwift.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/IQKeyboardManagerSwift-IQKeyboardManagerSwift.xcscheme new file mode 100644 index 0000000..4a29221 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/IQKeyboardManagerSwift-IQKeyboardManagerSwift.xcscheme @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "1500" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + <BuildActionEntries> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "982A68D37F5DCBC1FC1FDC0BB2F0EB8E" + BuildableName = "IQKeyboardManagerSwift.bundle" + BlueprintName = "IQKeyboardManagerSwift-IQKeyboardManagerSwift" + ReferencedContainer = "container:Pods.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + </BuildActionEntries> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES"> + <Testables> + </Testables> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/Pods/Pods.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/IQKeyboardManagerSwift.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/IQKeyboardManagerSwift.xcscheme new file mode 100644 index 0000000..78a923d --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/IQKeyboardManagerSwift.xcscheme @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "1500" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + <BuildActionEntries> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "B490E7485944099E16C9CBD79119D1D4" + BuildableName = "IQKeyboardManagerSwift.framework" + BlueprintName = "IQKeyboardManagerSwift" + ReferencedContainer = "container:Pods.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + </BuildActionEntries> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES"> + <Testables> + </Testables> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/Pods/Pods.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/xcschememanagement.plist b/Pods/Pods.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/xcschememanagement.plist index 911616b..d372514 100644 --- a/Pods/Pods.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Pods/Pods.xcodeproj/xcuserdata/g.makhoul.xcuserdatad/xcschemes/xcschememanagement.plist @@ -4,19 +4,33 @@ <dict> <key>SchemeUserState</key> <dict> - <key>LanguageManager-iOS.xcscheme</key> + <key>IQKeyboardManagerSwift-IQKeyboardManagerSwift.xcscheme</key> + <dict> + <key>isShown</key> + <false/> + <key>orderHint</key> + <integer>1</integer> + </dict> + <key>IQKeyboardManagerSwift.xcscheme</key> <dict> <key>isShown</key> <false/> <key>orderHint</key> <integer>0</integer> </dict> + <key>LanguageManager-iOS.xcscheme</key> + <dict> + <key>isShown</key> + <false/> + <key>orderHint</key> + <integer>2</integer> + </dict> <key>Pods-MiniScanner.xcscheme</key> <dict> <key>isShown</key> <false/> <key>orderHint</key> - <integer>1</integer> + <integer>3</integer> </dict> </dict> <key>SuppressBuildableAutocreation</key> diff --git a/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist new file mode 100644 index 0000000..1281ca3 --- /dev/null +++ b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>${PODS_DEVELOPMENT_LANGUAGE}</string> + <key>CFBundleExecutable</key> + <string>${EXECUTABLE_NAME}</string> + <key>CFBundleIdentifier</key> + <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundlePackageType</key> + <string>FMWK</string> + <key>CFBundleShortVersionString</key> + <string>7.0.3</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>${CURRENT_PROJECT_VERSION}</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-dummy.m b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-dummy.m new file mode 100644 index 0000000..7937f27 --- /dev/null +++ b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-dummy.m @@ -0,0 +1,5 @@ +#import <Foundation/Foundation.h> +@interface PodsDummy_IQKeyboardManagerSwift : NSObject +@end +@implementation PodsDummy_IQKeyboardManagerSwift +@end diff --git a/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import <UIKit/UIKit.h> +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-umbrella.h b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-umbrella.h new file mode 100644 index 0000000..e95b398 --- /dev/null +++ b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import <UIKit/UIKit.h> +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double IQKeyboardManagerSwiftVersionNumber; +FOUNDATION_EXPORT const unsigned char IQKeyboardManagerSwiftVersionString[]; + diff --git a/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.debug.xcconfig b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.debug.xcconfig new file mode 100644 index 0000000..1472651 --- /dev/null +++ b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift +OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -framework "CoreGraphics" -framework "Foundation" -framework "QuartzCore" -framework "UIKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/IQKeyboardManagerSwift +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.modulemap b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.modulemap new file mode 100644 index 0000000..6d9b343 --- /dev/null +++ b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.modulemap @@ -0,0 +1,6 @@ +framework module IQKeyboardManagerSwift { + umbrella header "IQKeyboardManagerSwift-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.release.xcconfig b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.release.xcconfig new file mode 100644 index 0000000..1472651 --- /dev/null +++ b/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift +OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -framework "CoreGraphics" -framework "Foundation" -framework "QuartzCore" -framework "UIKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/IQKeyboardManagerSwift +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/IQKeyboardManagerSwift/ResourceBundle-IQKeyboardManagerSwift-IQKeyboardManagerSwift-Info.plist b/Pods/Target Support Files/IQKeyboardManagerSwift/ResourceBundle-IQKeyboardManagerSwift-IQKeyboardManagerSwift-Info.plist new file mode 100644 index 0000000..394246f --- /dev/null +++ b/Pods/Target Support Files/IQKeyboardManagerSwift/ResourceBundle-IQKeyboardManagerSwift-IQKeyboardManagerSwift-Info.plist @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>${PODS_DEVELOPMENT_LANGUAGE}</string> + <key>CFBundleIdentifier</key> + <string>${PRODUCT_BUNDLE_IDENTIFIER}</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>7.0.3</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-acknowledgements.markdown b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-acknowledgements.markdown index 48594d5..32c972d 100644 --- a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-acknowledgements.markdown @@ -1,6 +1,31 @@ # Acknowledgements This application makes use of the following third party libraries: +## IQKeyboardManagerSwift + +MIT License + +Copyright (c) 2013-2023 Iftekhar Qurashi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + ## LanguageManager-iOS The MIT License (MIT) diff --git a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-acknowledgements.plist b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-acknowledgements.plist index 52c3891..e207ac5 100644 --- a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-acknowledgements.plist @@ -12,6 +12,37 @@ <key>Type</key> <string>PSGroupSpecifier</string> </dict> + <dict> + <key>FooterText</key> + <string>MIT License + +Copyright (c) 2013-2023 Iftekhar Qurashi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +</string> + <key>License</key> + <string>MIT</string> + <key>Title</key> + <string>IQKeyboardManagerSwift</string> + <key>Type</key> + <string>PSGroupSpecifier</string> + </dict> <dict> <key>FooterText</key> <string>The MIT License (MIT) diff --git a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Debug-input-files.xcfilelist b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Debug-input-files.xcfilelist index 6d9163b..5cbf342 100644 --- a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Debug-input-files.xcfilelist +++ b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Debug-input-files.xcfilelist @@ -1,2 +1,3 @@ ${PODS_ROOT}/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks.sh +${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework ${BUILT_PRODUCTS_DIR}/LanguageManager-iOS/LanguageManager_iOS.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Debug-output-files.xcfilelist b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Debug-output-files.xcfilelist index c2f68ee..7565786 100644 --- a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Debug-output-files.xcfilelist +++ b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Debug-output-files.xcfilelist @@ -1 +1,2 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LanguageManager_iOS.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Release-input-files.xcfilelist b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Release-input-files.xcfilelist index 6d9163b..5cbf342 100644 --- a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Release-input-files.xcfilelist +++ b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Release-input-files.xcfilelist @@ -1,2 +1,3 @@ ${PODS_ROOT}/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks.sh +${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework ${BUILT_PRODUCTS_DIR}/LanguageManager-iOS/LanguageManager_iOS.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Release-output-files.xcfilelist b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Release-output-files.xcfilelist index c2f68ee..7565786 100644 --- a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Release-output-files.xcfilelist +++ b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks-Release-output-files.xcfilelist @@ -1 +1,2 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LanguageManager_iOS.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks.sh b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks.sh index 06343c7..1992d7c 100755 --- a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks.sh +++ b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner-frameworks.sh @@ -176,9 +176,11 @@ code_sign_if_enabled() { } if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework" install_framework "${BUILT_PRODUCTS_DIR}/LanguageManager-iOS/LanguageManager_iOS.framework" fi if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework" install_framework "${BUILT_PRODUCTS_DIR}/LanguageManager-iOS/LanguageManager_iOS.framework" fi if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then diff --git a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner.debug.xcconfig b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner.debug.xcconfig index b10d8e5..08a867f 100644 --- a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner.debug.xcconfig +++ b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner.debug.xcconfig @@ -1,11 +1,11 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LanguageManager-iOS" +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/LanguageManager-iOS" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LanguageManager-iOS/LanguageManager_iOS.framework/Headers" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/LanguageManager-iOS/LanguageManager_iOS.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' -LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift -OTHER_LDFLAGS = $(inherited) -framework "LanguageManager_iOS" +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift +OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "LanguageManager_iOS" -framework "QuartzCore" -framework "UIKit" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) diff --git a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner.release.xcconfig b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner.release.xcconfig index b10d8e5..08a867f 100644 --- a/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner.release.xcconfig +++ b/Pods/Target Support Files/Pods-MiniScanner/Pods-MiniScanner.release.xcconfig @@ -1,11 +1,11 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LanguageManager-iOS" +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/LanguageManager-iOS" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LanguageManager-iOS/LanguageManager_iOS.framework/Headers" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/LanguageManager-iOS/LanguageManager_iOS.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' -LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift -OTHER_LDFLAGS = $(inherited) -framework "LanguageManager_iOS" +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift $(SDKROOT)/usr/lib/swift +OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "LanguageManager_iOS" -framework "QuartzCore" -framework "UIKit" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) -- GitLab