diff --git a/.DS_Store b/.DS_Store index d96b22ba810b27d9169f0bea2509d58baae38c49..cf3157b6c369e2bd71d6f12e9c47e7d83e655f1c 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/MiniScanner.xcodeproj/project.pbxproj b/MiniScanner.xcodeproj/project.pbxproj index 3240794acac925012867876a22e4a6a2ca22684c..c0cab02e385f07d97835ed8f2c32cf371e6559ee 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 967e65e7b7d230c9cb69b8fb75b25fe515d2522c..638d735805511f6ca3f6a4ed3d89968fa1ceffed 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 Binary files a/MiniScanner.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate and b/MiniScanner.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/MiniScanner/.DS_Store b/MiniScanner/.DS_Store index 43430360f8b127aad2173de282fcc5f246d7831b..acf156a5b4057310c05955f3ceb8d582dcd6e107 100644 Binary files a/MiniScanner/.DS_Store and b/MiniScanner/.DS_Store differ diff --git a/MiniScanner/Extensions/UIButton+Extensions.swift b/MiniScanner/Extensions/UIButton+Extensions.swift new file mode 100644 index 0000000000000000000000000000000000000000..0d904e8b4ab8f37a0deadf1bba70810cba5c88f2 --- /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 93395b7e6a6d0c6a955c69f2470e02ceefdb20ee..36d5f8ae356cbfce5dd9c1b7f4cd289e0b219a8c 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 0000000000000000000000000000000000000000..08697e141c2ed9ab643ebe619e64262af4dabd7c --- /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 0000000000000000000000000000000000000000..c785d14c9569bc9f88514b58fe79596fe7c596b5 --- /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 0000000000000000000000000000000000000000..5d3c6de754fd31cbd3d6c537b1952026d1f505f3 --- /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 Binary files a/MiniScanner/Modules/.DS_Store and b/MiniScanner/Modules/.DS_Store differ diff --git a/MiniScanner/Modules/Documents/.DS_Store b/MiniScanner/Modules/Documents/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c8909fced09ac5e392e8dea117008b5b770b46d4 Binary files /dev/null and b/MiniScanner/Modules/Documents/.DS_Store differ 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 d52dbd724c29197d74d8b5a462cb764e8ce9bdd0..f13ef36d87ba70ed8427267854e7ba00626b8a14 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 919a9b78255c45b86fb73bb6807c749bf6682888..90947360347b7d04b6746e913f83f92dabcaaa43 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 0000000000000000000000000000000000000000..79ca6be93f50bd9e31c368fc987e6e69d12a3055 --- /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 0000000000000000000000000000000000000000..1af52651c0811025a28c9953abb4c9eaf25115c6 --- /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 0000000000000000000000000000000000000000..4be47b2e9e0c63026f6cd6284b1d6dba7fb10fd5 --- /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 0000000000000000000000000000000000000000..fab189021b517264261973fe429610303030269f --- /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 392273d1ac7368693c78d2f9f3fad8f80aa82e1d..4ca2ef5fbd50f13cd6c3742dc273a330e53fdad1 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 cbf4b61ac272c711b0f05ce97cbbc11012cd18b6..9cedbe365a5aa5f01c69f23f542b0e3aec670f33 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 Binary files a/MiniScanner/Supporting Files/.DS_Store and b/MiniScanner/Supporting Files/.DS_Store differ diff --git a/MiniScanner/Supporting Files/AppDelegate.swift b/MiniScanner/Supporting Files/AppDelegate.swift index b9fea47e28e79fd26f6f2102e644b82847475b1f..c06e46735e19a8aeaaf2c4d854c68629ba901459 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 0000000000000000000000000000000000000000..db8d02fdecfd961b1cbe8cdf933b0ce1e2b2bf39 --- /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 0000000000000000000000000000000000000000..39291a24b722f0193fc2501c1b2d6d1244a30c32 --- /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 0000000000000000000000000000000000000000..8fbac3d33c4262315a8cc55acab1faffe0a777a4 --- /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 0000000000000000000000000000000000000000..258ff3bc17242596ed29fee8c189427c8bd0e516 --- /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 0000000000000000000000000000000000000000..690ad6df684689e3947f7d2e68b40f8bb5ab0939 --- /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 114e943ae5102f7086baa862b6fac644e1b05e68..8803dd298d15be66d84f2227276c076ccf62ef9d 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 913eeddfa19742652c823b0ac5c8768a19d19132..e3f77d72e1a7f27afac22a9f490be7155c70fe16 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 0000000000000000000000000000000000000000..ef0b892ac4f1838bd828e2ff2d54fdc1e74b8330 --- /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 0000000000000000000000000000000000000000..9377c017f318b25c564e157eb1d1613ad8256a87 --- /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 0000000000000000000000000000000000000000..653bc2c553da0f9e8dcefa0ce328405c8a023e17 --- /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 0000000000000000000000000000000000000000..93aba8c64d8b0fa904678e81a07a71df25e0ea7b --- /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 0000000000000000000000000000000000000000..49f6f16c3c0884c9278a6ca1a9a3f70f6f33d978 --- /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 0000000000000000000000000000000000000000..3c6244baabe6da702a3a80a407778b4869fc30e4 --- /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 0000000000000000000000000000000000000000..5ee43870474644a57b5a1b17e15f6c73a2bd6c43 --- /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 0000000000000000000000000000000000000000..a3aac5c68de2cc9dd9d7671cc6539afefaeb96fc --- /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 0000000000000000000000000000000000000000..43df95fd8ac6167d6a3db3ed57da747da1eb3a8e --- /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 0000000000000000000000000000000000000000..c2cef98cd5311c570c9dcd8386c429a2f0a2226c --- /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 0000000000000000000000000000000000000000..36a18746d9134a8336453a9fec977ab042c3d858 --- /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 0000000000000000000000000000000000000000..d76cb9d98c1838005e8a7ef012619f193f7dc59b --- /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 0000000000000000000000000000000000000000..a7b1791967c00dc3391b2f6873f1a661400b6b64 --- /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 0000000000000000000000000000000000000000..5b01190ea27dd23a8754c0c4c37bb9e18b0c98d6 --- /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 0000000000000000000000000000000000000000..3850630e649e5fd2870b40497d811ca887772b8d --- /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 0000000000000000000000000000000000000000..676a8bc0ea642fda64ee774d050f39eaf588e1a0 --- /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 0000000000000000000000000000000000000000..eeaca4b3eb59080373c3a9f761f6c6f80d7888cb --- /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 0000000000000000000000000000000000000000..d4bad3c45adf933d3260422cb0db8431add771c1 --- /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 0000000000000000000000000000000000000000..e8f71882d5cb83431a7b1ef696ee63849df1cec8 --- /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 0000000000000000000000000000000000000000..b4e5216bec22e85d229a3f316c552e47bf05769e --- /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 0000000000000000000000000000000000000000..52af9ccbf95ea9f83d277c63cdd873776153545d --- /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 0000000000000000000000000000000000000000..2ba446a098106720c6fd9d43f5e9cadec57d2930 --- /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 0000000000000000000000000000000000000000..d841752a1aa099503125a49c787bfde35f67c012 --- /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 0000000000000000000000000000000000000000..9c969d3f7f7afa24f67dd8eebaf3ab28dad83602 --- /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 0000000000000000000000000000000000000000..65d692ca4d590812d9b2c4207b18df87eb195bc3 --- /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 0000000000000000000000000000000000000000..b9ae6b11b53fd7e07c897d176fc2e6d1f0341c42 --- /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 0000000000000000000000000000000000000000..9437935b1f7b84fe2cd23a7cf3d477b808210139 --- /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 0000000000000000000000000000000000000000..b0e53a38c3b3c8afc4345021c7d42314fceaa514 --- /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 0000000000000000000000000000000000000000..7718e81b113a274faef295e0e490db35339758f1 --- /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 0000000000000000000000000000000000000000..b06a473ee58fdf6b40fc544fc51eb0c4e5f02bcf --- /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 0000000000000000000000000000000000000000..eb0eaf6a0eee04a06ecf7ed8729a6a27372aff1f --- /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 0000000000000000000000000000000000000000..90211906c1b81fb9357741321167370068497009 --- /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 0000000000000000000000000000000000000000..8cc195fa8e6e5da4de18245ff1bed0946ccd6ba2 --- /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 0000000000000000000000000000000000000000..6519cc396a16c2387291d6654c4939e31e5a12b6 --- /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 0000000000000000000000000000000000000000..f1a4efecaf1a64f51762df8947bd4a2e5df555d0 --- /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 0000000000000000000000000000000000000000..562c99c360dc5b3e27825cd61338098ae02b8a4f --- /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 0000000000000000000000000000000000000000..24c542a6e7b6ca6f7c20024320a293260ca71547 --- /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 0000000000000000000000000000000000000000..7da92eaf39e03c43c4191e36e6c76ffb8e0aa95a --- /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 0000000000000000000000000000000000000000..8b8753fbd4d7bea56920a3eb08f450e26807595c --- /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 0000000000000000000000000000000000000000..022a94d6f42a0540110b9149b4940e7885e1e159 --- /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 0000000000000000000000000000000000000000..d108f9669e6e20040f64cc2dd79b5f6b728d9b1e --- /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 0000000000000000000000000000000000000000..907f51f9eacb868bf655ddb68d1d13f19c4c6f04 --- /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 0000000000000000000000000000000000000000..7bd0792fca5735055fcd2c9c0921cb2a0119ca81 --- /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 0000000000000000000000000000000000000000..fe1d1a11f583e080d3d839932d7408d72d26df4e --- /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 = "iVBORw0KGgoAAAANSUhEUgAAAD8AAAAkCAYAAAA+TuKHAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABWWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpMwidZAAAGmklEQVRoBd1ZWWwbRRie2bVz27s2adPGxzqxqAQCIRA3CDVJGxpKaEtRoSAVISQQggdeQIIHeIAHkOCBFyQeKlARhaYHvUJa0ksVoIgKUKFqKWqdeG2nR1Lsdeo0h73D54iku7NO6ySOk3alyPN//+zM/81/7MyEkDl66j2eJXWK8vocTT82rTgXk/t8vqBNEI9QSp9zOeVkPJnomgs7ik5eUZQ6OxGOEEq9WcKUksdlWbqU0LRfi70ARSXv8Xi8dkE8CsJ+I1FK6BNYgCgW4A8jPtvtopFHqNeWCLbDIF6fkxQjK91O1z9IgRM59bMAFoV8YEFgka1EyBJfMhkH5L9ACFstS9IpRMDJyfoVEp918sGamoVCme0QyN3GG87wAKcTOBYA4hrJKf+VSCb+nsBnqYHVnr2ntra2mpWWH0BVu52fhRH2XSZDmsA/xensokC21Pv9T3J4wcWrq17gob1er7tEhMcJuYsfGoS3hdTweuBpxaM0iCJph8fLuX7DJMPWnI2GOzi8YOKseD4gB+RSQezMRRx5vRPEn88Sz7IIx8KHgT3FCBniWJUyke6o8/uXc3jBxIKTd7vdTsFJfkSo38NbCY/vPRsOPwt81KgLqeoBXc+sBjZsxLF4ZfgM7goqSqMRL1S7oOSrq6sdLodjH0rYfbyByPEOePwZ4CO8Liv3RCL70Wctr8+mA2NkT53P91iu92aCFYx8TU1NpbOi8gfs2R7iDYLxnXqYPg3c5Fm+Xygcbs/omXXATZGBBagQqNAe9Psf4d+ZiVwQ8qjqFVVl5dmi9ShvDEL90IieXtVDevic5ruOyYiAXYiA9YSxsZow0YnSKkKFjoAn8OAENsPGjKs9qnp5iSDuBXFLXsLjR4fSIy29vb2DU7UThW4d8n0zxjXtRVAYNaJnlocikWNTHZPvP1PPl2LLujM3cfbzwJXUyukQzxrZraptRCcbEDm60Wh4S0IE7McByVJQjf3yac+EfEm9ouxAcWu2TsS6koOplr6+vstWXf5IKBrejBR4ybIAlLpE1JE6j8eyh8h/dEKmS95e7w9sy57G+MkQ6sdYMrmiv79/gNdNR0YEbGKUvIIFQMRffRBtbkG0HQj6fHdcRafWmg55Gzy+BR5vtUzF2O96kjSH4nHNopsB0B0Ob6SEvcYvAPYS1UwQDyqLFcu5IZ/pTMUkjxfEoD/wLVY9+z02PXDL8RE9s0y9qMZNigIJcU37TZblfj7aUAMqURLXuqqq9sQHBi5NZbqpkBfh8a9BPLtDMz3wyImh9GhTLBab0uSmQfIQcNQ95pJkDVG3wtgdC1KFA+HaSodjdzKZ/Neou1Y7X/JC0K98BeIvWAdjp+jwUKN6/nyfVVd4JK4lunDrkwJhc6Gl1GGjwhqnLO3UNC2Rz8z5kKfw+EYQf5EfEKF+Wh+kDd0XYxd43WzKiIBfEAEjiIAm0zyUSFiU1XJF+feJy5evW3euR57C41+A+MumSbICY2dGmd6gnlPPWXRFABABP7llCXsA2mCcDjVAJoK4qryycsfAwEDSqOPb1yQPj38O4q/yL4F4aCiTXhqNRmMWXREBFMGjslOywUbToQeyyy4IrVVO53bUgEk/uZOSr/MHPsOd0hs8F4R6mI2ONKi9vRFeNxdyIqkddknOMhA2nyuy+wAqtEol8rbEYCLnZisneXj8UxB/00KGkUiGsqU90WiPRTeHACLgoNsp4eBDHzaagRS4RbCzle6ysq3xVIq/LiMW8ti5fYRVfMs4yFibsdgI05eqqhqy6OYBEE9qnSiCLhRB7tRHFzDR1oIasBU1wHTAMpHHjcmHIP4OzwXf8XMkk24IR6NneN18klEE97mc0gJwuN9oF+SFNlF8vNJR1YYacGVcN0Eet6XvY6Pw3rhi/Bc5fiEzShp7eiOnx7H5/IsI6EAELEIE3Gu0EymwyCbQZocktWEfMHa3MEa+zqe8KwjCB8bO/7f70kxvVGPqyRy6eQshAtpdsuTDN/9us5F0MQ4zTS5BaIsPDQ3jO+5/G+fjj82dIDF2CZeKjd3R6J8W3Y0BYFca+JJQssFqLuvSUqlmESHSiZywGzsgx+OZNFnWE4scN+I3WJshAnYjAm5FBNxptp16y+y2hICLEtOVMXJcI0xvDveGi/ofU7NxBZN0XIpuIIy0mUZkZNNZVf1kDAt6lZagEhjGnxbweh8wdbw5hOwdxHbwY/j9BpTM9xi4MGzFvZhpk3Bz8J5gkb19ym7cJr5w/wEmUjzJqoNVhwAAAABJRU5ErkJggg==" + // 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 = "iVBORw0KGgoAAAANSUhEUgAAAD8AAAAkCAYAAAA+TuKHAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABWWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpMwidZAAAGp0lEQVRoBd1ZCWhcRRiemff25WrydmOtuXbfZlMo4lEpKkppm6TpZUovC4UqKlQoUhURqQcUBcWDIkhVUCuI9SpJa+2h0VZjUawUEUUUirLNXqmxSnc32WaT7O4bv0nd5R1bc+2maR8s7z9m5v+/+f/5Z94sIf89jW73Yp/bfUuWvwLfDp/H8zhwObLYmCCaPJ6FjLJPCWNHNU1bkFVeQW/Zp2l7KWUvNmlaB3DJAhvz1ntvI5R1EUpnUUKdEifHGuvr519BwKUmj/cDYNtwARNd5/NoH4GWKIhzlFKXCSzn/xCut/jD4V9N8suPYYj4ewC+2e46f55Rwp/geExKSmdzJn2l1WrXmuSXF8MQ8XfyAeeEn9KTyV3MHwq9RTh50IqLEjJHUkh3Y13dPKvuMuApIr6bUHKP1VeE+Y8MIa09Z8/+JQlltD/+Q7VaFcW6X2VsjFmbRRnbUFFZeai/v/+cUTeDaYqIv4GlfL/NR879I3qmORwOnxG6UfCCiMbjJ51VagKdlgs+91BaKVO6oVJVD8bj8WhOPkMJn1t7jTL6gNU9pHpgKJ1q7u3tjWR1OfBCEOuPf+9Sq4YwAW3ZBqNvSqsYpeuc5WUHYolE3KSbQYzP430FwB+yuoSCFtKHaXP4z3DIqDOBFwpkwHfVThXLgrYaG6IGOAmT1pZVVHw8MDDQb9TNBLrJre0E8EdtvnAeSRPeHOwN9lh1NvCiASbgG5fqRLDJEmMHsSU6GFuDGrAfNWDAqLuUNE5uL6A2bbf5wPkZrmdaAuGw36aDIC940TAajx1HBijIgEWmjpRWS4ytrnKq+1EDEibdJWAa3dqzjLGnrKaxxvt4OtXS09v7u1WX5S8KXjRABnQ7VbUCEV+Y7SDeWAJX4dfuLCnZFzt//rxRN500jqo74NvTVptY42fTnLcGI5FTVp2R/1/womEsHj/mwgxg27vd2BH8bCrLq0rKyjoTicSgUTcdNIrbkwD+nM2WOJ3qmaVI9d9sOotgTPCiPTLgi+oqdTbOAbea+lM6xyHLK8pnVXSiCCZNuiIyjZr2GArSS1YTOKie45n0UqT6L1ZdPn5c4EVHHIS6sA3WYLZvNg6E9L9GZmwZzgEdqAFDRl0xaET8EQB/2To21ngsQ0kbIv6zVXcxftzgxQDIgM+qVbUeGbDAPCCtxbfxUhdjHdGhoWGzrnAcIr4NwHflGbGf6PqyQCj0Yx7dRUUTAi9GwQQccapOL7bBm4yjIiPqSElpC5VYRzKZLPgE4M5hK0rt67CDZDM9A+k0XxmIhE6apONgJgxejBmLxw65VHUu/LjRaANeNZQpyhJZUToGBwdHjLqp0Ij4FgB/0wocaxw7DV8F4CcmM/6kwMMQRwYcrFad87DvXW8yTKlbkZVFSmlJB3bBlEk3CQYRvxfA3wbw0Vun7BAAPqjrmfaecPjbrGyib2sKTbS/LG5F4NhGe0d+fDiTuSMSiUx6F8Bn6V343N6TB3gSyb/aHwx22+2OX2KazfF3y7VMnw4FcUvCP8lJcgRtVph0yEu8pTnRBAiv270JwN+1AscQw5zr66YKXLgyVfBijBQc2YQ0PCIY4wPH2yQPERNTYpSPRSPid0qUvY/+1mU5QjJ8PVL96FhjjEdfCPDCzggyAKnPP7cZpWQFlsZ+yPGdMPaDiK/F6fEjbKeypXVK5/pGfyTYZZFPmi0UeOHAcCZI1+Oa6JjVG0SwHbcrnZDn7sytbQSPiLdLTBJXy+Z2nKcR8U09odDhfP0mKyskeBIggaERPb0WGfC1zSFK1gDcXsitER1t6m3wrkTEbRmC5ZTRCd+MiB+wjTlFwVSrfV7zdXV15aWy0oWKvNjWgJMOfyiAIklwYXLhwfd4G/47OAxnTMVRAKec3u0PB8SkFfyxFpSCGMBHTkpWHPsU2bEEKe8xDUrJdfhKnItzgiiEXKvXWhijR9CuzNgOwHWc1+87HQ5+aJQXki4KeOGgOOFJDkdnqeJowSGlweg00vsGHJAa1UpnTJKIAF5u1AM4R8S3APgeo7zQdFHS3uikz+VSSWXVlwBo+hoUbUR0ITfVHQEcEd+K4rbbOE4xaJPhYhg4HY3GcYG4HFB/so5vBT6q53TbdAAXtooe+SzghoaGakWSu2FwflZmfWMffxjAX7XKi8VPG3gBoKam5uoKpeQEDjBz7YD4dpwUd9rlxZMUPe2Nrvf19f2dTKdasap7jHIsiR3TDdxsfxq5xtpazad5g02al+Na6plpND0zTHk8Hp+4iLyU3vwLp0orLWXqrZQAAAAASUVORK5CYII=" + // 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 0000000000000000000000000000000000000000..0c652ed425eb3620b05d30837dfaf4f85866dc2f --- /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 0000000000000000000000000000000000000000..01f6f96609ae0a900c2a269cf36a1dc7d1e4f642 --- /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 913eeddfa19742652c823b0ac5c8768a19d19132..e3f77d72e1a7f27afac22a9f490be7155c70fe16 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 c5356412cb8e08b572e960fa6641d8c267a392ee..265cb6342897d7c99c8efdb2e67314fd6d4fe885 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 0000000000000000000000000000000000000000..4a29221dfae268ee6e8c5583bce23ff114c4bc37 --- /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 0000000000000000000000000000000000000000..78a923df338709ab1b2452f0883653af55c8bbc9 --- /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 911616b4e10183e995d4758d90d7b36d3fc5151b..d37251436a5f23ce869d2e247067d2e20b51d59d 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 0000000000000000000000000000000000000000..1281ca3be803661e3c1c804f38865e43379cbf42 --- /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 0000000000000000000000000000000000000000..7937f277d30f87beed9e1e92ba58f2f01608104e --- /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 0000000000000000000000000000000000000000..beb2a2441835aeaf9ee2ba30c557a8f2b6e4363f --- /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 0000000000000000000000000000000000000000..e95b39874bbe3fc2be4ce9f42fcb100a12af5cff --- /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 0000000000000000000000000000000000000000..1472651271f5f0bd8f5e5df8ea2d4c4d5840cf6a --- /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 0000000000000000000000000000000000000000..6d9b3439a7656f1df8a00bf5b6d506b72251efb8 --- /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 0000000000000000000000000000000000000000..1472651271f5f0bd8f5e5df8ea2d4c4d5840cf6a --- /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 0000000000000000000000000000000000000000..394246f9397b9b1cbe4fc9963496a9a3ffd27f43 --- /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 48594d570793096423e69beff3c86d8cbde327e1..32c972dfb6779fb0a0e89e19651c2e4d21328eaf 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 52c389111427f741dadff43a2f76014d072b9fe0..e207ac594318fe5566cf13a503b9b2a10b5dec33 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 6d9163b426f1dfb36ec625e02622b60156374f09..5cbf342d16145381e4c7d02a6cda0ced3d742389 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 c2f68ee9bd2e8dc30ad2e450fe51da18b4a86385..75657862f5775d03c79846a2a69cca615d853761 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 6d9163b426f1dfb36ec625e02622b60156374f09..5cbf342d16145381e4c7d02a6cda0ced3d742389 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 c2f68ee9bd2e8dc30ad2e450fe51da18b4a86385..75657862f5775d03c79846a2a69cca615d853761 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 06343c786171c40581f1bdc59fdb55ad201ef8e1..1992d7cb033ce920712d6fc39f15bb4aba3cb861 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 b10d8e547eba5625f777dde8141f1daf343fecd4..08a867f7698da2b2e2080467a900ae9f09fa5bfd 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 b10d8e547eba5625f777dde8141f1daf343fecd4..08a867f7698da2b2e2080467a900ae9f09fa5bfd 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)