From c6b6c837e9726e4cd3bdc2ea3dd0cf5c6719643d Mon Sep 17 00:00:00 2001 From: Ozgen Cetinkaya Date: Wed, 10 Jan 2024 16:26:56 +0400 Subject: [PATCH 1/4] SampleApp is updated with STCPay example --- .DS_Store | Bin 0 -> 6148 bytes SampleApp/.DS_Store | Bin 8196 -> 8196 bytes SampleApp/Podfile | 10 + SampleApp/Podfile.lock | 27 + SampleApp/Pods/.DS_Store | Bin 0 -> 6148 bytes .../Categories/IQNSArray+Sort.swift | 57 + .../Categories/IQUIScrollView+Additions.swift | 117 ++ .../IQUITextFieldView+Additions.swift | 93 ++ .../Categories/IQUIView+Hierarchy.swift | 324 +++++ .../IQUIViewController+Additions.swift | 54 + .../IQKeyboardManagerConstants.swift | 150 ++ .../IQKeyboardManagerConstantsInternal.swift | 24 + .../IQKeyboardManager+Debug.swift | 111 ++ .../IQKeyboardManager+Internal.swift | 193 +++ ...boardManager+OrientationNotification.swift | 77 + .../IQKeyboardManager+Position.swift | 694 +++++++++ .../IQKeyboardManager+Toolbar.swift | 398 ++++++ ...yboardManager+UIKeyboardNotification.swift | 341 +++++ ...dManager+UITextFieldViewNotification.swift | 230 +++ .../IQKeyboardManager.swift | 427 ++++++ .../IQKeyboardReturnKeyHandler.swift | 695 +++++++++ .../IQTextView/IQPlaceholderable.swift | 38 + .../IQTextView/IQTextView.swift | 186 +++ .../IQToolbar/IQBarButtonItem.swift | 112 ++ .../IQToolbar/IQInvocation.swift | 45 + .../IQToolbar/IQPreviousNextView.swift | 29 + .../IQToolbar/IQTitleBarButtonItem.swift | 138 ++ .../IQToolbar/IQToolbar.swift | 172 +++ .../IQUIView+IQKeyboardToolbar.swift | 513 +++++++ .../PrivacyInfo.xcprivacy | 10 + .../Pods/IQKeyboardManagerSwift/LICENSE.md | 21 + .../Pods/IQKeyboardManagerSwift/README.md | 223 +++ .../Local Podspecs/PayFortSDK.podspec.json | 26 + SampleApp/Pods/MBProgressHUD/LICENSE | 19 + SampleApp/Pods/MBProgressHUD/MBProgressHUD.h | 411 ++++++ SampleApp/Pods/MBProgressHUD/MBProgressHUD.m | 1194 ++++++++++++++++ SampleApp/Pods/MBProgressHUD/README.mdown | 138 ++ SampleApp/Pods/Manifest.lock | 27 + SampleApp/Pods/Pods.xcodeproj/project.pbxproj | 1242 +++++++++++++++++ .../xcschemes/IQKeyboardManagerSwift.xcscheme | 58 + .../xcschemes/MBProgressHUD.xcscheme | 58 + .../xcschemes/PayFortSDK.xcscheme | 58 + .../xcschemes/Pods-SampleApp.xcscheme | 58 + .../xcschemes/Pods-SampleAppTests.xcscheme | 58 + .../xcschemes/xcschememanagement.plist | 36 + SampleApp/Pods/Target Support Files/.DS_Store | Bin 0 -> 6148 bytes .../IQKeyboardManagerSwift-Info.plist | 26 + .../IQKeyboardManagerSwift-dummy.m | 5 + .../IQKeyboardManagerSwift-prefix.pch | 12 + .../IQKeyboardManagerSwift-umbrella.h | 16 + .../IQKeyboardManagerSwift.debug.xcconfig | 15 + .../IQKeyboardManagerSwift.modulemap | 6 + .../IQKeyboardManagerSwift.release.xcconfig | 15 + .../MBProgressHUD/MBProgressHUD-Info.plist | 26 + .../MBProgressHUD/MBProgressHUD-dummy.m | 5 + .../MBProgressHUD/MBProgressHUD-prefix.pch | 12 + .../MBProgressHUD/MBProgressHUD-umbrella.h | 17 + .../MBProgressHUD.debug.xcconfig | 13 + .../MBProgressHUD/MBProgressHUD.modulemap | 6 + .../MBProgressHUD.release.xcconfig | 13 + ...ortSDK-xcframeworks-input-files.xcfilelist | 2 + ...rtSDK-xcframeworks-output-files.xcfilelist | 1 + .../PayFortSDK/PayFortSDK-xcframeworks.sh | 121 ++ .../PayFortSDK/PayFortSDK.debug.xcconfig | 15 + .../PayFortSDK/PayFortSDK.release.xcconfig | 15 + .../Pods-SampleApp/Pods-SampleApp-Info.plist | 26 + .../Pods-SampleApp-acknowledgements.markdown | 75 + .../Pods-SampleApp-acknowledgements.plist | 119 ++ .../Pods-SampleApp/Pods-SampleApp-dummy.m | 5 + ...pp-frameworks-Debug-input-files.xcfilelist | 4 + ...p-frameworks-Debug-output-files.xcfilelist | 3 + ...-frameworks-Release-input-files.xcfilelist | 4 + ...frameworks-Release-output-files.xcfilelist | 3 + .../Pods-SampleApp-frameworks.sh | 190 +++ .../Pods-SampleApp/Pods-SampleApp-umbrella.h | 16 + .../Pods-SampleApp.debug.xcconfig | 15 + .../Pods-SampleApp/Pods-SampleApp.modulemap | 6 + .../Pods-SampleApp.release.xcconfig | 15 + .../Pods-SampleAppTests-Info.plist | 26 + ...s-SampleAppTests-acknowledgements.markdown | 3 + ...Pods-SampleAppTests-acknowledgements.plist | 29 + .../Pods-SampleAppTests-dummy.m | 5 + .../Pods-SampleAppTests-umbrella.h | 16 + .../Pods-SampleAppTests.debug.xcconfig | 12 + .../Pods-SampleAppTests.modulemap | 6 + .../Pods-SampleAppTests.release.xcconfig | 12 + SampleApp/SampleApp.xcodeproj/project.pbxproj | 125 +- .../xcshareddata/xcschemes/SampleApp.xcscheme | 2 +- .../xcschemes/xcschememanagement.plist | 14 + .../UserInterfaceState.xcuserstate | Bin 63065 -> 0 bytes .../UserInterfaceState.xcuserstate | Bin 0 -> 172638 bytes SampleApp/SampleApp/.DS_Store | Bin 0 -> 6148 bytes SampleApp/SampleApp/AppDelegate.swift | 2 +- SampleApp/SampleApp/Assets.xcassets/.DS_Store | Bin 0 -> 6148 bytes .../SampleApp/Base.lproj/Main.storyboard | 537 +++++-- SampleApp/SampleApp/Common/GlobalClass.swift | 20 +- .../SampleApp/Common/NetworkLogger.swift | 268 ++++ .../Common/TableViewDataSource.swift | 2 +- SampleApp/SampleApp/Common/Token.swift | 22 + SampleApp/SampleApp/Controllers/.DS_Store | Bin 6148 -> 6148 bytes .../SampleApp/Controllers/Main/ApplePay.swift | 2 +- .../Main/CustomCardViewController.swift | 6 +- .../Main/DirectPayViewController.swift | 27 +- .../Main/HalfCardViewController.swift | 10 +- .../Controllers/Main/MainViewController.swift | 27 +- .../SampleApp/Controllers/Main/STCPay.swift | 33 + .../SdkTokenSettingViewController.swift | 9 - SampleApp/SampleApp/CustomPayFortView-ar.xib | 60 +- SampleApp/SampleApp/CustomPayFortView.xib | 30 +- SampleApp/SampleApp/SampleApp.entitlements | 3 +- SampleApp/SampleApp/SceneDelegate.swift | 1 + SampleApp/SampleApp/ViewController.swift | 192 ++- 112 files changed, 10964 insertions(+), 251 deletions(-) create mode 100644 .DS_Store create mode 100644 SampleApp/Podfile.lock create mode 100644 SampleApp/Pods/.DS_Store create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQNSArray+Sort.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIScrollView+Additions.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUITextFieldView+Additions.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIView+Hierarchy.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIViewController+Additions.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstantsInternal.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Debug.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Internal.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+OrientationNotification.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Position.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Toolbar.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UIKeyboardNotification.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UITextFieldViewNotification.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/PrivacyInfo.xcprivacy create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/LICENSE.md create mode 100644 SampleApp/Pods/IQKeyboardManagerSwift/README.md create mode 100644 SampleApp/Pods/Local Podspecs/PayFortSDK.podspec.json create mode 100644 SampleApp/Pods/MBProgressHUD/LICENSE create mode 100644 SampleApp/Pods/MBProgressHUD/MBProgressHUD.h create mode 100644 SampleApp/Pods/MBProgressHUD/MBProgressHUD.m create mode 100644 SampleApp/Pods/MBProgressHUD/README.mdown create mode 100644 SampleApp/Pods/Manifest.lock create mode 100644 SampleApp/Pods/Pods.xcodeproj/project.pbxproj create mode 100644 SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/IQKeyboardManagerSwift.xcscheme create mode 100644 SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/MBProgressHUD.xcscheme create mode 100644 SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/PayFortSDK.xcscheme create mode 100644 SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/Pods-SampleApp.xcscheme create mode 100644 SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/Pods-SampleAppTests.xcscheme create mode 100644 SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 SampleApp/Pods/Target Support Files/.DS_Store create mode 100644 SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-Info.plist create mode 100644 SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-dummy.m create mode 100644 SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch create mode 100644 SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-umbrella.h create mode 100644 SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.debug.xcconfig create mode 100644 SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.modulemap create mode 100644 SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.release.xcconfig create mode 100644 SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-Info.plist create mode 100644 SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-dummy.m create mode 100644 SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-prefix.pch create mode 100644 SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-umbrella.h create mode 100644 SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.debug.xcconfig create mode 100644 SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.modulemap create mode 100644 SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.release.xcconfig create mode 100644 SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks-input-files.xcfilelist create mode 100644 SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks-output-files.xcfilelist create mode 100755 SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks.sh create mode 100644 SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK.debug.xcconfig create mode 100644 SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK.release.xcconfig create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-Info.plist create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-acknowledgements.markdown create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-acknowledgements.plist create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-dummy.m create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Debug-input-files.xcfilelist create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Debug-output-files.xcfilelist create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Release-input-files.xcfilelist create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Release-output-files.xcfilelist create mode 100755 SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks.sh create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-umbrella.h create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.debug.xcconfig create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.modulemap create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.release.xcconfig create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-Info.plist create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-acknowledgements.markdown create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-acknowledgements.plist create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-dummy.m create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-umbrella.h create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.debug.xcconfig create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.modulemap create mode 100644 SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.release.xcconfig create mode 100644 SampleApp/SampleApp.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100644 SampleApp/SampleApp.xcworkspace/xcuserdata/ahmadalkalouti.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 SampleApp/SampleApp.xcworkspace/xcuserdata/cetozgen.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 SampleApp/SampleApp/.DS_Store create mode 100644 SampleApp/SampleApp/Assets.xcassets/.DS_Store create mode 100644 SampleApp/SampleApp/Common/NetworkLogger.swift create mode 100644 SampleApp/SampleApp/Common/Token.swift create mode 100644 SampleApp/SampleApp/Controllers/Main/STCPay.swift diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..8c250aa39ed7204d55db2cccd4cea32ba217f629 GIT binary patch literal 6148 zcmeHKO-sW-5S^{jri##mipK@7MOzU+@DgkF;zf+;L8T_PYB0@)HZ@8qp>8)vIDbkzutylzAKu^JWq5!qxW*gpK?|CY%GEnR?Zkd4eB{0OaTs)x za`~0zCalS+yq&ja>hOpV8=8h|nMOJ^v(VruE|7u80yZh?;Fl2pUb? za()^_4UtwwH)?bw*HsI4!7kK`i@o0J*2YGOSIYeo?`>8#OMHE;-0v6c`K6WZqxxOg zio}x=ncRpqcKw`pAKwf34lny5z??vwFGgvMn_|&5LeKcq9Q6P z(Lem-ri~=7Om{7wa<^R2}>;I1= zGcpPo1^$%+%&NJyDu$$U>ril%YdQKQIvMTD6iNyJ z6Vrpq=S3AKO9&jFd|C7a5XjdQ)`zD_gJnAmX5X_LskjqfOki(G5;0UA(7!(+c7z}{em_Zjvn*m89 zAgRD$2o^B`(jXC&r1Ii|q@4UD1_p+mAO~njR#zJtnHlIP7+Qkuw=@E>O^nUZtnUU{ zZ{GvdMuFv%TZCMg=6g+^AfzRdoA2TRbqI&({LTq_%a1xjB~q|TOfC@SWny?Rxn9_Y znc;`lBoTwj?}WKnc~1iMPPP{@oUA9p1LxT>F)B>17g3ztBD#8GX%6FNc8PB+f~h&_ ThQZ1CxdlLP00C)+WHJH(6I*g? diff --git a/SampleApp/Podfile b/SampleApp/Podfile index c258baf..be162f8 100644 --- a/SampleApp/Podfile +++ b/SampleApp/Podfile @@ -16,3 +16,13 @@ target 'SampleApp' do end end + +post_install do |installer| + installer.pods_project.targets.each do |target| + if ['PayFortSDK'].include? target.name + target.build_configurations.each do |config| + config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES' + end + end + end + end diff --git a/SampleApp/Podfile.lock b/SampleApp/Podfile.lock new file mode 100644 index 0000000..3a08354 --- /dev/null +++ b/SampleApp/Podfile.lock @@ -0,0 +1,27 @@ +PODS: + - IQKeyboardManagerSwift (6.5.16) + - MBProgressHUD (1.2.0) + - PayFortSDK (3.2.0) + +DEPENDENCIES: + - IQKeyboardManagerSwift + - MBProgressHUD + - PayFortSDK (from `/Users/cetozgen/gitprivaterepos/fort-ios-sdk-localtest/`) + +SPEC REPOS: + trunk: + - IQKeyboardManagerSwift + - MBProgressHUD + +EXTERNAL SOURCES: + PayFortSDK: + :path: "/Users/cetozgen/gitprivaterepos/fort-ios-sdk-localtest/" + +SPEC CHECKSUMS: + IQKeyboardManagerSwift: 12d89768845bb77b55cc092ecc2b1f9370f06b76 + MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406 + PayFortSDK: 92d7df56734bd520241250ebc9b93987782b33b9 + +PODFILE CHECKSUM: 8037295a3735c99e78f5a1b1d37cac6edcee2814 + +COCOAPODS: 1.14.3 diff --git a/SampleApp/Pods/.DS_Store b/SampleApp/Pods/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..aeb5bc6f080444678067e38b2606e8aa27419131 GIT binary patch literal 6148 zcmeHK&rjPh6n-upxI&wHU=l}5T&vNdX)x_TRyxkpg4hA3l8~xoOXH|X*GW~SoY^0; z+s@q4{)OH5pX~FGB2Zy$7leji_59h-?>YA8#O@;^)*eMIqB;?AsKQDO#WkY(mCi}U zS{8v!kMWGY&@oAhs5j^B4EK=%wRcbGt=_YoF7IDPLs&m1{g!_$2brEc+djX|e;_-Z zFp(kr`2Mf&8%N)MyuLjq`sbMJ ziy%&WLmd!DJ-8gckJCtw+j5jfxsLTs2e0v3x4t@=Y`omuY=~BK+7Oei)>cEjc;1{& zYy9cj`m1-{Pst#ar)oj?tngiFd2De8Us3t%^?vq;X(H1;VrJvb#&PHva11<52JBhD zmmlWx-Kre}j)6Zgpw0&YRp?nP4eFx [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 sortedArrayByPosition() -> [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/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIScrollView+Additions.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIScrollView+Additions.swift new file mode 100644 index 0000000..280f5e5 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIScrollView+Additions.swift @@ -0,0 +1,117 @@ +// +// IQUIScrollView+Additions.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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 - UIKit contains Foundation +import UIKit + +@available(iOSApplicationExtension, unavailable) +@objc public extension UIScrollView { + + private struct AssociatedKeys { + static var shouldIgnoreScrollingAdjustment: Int = 0 + static var shouldIgnoreContentInsetAdjustment: Int = 0 + static var shouldRestoreScrollViewContentOffset: Int = 0 + } + + /** + If YES, then scrollview will ignore scrolling (simply not scroll it) for adjusting textfield position. Default is NO. + */ + var shouldIgnoreScrollingAdjustment: Bool { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.shouldIgnoreScrollingAdjustment) as? Bool ?? false + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.shouldIgnoreScrollingAdjustment, 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 shouldIgnoreContentInsetAdjustment: Bool { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.shouldIgnoreContentInsetAdjustment) as? Bool ?? false + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.shouldIgnoreContentInsetAdjustment, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** + To set customized distance from keyboard for textField/textView. Can't be less than zero + */ + var shouldRestoreScrollViewContentOffset: Bool { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.shouldRestoreScrollViewContentOffset) as? Bool ?? false + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.shouldRestoreScrollViewContentOffset, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } +} + +@available(iOSApplicationExtension, unavailable) +internal extension UITableView { + + func previousIndexPath(of indexPath: IndexPath) -> IndexPath? { + var previousRow = indexPath.row - 1 + var previousSection = 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 + } + } +} + +@available(iOSApplicationExtension, unavailable) +internal extension UICollectionView { + + func previousIndexPath(of indexPath: IndexPath) -> IndexPath? { + var previousRow = indexPath.row - 1 + var previousSection = 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/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUITextFieldView+Additions.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUITextFieldView+Additions.swift new file mode 100644 index 0000000..19ce042 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUITextFieldView+Additions.swift @@ -0,0 +1,93 @@ +// +// IQUITextFieldView+Additions.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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 - UIKit contains Foundation +import UIKit + +/** +Uses default keyboard distance for textField. +*/ +@available(iOSApplicationExtension, unavailable) +public let kIQUseDefaultKeyboardDistance = CGFloat.greatestFiniteMagnitude + +/** +UIView category for managing UITextField/UITextView +*/ +@available(iOSApplicationExtension, unavailable) +@objc public extension UIView { + + private struct AssociatedKeys { + static var keyboardDistanceFromTextField: Int = 0 + static var ignoreSwitchingByNextPrevious: Int = 0 + static var enableMode: Int = 0 + static var shouldResignOnTouchOutsideMode: Int = 0 + } + + /** + To set customized distance from keyboard for textField/textView. Can't be less than zero + */ + var keyboardDistanceFromTextField: CGFloat { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.keyboardDistanceFromTextField) as? CGFloat ?? kIQUseDefaultKeyboardDistance + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.keyboardDistanceFromTextField, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** + If shouldIgnoreSwitchingByNextPrevious is true then library will ignore this textField/textView while moving to other textField/textView using keyboard toolbar next previous buttons. Default is false + */ + var ignoreSwitchingByNextPrevious: Bool { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.ignoreSwitchingByNextPrevious) as? Bool ?? false + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.ignoreSwitchingByNextPrevious, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** + Override Enable/disable managing distance between keyboard and textField behaviour for this particular textField. + */ + var enableMode: IQEnableMode { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.enableMode) as? IQEnableMode ?? .default + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.enableMode, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** + Override resigns Keyboard on touching outside of UITextField/View behaviour for this particular textField. + */ + var shouldResignOnTouchOutsideMode: IQEnableMode { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.shouldResignOnTouchOutsideMode) as? IQEnableMode ?? .default + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.shouldResignOnTouchOutsideMode, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIView+Hierarchy.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIView+Hierarchy.swift new file mode 100644 index 0000000..0f554d9 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIView+Hierarchy.swift @@ -0,0 +1,324 @@ +// +// IQUIView+Hierarchy.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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) +@objc public extension UIView { + + // MARK: viewControllers + + /** + Returns the UIViewController object that manages the receiver. + */ + func viewContainingController() -> UIViewController? { + + var nextResponder: UIResponder? = self + + repeat { + nextResponder = nextResponder?.next + + if let viewController = 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 = window?.rootViewController { + controllersHierarchy.append(topController) + + while let presented = topController.presentedViewController { + + topController = presented + + controllersHierarchy.append(presented) + } + + var matchController: UIResponder? = viewContainingController() + + while let mController = matchController as? UIViewController, controllersHierarchy.contains(mController) == false { + + 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 = viewContainingController() + var parentContainerViewController: UIViewController? + + if var navController = matchController?.navigationController { + + while let parentNav = navController.navigationController { + navController = parentNav + } + + var parentController: UIViewController = navController + + while let parent = parentController.parent, + (parent.isKind(of: UINavigationController.self) == false && + parent.isKind(of: UITabBarController.self) == false && + parent.isKind(of: UISplitViewController.self) == false) { + + parentController = parent + } + + if navController == parentController { + parentContainerViewController = navController.topViewController + } else { + parentContainerViewController = parentController + } + } else if let tabController = matchController?.tabBarController { + + if let navController = tabController.selectedViewController as? UINavigationController { + parentContainerViewController = navController.topViewController + } else { + parentContainerViewController = tabController.selectedViewController + } + } else { + while let parentController = matchController?.parent, + (parentController.isKind(of: UINavigationController.self) == false && + parentController.isKind(of: UITabBarController.self) == false && + parentController.isKind(of: UISplitViewController.self) == false) { + + matchController = parentController + } + + parentContainerViewController = matchController + } + + let finalController = parentContainerViewController?.parentIQContainerViewController() ?? parentContainerViewController + + return finalController + + } + + // MARK: Superviews/Subviews/Siglings + + /** + 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 superviewOfClassType(_ classType: UIView.Type, belowView: UIView? = nil) -> UIView? { + + var superView = superview + + while let unwrappedSuperView = superView { + + if unwrappedSuperView.isKind(of: classType) { + + // If it's UIScrollView, then validating for special cases + if unwrappedSuperView.isKind(of: UIScrollView.self) { + + 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?.isKind(of: UITableView.self) == false, + unwrappedSuperView.superview?.isKind(of: UITableViewCell.self) == false, + classNameString.hasPrefix("_") == false { + return superView + } + } else { + return superView + } + } else if unwrappedSuperView == belowView { + return nil + } + + superView = unwrappedSuperView.superview + } + + return nil + } + + /** + Returns all siblings of the receiver which canBecomeFirstResponder. + */ + internal func responderSiblings() -> [UIView] { + + // Array of (UITextField/UITextView's). + var tempTextFields = [UIView]() + + // Getting all siblings + if let siblings = superview?.subviews { + for textField in siblings { + if (textField == self || textField.ignoreSwitchingByNextPrevious == false), textField.IQcanBecomeFirstResponder() { + tempTextFields.append(textField) + } + } + } + + return tempTextFields + } + + /** + Returns all deep subViews of the receiver which canBecomeFirstResponder. + */ + internal func deepResponderViews() -> [UIView] { + + // Array of (UITextField/UITextView's). + var textfields = [UIView]() + + for textField in subviews { + + if (textField == self || textField.ignoreSwitchingByNextPrevious == false), textField.IQcanBecomeFirstResponder() { + 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, isUserInteractionEnabled, !isHidden, alpha != 0.0 { + for deepView in textField.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 = view1.convert(view1.bounds, to: self) + let frame2 = view2.convert(view2.bounds, to: self) + + if frame1.minY != frame2.minY { + return frame1.minY < frame2.minY + } else { + return frame1.minX < frame2.minX + } + }) + } + + private func IQcanBecomeFirstResponder() -> Bool { + + var IQcanBecomeFirstResponder = false + + if self.conforms(to: UITextInput.self) { + // Setting toolbar to keyboard. + if let textView = self as? UITextView { + IQcanBecomeFirstResponder = textView.isEditable + } else if let textField = self as? UITextField { + IQcanBecomeFirstResponder = textField.isEnabled + } + } + + if IQcanBecomeFirstResponder { + IQcanBecomeFirstResponder = isUserInteractionEnabled && !isHidden && alpha != 0.0 && !isAlertViewTextField() && textFieldSearchBar() == nil + } + + return IQcanBecomeFirstResponder + } + + // MARK: Special TextFields + + /** + Returns searchBar if receiver object is UISearchBarTextField, otherwise return nil. + */ + internal func textFieldSearchBar() -> UISearchBar? { + + var responder: UIResponder? = self.next + + while let bar = responder { + + if let searchBar = 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. + */ + internal func isAlertViewTextField() -> Bool { + + var alertViewController: UIResponder? = viewContainingController() + + var isAlertViewTextField = false + + while let controller = alertViewController, !isAlertViewTextField { + + if controller.isKind(of: UIAlertController.self) { + isAlertViewTextField = true + break + } + + alertViewController = controller.next + } + + return isAlertViewTextField + } + + private func depth() -> Int { + var depth: Int = 0 + + if let superView = superview { + depth = superView.depth()+1 + } + + return depth + } + +} + +@available(iOSApplicationExtension, unavailable) +extension NSObject { + + internal func _IQDescription() -> String { + return "<\(self) \(Unmanaged.passUnretained(self).toOpaque())>" + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIViewController+Additions.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIViewController+Additions.swift new file mode 100644 index 0000000..5cba198 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Categories/IQUIViewController+Additions.swift @@ -0,0 +1,54 @@ +// +// IQUIViewController+Additions.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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) +@objc extension UIViewController { + + private struct AssociatedKeys { + static var IQLayoutGuideConstraint: Int = 0 + } + + /** + 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 parentIQContainerViewController() -> UIViewController? { + return self + } + + /** + To set customized distance from keyboard for textField/textView. Can't be less than zero + + @deprecated Due to change in core-logic of handling distance between textField and keyboard distance, this layout contraint tweak is no longer needed and things will just work out of the box regardless of constraint pinned with safeArea/layoutGuide/superview + */ + @available(*, deprecated, message: "Due to change in core-logic of handling distance between textField and keyboard distance, this layout contraint tweak is no longer needed and things will just work out of the box regardless of constraint pinned with safeArea/layoutGuide/superview.") + @IBOutlet public var IQLayoutGuideConstraint: NSLayoutConstraint? { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.IQLayoutGuideConstraint) as? NSLayoutConstraint + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.IQLayoutGuideConstraint, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift new file mode 100644 index 0000000..3eea696 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift @@ -0,0 +1,150 @@ +// +// IQKeyboardManagerConstants.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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: IQAutoToolbarManageBehaviour + +/** +`IQAutoToolbarBySubviews` +Creates Toolbar according to subview's hirarchy 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 IQAutoToolbarManageBehaviour: 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/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstantsInternal.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstantsInternal.swift new file mode 100644 index 0000000..595b2e5 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstantsInternal.swift @@ -0,0 +1,24 @@ +// +// IQKeyboardManagerConstantsInternal.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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 diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Debug.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Debug.swift new file mode 100644 index 0000000..b5008db --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Debug.swift @@ -0,0 +1,111 @@ +// +// IQKeyboardManager+Debug.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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 - UIKit contains Foundation +import UIKit + +// MARK: Debugging & Developer options +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManager { + + 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) + } + } + + /** + @warning Use below methods to completely enable/disable notifications registered by library internally. + Please keep in mind that library is totally dependent on NSNotification of UITextField, UITextField, Keyboard etc. + If you do unregisterAllNotifications then library will not work at all. You should only use below methods if you want to completedly disable all library functions. + You should use below methods at your own risk. + */ + @objc func registerAllNotifications() { + + // Registering for keyboard notification. + NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) + + NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive(_:)), name: UIApplication.didBecomeActiveNotification, object: nil) + + // Registering for UITextField notification. + registerTextFieldViewClass(UITextField.self, didBeginEditingNotificationName: UITextField.textDidBeginEditingNotification.rawValue, didEndEditingNotificationName: UITextField.textDidEndEditingNotification.rawValue) + + // Registering for UITextView notification. + registerTextFieldViewClass(UITextView.self, didBeginEditingNotificationName: UITextView.textDidBeginEditingNotification.rawValue, didEndEditingNotificationName: UITextView.textDidEndEditingNotification.rawValue) + + // Registering for orientation changes notification + NotificationCenter.default.addObserver(self, selector: #selector(self.willChangeStatusBarOrientation(_:)), name: UIApplication.willChangeStatusBarOrientationNotification, object: UIApplication.shared) + } + + @objc func unregisterAllNotifications() { + + // Unregistering for keyboard notification. + NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil) + NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil) + + NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil) + + // Unregistering for UITextField notification. + unregisterTextFieldViewClass(UITextField.self, didBeginEditingNotificationName: UITextField.textDidBeginEditingNotification.rawValue, didEndEditingNotificationName: UITextField.textDidEndEditingNotification.rawValue) + + // Unregistering for UITextView notification. + unregisterTextFieldViewClass(UITextView.self, didBeginEditingNotificationName: UITextView.textDidBeginEditingNotification.rawValue, didEndEditingNotificationName: UITextView.textDidEndEditingNotification.rawValue) + + // Unregistering for orientation changes notification + NotificationCenter.default.removeObserver(self, name: UIApplication.willChangeStatusBarOrientationNotification, object: UIApplication.shared) + } + + 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 = "IQKeyboardManager" + for _ in 0 ... Static.indentation { + preLog += "|\t" + } + + print(preLog + logString) + + if indentation > 0 { + Static.indentation += indentation + } + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Internal.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Internal.swift new file mode 100644 index 0000000..a37a560 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Internal.swift @@ -0,0 +1,193 @@ +// +// IQKeyboardManager+Internal.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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 - UIKit contains Foundation +import UIKit + +@available(iOSApplicationExtension, unavailable) +internal extension IQKeyboardManager { + + /** Get all UITextField/UITextView siblings of textFieldView. */ + func responderViews() -> [UIView]? { + + var superConsideredView: UIView? + + // If find any consider responderView in it's upper hierarchy then will get deepResponderView. + for disabledClass in toolbarPreviousNextAllowedClasses { + superConsideredView = textFieldView?.superviewOfClassType(disabledClass) + if superConsideredView != nil { + break + } + } + + // 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. (Enhancement ID: #22) + if let view = superConsideredView { + return view.deepResponderViews() + } else { // Otherwise fetching all the siblings + + guard let textFields = textFieldView?.responderSiblings() else { + return nil + } + + // Sorting textFields according to behaviour + switch toolbarManageBehaviour { + // If autoToolbar behaviour is bySubviews, then returning it. + case .bySubviews: return textFields + + // If autoToolbar behaviour is by tag, then sorting it according to tag property. + case .byTag: return textFields.sortedArrayByTag() + + // If autoToolbar behaviour is by tag, then sorting it according to tag property. + case .byPosition: return textFields.sortedArrayByPosition() + } + } + } + + func privateIsEnabled() -> Bool { + + var isEnabled = enable + + let enableMode = textFieldView?.enableMode + + if enableMode == .enabled { + isEnabled = true + } else if enableMode == .disabled { + isEnabled = false + } else if var textFieldViewController = textFieldView?.viewContainingController() { + + // If it is searchBar textField embedded in Navigation Bar + if textFieldView?.textFieldSearchBar() != nil, let navController = textFieldViewController as? UINavigationController, let topController = 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 { + + guard var textFieldViewController = textFieldView?.viewContainingController() else { + return enableAutoToolbar + } + + // If it is searchBar textField embedded in Navigation Bar + if textFieldView?.textFieldSearchBar() != nil, let navController = textFieldViewController as? UINavigationController, let topController = navController.topViewController { + textFieldViewController = topController + } + + var enableToolbar = enableAutoToolbar + + if !enableToolbar, enabledToolbarClasses.contains(where: { textFieldViewController.isKind(of: $0) }) { + enableToolbar = true + } + + if enableToolbar { + + // If found any toolbar disabled classes then return. + if disabledToolbarClasses.contains(where: { textFieldViewController.isKind(of: $0) }) { + enableToolbar = false + } + + // Special Controllers + if enableToolbar { + + let classNameString: String = "\(type(of: textFieldViewController.self))" + + // _UIAlertControllerTextFieldViewController + if classNameString.contains("UIAlertController"), classNameString.hasSuffix("TextFieldViewController") { + enableToolbar = false + } + } + } + + return enableToolbar + } + + func privateShouldResignOnTouchOutside() -> Bool { + + var shouldResign = shouldResignOnTouchOutside + + let enableMode = textFieldView?.shouldResignOnTouchOutsideMode + + if enableMode == .enabled { + shouldResign = true + } else if enableMode == .disabled { + shouldResign = false + } else if var textFieldViewController = textFieldView?.viewContainingController() { + + // If it is searchBar textField embedded in Navigation Bar + if textFieldView?.textFieldSearchBar() != nil, let navController = textFieldViewController as? UINavigationController, let topController = navController.topViewController { + textFieldViewController = topController + } + + // If viewController is kind of enable viewController class, then assuming shouldResignOnTouchOutside is enabled. + if !shouldResign, enabledTouchResignedClasses.contains(where: { textFieldViewController.isKind(of: $0) }) { + shouldResign = true + } + + if shouldResign { + + // If viewController is kind of disable viewController class, then assuming shouldResignOnTouchOutside is disable. + if disabledTouchResignedClasses.contains(where: { textFieldViewController.isKind(of: $0) }) { + shouldResign = false + } + + // Special Controllers + if shouldResign { + + let classNameString: String = "\(type(of: textFieldViewController.self))" + + // _UIAlertControllerTextFieldViewController + if classNameString.contains("UIAlertController"), classNameString.hasSuffix("TextFieldViewController") { + shouldResign = false + } + } + } + } + return shouldResign + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+OrientationNotification.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+OrientationNotification.swift new file mode 100644 index 0000000..fc819dc --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+OrientationNotification.swift @@ -0,0 +1,77 @@ +// +// IQKeyboardManager+OrientationNotification.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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 - UIKit contains Foundation +import UIKit + +// MARK: UIStatusBar Notification methods +@available(iOSApplicationExtension, unavailable) +internal extension IQKeyboardManager { + + /** UIApplicationWillChangeStatusBarOrientationNotification. Need to set the textView to it's original position. If any frame changes made. (Bug ID: #92)*/ + @objc func willChangeStatusBarOrientation(_ notification: Notification) { + + let currentStatusBarOrientation: UIInterfaceOrientation + #if swift(>=5.1) + if #available(iOS 13, *) { + currentStatusBarOrientation = keyWindow()?.windowScene?.interfaceOrientation ?? UIInterfaceOrientation.unknown + } else { + currentStatusBarOrientation = UIApplication.shared.statusBarOrientation + } + #else + currentStatusBarOrientation = UIApplication.shared.statusBarOrientation + #endif + + guard let statusBarOrientation = notification.userInfo?[UIApplication.statusBarOrientationUserInfoKey] as? Int, currentStatusBarOrientation.rawValue != statusBarOrientation else { + return + } + + let startTime = CACurrentMediaTime() + showLog("📱>>>>> \(#function) started >>>>>", indentation: 1) + showLog("Notification Object:\(notification.object ?? "NULL")") + + // If textViewContentInsetChanged is saved then restore it. + if let textView = textFieldView as? UIScrollView, textView.responds(to: #selector(getter: UITextView.isEditable)) { + + if isTextViewContentInsetChanged { + self.isTextViewContentInsetChanged = false + if textView.contentInset != self.startingTextViewContentInsets { + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in + + self.showLog("Restoring textView.contentInset to: \(self.startingTextViewContentInsets)") + + // Setting textField to it's initial contentInset + textView.contentInset = self.startingTextViewContentInsets + textView.scrollIndicatorInsets = self.startingTextViewScrollIndicatorInsets + + }, completion: { (_) -> Void in }) + } + } + } + + restorePosition() + + let elapsedTime = CACurrentMediaTime() - startTime + showLog("📱<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Position.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Position.swift new file mode 100644 index 0000000..b9a3937 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Position.swift @@ -0,0 +1,694 @@ +// +// IQKeyboardManager+Position.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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 - UIKit contains Foundation +import UIKit + +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManager { + + private struct AssociatedKeys { + static var movedDistance: Int = 0 + static var movedDistanceChanged: Int = 0 + static var lastScrollView: Int = 0 + static var startingContentOffset: Int = 0 + static var startingScrollIndicatorInsets: Int = 0 + static var startingContentInsets: Int = 0 + static var startingTextViewContentInsets: Int = 0 + static var startingTextViewScrollIndicatorInsets: Int = 0 + static var isTextViewContentInsetChanged: 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. + */ + @objc 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 weak var lastScrollView: UIScrollView? { + get { + return (objc_getAssociatedObject(self, &AssociatedKeys.lastScrollView) as? WeakObjectContainer)?.object as? UIScrollView + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.lastScrollView, WeakObjectContainer(object: newValue), .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** LastScrollView's initial contentOffset. */ + internal var startingContentOffset: CGPoint { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.startingContentOffset) as? CGPoint ?? IQKeyboardManager.kIQCGPointInvalid + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.startingContentOffset, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** LastScrollView's initial scrollIndicatorInsets. */ + internal var startingScrollIndicatorInsets: UIEdgeInsets { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.startingScrollIndicatorInsets) as? UIEdgeInsets ?? .init() + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.startingScrollIndicatorInsets, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** LastScrollView's initial contentInsets. */ + internal var startingContentInsets: UIEdgeInsets { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.startingContentInsets) as? UIEdgeInsets ?? .init() + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.startingContentInsets, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** used to adjust contentInset of UITextView. */ + internal var startingTextViewContentInsets: UIEdgeInsets { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.startingTextViewContentInsets) as? UIEdgeInsets ?? .init() + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.startingTextViewContentInsets, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** used to adjust scrollIndicatorInsets of UITextView. */ + internal var startingTextViewScrollIndicatorInsets: UIEdgeInsets { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.startingTextViewScrollIndicatorInsets) as? UIEdgeInsets ?? .init() + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.startingTextViewScrollIndicatorInsets, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** used with textView to detect a textFieldView contentInset is changed or not. (Bug ID: #92)*/ + internal var isTextViewContentInsetChanged: Bool { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.isTextViewContentInsetChanged) as? Bool ?? false + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.isTextViewContentInsetChanged, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + @objc internal func applicationDidBecomeActive(_ notificatin: Notification) { + + guard privateIsEnabled(), + keyboardShowing, + topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == false, let textFieldView = textFieldView, + textFieldView.isAlertViewTextField() == false else { + return + } + self.adjustPosition() + } + + // swiftlint:disable function_body_length + /* Adjusting RootViewController's frame according to interface orientation. */ + 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 = textFieldView, + let rootController = textFieldView.parentContainerViewController(), + let window = keyWindow(), + let textFieldViewRectInWindow = textFieldView.superview?.convert(textFieldView.frame, to: window), + let textFieldViewRectInRootSuperview = textFieldView.superview?.convert(textFieldView.frame, to: rootController.view?.superview) else { + return + } + + let startTime = CACurrentMediaTime() + showLog(">>>>> \(#function) started >>>>>", indentation: 1) + + // Getting RootViewOrigin. + var rootViewOrigin = rootController.view.frame.origin + + // Maintain keyboardDistanceFromTextField + let specialKeyboardDistanceFromTextField: CGFloat + + if let searchBar = textFieldView.textFieldSearchBar() { + specialKeyboardDistanceFromTextField = searchBar.keyboardDistanceFromTextField + } else { + specialKeyboardDistanceFromTextField = textFieldView.keyboardDistanceFromTextField + } + + let newKeyboardDistanceFromTextField = (specialKeyboardDistanceFromTextField == kIQUseDefaultKeyboardDistance) ? keyboardDistanceFromTextField : specialKeyboardDistanceFromTextField + + let kbSize: CGSize + let originalKbSize: CGSize + + // Calculating actual keyboard covered size respect to window, keyboard frame may be different when hardware keyboard is attached (Bug ID: #469) (Bug ID: #381) (Bug ID: #1506) + do { + var kbFrame = keyboardFrame + + kbFrame.origin.y -= newKeyboardDistanceFromTextField + kbFrame.size.height += newKeyboardDistanceFromTextField + + kbFrame.origin.y -= topViewBeginSafeAreaInsets.bottom + kbFrame.size.height += topViewBeginSafeAreaInsets.bottom + + let intersectRect = kbFrame.intersection(window.frame) + if intersectRect.isNull { + kbSize = CGSize(width: kbFrame.size.width, height: 0) + } else { + kbSize = intersectRect.size + } + } + + do { + let intersectRect = keyboardFrame.intersection(window.frame) + if intersectRect.isNull { + originalKbSize = CGSize(width: keyboardFrame.size.width, height: 0) + } else { + originalKbSize = intersectRect.size + } + } + + let statusBarHeight: CGFloat + + let navigationBarAreaHeight: CGFloat + if let navigationController = rootController.navigationController { + navigationBarAreaHeight = navigationController.navigationBar.frame.maxY + } else { +#if swift(>=5.1) + if #available(iOS 13, *) { + statusBarHeight = window.windowScene?.statusBarManager?.statusBarFrame.height ?? 0 + } else { + statusBarHeight = UIApplication.shared.statusBarFrame.height + } +#else + statusBarHeight = UIApplication.shared.statusBarFrame.height +#endif + navigationBarAreaHeight = statusBarHeight + } + + let layoutAreaHeight: CGFloat = rootController.view.directionalLayoutMargins.top + + let isScrollableTextView: Bool + + if let textView = textFieldView as? UIScrollView, textFieldView.responds(to: #selector(getter: UITextView.isEditable)) { + isScrollableTextView = textView.isScrollEnabled + } else { + isScrollableTextView = false + } + + let topLayoutGuide: CGFloat = max(navigationBarAreaHeight, layoutAreaHeight) + + // 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 : rootController.view.directionalLayoutMargins.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 = min(topMovement, bottomMovement) + } + + showLog("Need to move: \(moveUp), will be moving \(moveUp < 0 ? "down" : "up")") + + var superScrollView: UIScrollView? + var superView = textFieldView.superviewOfClassType(UIScrollView.self) as? UIScrollView + + // Getting UIScrollView whose scrolling is enabled. // (Bug ID: #285) + while let view = superView { + + if view.isScrollEnabled, !view.shouldIgnoreScrollingAdjustment { + superScrollView = view + break + } else { + // Getting it's superScrollView. // (Enhancement ID: #21, #24) + superView = view.superviewOfClassType(UIScrollView.self) as? UIScrollView + } + } + + // If there was a lastScrollView. // (Bug ID: #34) + if let lastScrollView = lastScrollView { + // If we can't find current superScrollView, then setting lastScrollView to it's original form. + if superScrollView == nil { + + if lastScrollView.contentInset != self.startingContentInsets { + showLog("Restoring contentInset to: \(startingContentInsets)") + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in + + lastScrollView.contentInset = self.startingContentInsets + lastScrollView.scrollIndicatorInsets = self.startingScrollIndicatorInsets + }) + } + + if lastScrollView.shouldRestoreScrollViewContentOffset, !lastScrollView.contentOffset.equalTo(startingContentOffset) { + showLog("Restoring contentOffset to: \(startingContentOffset)") + + let animatedContentOffset = textFieldView.superviewOfClassType(UIStackView.self, belowView: lastScrollView) != nil // (Bug ID: #1365, #1508, #1541) + + if animatedContentOffset { + lastScrollView.setContentOffset(startingContentOffset, animated: UIView.areAnimationsEnabled) + } else { + lastScrollView.contentOffset = startingContentOffset + } + } + + startingContentInsets = .zero + startingScrollIndicatorInsets = .zero + startingContentOffset = .zero + self.lastScrollView = nil + } else if superScrollView != lastScrollView { // If both scrollView's are different, then reset lastScrollView to it's original frame and setting current scrollView as last scrollView. + + if lastScrollView.contentInset != self.startingContentInsets { + showLog("Restoring contentInset to: \(startingContentInsets)") + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in + + lastScrollView.contentInset = self.startingContentInsets + lastScrollView.scrollIndicatorInsets = self.startingScrollIndicatorInsets + }) + } + + if lastScrollView.shouldRestoreScrollViewContentOffset, !lastScrollView.contentOffset.equalTo(startingContentOffset) { + showLog("Restoring contentOffset to: \(startingContentOffset)") + + let animatedContentOffset = textFieldView.superviewOfClassType(UIStackView.self, belowView: lastScrollView) != nil // (Bug ID: #1365, #1508, #1541) + + if animatedContentOffset { + lastScrollView.setContentOffset(startingContentOffset, animated: UIView.areAnimationsEnabled) + } else { + lastScrollView.contentOffset = startingContentOffset + } + } + + self.lastScrollView = superScrollView + if let scrollView = superScrollView { + startingContentInsets = scrollView.contentInset + startingContentOffset = scrollView.contentOffset + + #if swift(>=5.1) + if #available(iOS 11.1, *) { + startingScrollIndicatorInsets = scrollView.verticalScrollIndicatorInsets + } else { + startingScrollIndicatorInsets = scrollView.scrollIndicatorInsets + } + #else + startingScrollIndicatorInsets = scrollView.scrollIndicatorInsets + #endif + } + + showLog("Saving ScrollView New contentInset: \(startingContentInsets) and contentOffset: \(startingContentOffset)") + } + // 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 unwrappedSuperScrollView = superScrollView { // If there was no lastScrollView and we found a current scrollView. then setting it as lastScrollView. + lastScrollView = unwrappedSuperScrollView + startingContentInsets = unwrappedSuperScrollView.contentInset + startingContentOffset = unwrappedSuperScrollView.contentOffset + + #if swift(>=5.1) + if #available(iOS 11.1, *) { + startingScrollIndicatorInsets = unwrappedSuperScrollView.verticalScrollIndicatorInsets + } else { + startingScrollIndicatorInsets = unwrappedSuperScrollView.scrollIndicatorInsets + } + #else + startingScrollIndicatorInsets = unwrappedSuperScrollView.scrollIndicatorInsets + #endif + + showLog("Saving ScrollView contentInset: \(startingContentInsets) and contentOffset: \(startingContentOffset)") + } + + // Special case for ScrollView. + // If we found lastScrollView then setting it's contentOffset to show textField. + if let lastScrollView = lastScrollView { + // Saving + var lastView = textFieldView + var superScrollView = self.lastScrollView + + while let scrollView = superScrollView { + + var shouldContinue = false + + if moveUp > 0 { + shouldContinue = moveUp > (-scrollView.contentOffset.y - scrollView.contentInset.top) + + } else if let tableView = scrollView.superviewOfClassType(UITableView.self) as? UITableView { + // Special treatment for UITableView due to their cell reusing logic + shouldContinue = scrollView.contentOffset.y > 0 + + if shouldContinue, let tableCell = textFieldView.superviewOfClassType(UITableViewCell.self) as? UITableViewCell, let indexPath = tableView.indexPath(for: tableCell), let previousIndexPath = tableView.previousIndexPath(of: indexPath) { + + let previousCellRect = tableView.rectForRow(at: previousIndexPath) + if !previousCellRect.isEmpty { + let previousCellRectInRootSuperview = tableView.convert(previousCellRect, to: rootController.view.superview) + + moveUp = min(0, previousCellRectInRootSuperview.maxY - topLayoutGuide) + } + } + } else if let collectionView = scrollView.superviewOfClassType(UICollectionView.self) as? UICollectionView { + // Special treatment for UITableView due to their cell reusing logic + shouldContinue = scrollView.contentOffset.y > 0 + + if shouldContinue, let collectionCell = textFieldView.superviewOfClassType(UICollectionViewCell.self) as? UICollectionViewCell, let indexPath = collectionView.indexPath(for: collectionCell), let previousIndexPath = collectionView.previousIndexPath(of: indexPath), let attributes = collectionView.layoutAttributesForItem(at: previousIndexPath) { + + let previousCellRect = attributes.frame + if !previousCellRect.isEmpty { + let previousCellRectInRootSuperview = collectionView.convert(previousCellRect, to: rootController.view.superview) + + moveUp = min(0, previousCellRectInRootSuperview.maxY - topLayoutGuide) + } + } + } else { + + shouldContinue = textFieldViewRectInRootSuperview.minY < topLayoutGuide + + if shouldContinue { + moveUp = min(0, textFieldViewRectInRootSuperview.minY - topLayoutGuide) + } + } + + // Looping in upper hierarchy until we don't found any scrollView in it's upper hirarchy till UIWindow object. + if shouldContinue { + + var tempScrollView = scrollView.superviewOfClassType(UIScrollView.self) as? UIScrollView + var nextScrollView: UIScrollView? + while let view = tempScrollView { + + if view.isScrollEnabled, !view.shouldIgnoreScrollingAdjustment { + nextScrollView = view + break + } else { + tempScrollView = view.superviewOfClassType(UIScrollView.self) as? UIScrollView + } + } + + // Getting lastViewRect. + if let lastViewRect = lastView.superview?.convert(lastView.frame, to: scrollView) { + + // Calculating the expected Y offset from move and scrollView's contentOffset. + var shouldOffsetY = scrollView.contentOffset.y - min(scrollView.contentOffset.y, -moveUp) + + // Rearranging the expected Y offset according to the view. + shouldOffsetY = min(shouldOffsetY, 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 hierrchy.) + // [_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type + // shouldOffsetY >= 0 shouldOffsetY must be greater than in order to keep distance from navigationBar (Bug ID: #92) + if isScrollableTextView, + nextScrollView == nil, + shouldOffsetY >= 0 { + + // Converting Rectangle according to window bounds. + if let currentTextFieldViewRect = textFieldView.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 (superScrollView.contentOffset.y + expectedFixDistance) is lower than current shouldOffsetY, which means we're in a position where navigationBar up and hide, then reducing shouldOffsetY with expectedOffsetY (superScrollView.contentOffset.y + expectedFixDistance) + shouldOffsetY = min(shouldOffsetY, scrollView.contentOffset.y + expectedFixDistance) + + // 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 shouldOffsetY. + moveUp -= (shouldOffsetY-scrollView.contentOffset.y) + } + } else { + // Subtracting the Y offset from the move variable, because we are going to change scrollView's contentOffset.y to shouldOffsetY. + moveUp -= (shouldOffsetY-scrollView.contentOffset.y) + } + + let newContentOffset = CGPoint(x: scrollView.contentOffset.x, y: shouldOffsetY) + + if scrollView.contentOffset.equalTo(newContentOffset) == false { + + showLog("old contentOffset: \(scrollView.contentOffset) new contentOffset: \(newContentOffset)") + self.showLog("Remaining Move: \(moveUp)") + + // Getting problem while using `setContentOffset:animated:`, So I used animation API. + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in + + let animatedContentOffset = textFieldView.superviewOfClassType(UIStackView.self, belowView: scrollView) != nil // (Bug ID: #1365, #1508, #1541) + + if animatedContentOffset { + scrollView.setContentOffset(newContentOffset, animated: UIView.areAnimationsEnabled) + } else { + scrollView.contentOffset = newContentOffset + } + }, completion: { _ in + + if scrollView is UITableView || scrollView is UICollectionView { + // This will update the next/previous states + self.addToolbarIfRequired() + } + }) + } + } + + // Getting next lastView & superScrollView. + lastView = scrollView + superScrollView = nextScrollView + } else { + moveUp = 0 + break + } + } + + // Updating contentInset + if let lastScrollViewRect = lastScrollView.superview?.convert(lastScrollView.frame, to: window), + lastScrollView.shouldIgnoreContentInsetAdjustment == false { + + var bottomInset: CGFloat = (kbSize.height)-(window.frame.height-lastScrollViewRect.maxY) + var bottomScrollIndicatorInset = bottomInset - newKeyboardDistanceFromTextField - topViewBeginSafeAreaInsets.bottom + + // Update the insets so that the scroll vew doesn't shift incorrectly when the offset is near the bottom of the scroll view. + bottomInset = max(startingContentInsets.bottom, bottomInset) + bottomScrollIndicatorInset = max(startingScrollIndicatorInsets.bottom, bottomScrollIndicatorInset) + + bottomInset -= lastScrollView.safeAreaInsets.bottom + bottomScrollIndicatorInset -= lastScrollView.safeAreaInsets.bottom + + var movedInsets = lastScrollView.contentInset + movedInsets.bottom = bottomInset + + if lastScrollView.contentInset != movedInsets { + showLog("old ContentInset: \(lastScrollView.contentInset) new ContentInset: \(movedInsets)") + + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in + lastScrollView.contentInset = movedInsets + + var newScrollIndicatorInset: UIEdgeInsets + + #if swift(>=5.1) + if #available(iOS 11.1, *) { + newScrollIndicatorInset = lastScrollView.verticalScrollIndicatorInsets + } else { + newScrollIndicatorInset = lastScrollView.scrollIndicatorInsets + } + #else + newScrollIndicatorInset = lastScrollView.scrollIndicatorInsets + #endif + + 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 = window.frame.height - originalKbSize.height + var rootSuperViewFrameInWindow = window.frame + if let rootSuperview = rootController.view.superview { + rootSuperViewFrameInWindow = rootSuperview.convert(rootSuperview.bounds, to: window) + } + + let keyboardOverlapping = rootSuperViewFrameInWindow.maxY - keyboardYPosition + + let textViewHeight = min(textView.frame.height, rootSuperViewFrameInWindow.height-topLayoutGuide-keyboardOverlapping) + + if textView.frame.size.height-textView.contentInset.bottom>textViewHeight { + // _isTextViewContentInsetChanged, If frame is not change by library in past, then saving user textView properties (Bug ID: #92) + if !self.isTextViewContentInsetChanged { + self.startingTextViewContentInsets = textView.contentInset + + #if swift(>=5.1) + if #available(iOS 11.1, *) { + self.startingTextViewScrollIndicatorInsets = textView.verticalScrollIndicatorInsets + } else { + self.startingTextViewScrollIndicatorInsets = textView.scrollIndicatorInsets + } + #else + self.startingTextViewScrollIndicatorInsets = textView.scrollIndicatorInsets + #endif + } + + self.isTextViewContentInsetChanged = true + + var newContentInset = 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)") + + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in + + textView.contentInset = newContentInset + textView.scrollIndicatorInsets = newContentInset + }, completion: { (_) -> Void in }) + } + } + } + + // +Positive or zero. + if moveUp >= 0 { + + rootViewOrigin.y = max(rootViewOrigin.y - moveUp, min(0, -originalKbSize.height)) + + if rootController.view.frame.origin.equalTo(rootViewOrigin) == false { + showLog("Moving Upward") + + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in + + var rect = 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() + } + + self.showLog("Set \(rootController) origin to: \(rootViewOrigin)") + }) + } + + movedDistance = (topViewBeginOrigin.y-rootViewOrigin.y) + } else { // -Negative + let disturbDistance: CGFloat = rootViewOrigin.y-topViewBeginOrigin.y + + // disturbDistance Negative = frame disturbed. + // disturbDistance positive = frame not disturbed. + if disturbDistance <= 0 { + + rootViewOrigin.y -= max(moveUp, disturbDistance) + + if rootController.view.frame.origin.equalTo(rootViewOrigin) == false { + showLog("Moving Downward") + // Setting adjusted rootViewRect + // Setting adjusted rootViewRect + + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in + + var rect = 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() + } + + self.showLog("Set \(rootController) origin to: \(rootViewOrigin)") + }) + } + + movedDistance = (topViewBeginOrigin.y-rootViewOrigin.y) + } + } + + let elapsedTime = CACurrentMediaTime() - startTime + showLog("<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) + } + // swiftlint:enable function_body_length + + internal func restorePosition() { + + // Setting rootViewController frame to it's original position. // (Bug ID: #18) + guard topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == false, let rootViewController = rootViewController else { + return + } + + if rootViewController.view.frame.origin.equalTo(self.topViewBeginOrigin) == false { + // Used UIViewAnimationOptionBeginFromCurrentState to minimize strange animations. + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in + + // Setting it's new frame + var rect = rootViewController.view.frame + rect.origin = self.topViewBeginOrigin + rootViewController.view.frame = rect + + // Animating content if needed (Bug ID: #204) + if self.layoutIfNeededOnUpdate { + // Animating content (Bug ID: #160) + rootViewController.view.setNeedsLayout() + rootViewController.view.layoutIfNeeded() + } + + self.showLog("Restoring \(rootViewController) origin to: \(self.topViewBeginOrigin)") + }) + } + + self.movedDistance = 0 + + if rootViewController.navigationController?.interactivePopGestureRecognizer?.state == .began { + self.rootViewControllerWhilePopGestureRecognizerActive = rootViewController + self.topViewBeginOriginWhilePopGestureRecognizerActive = self.topViewBeginOrigin + } + + self.rootViewController = nil + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Toolbar.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Toolbar.swift new file mode 100644 index 0000000..dbc930a --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+Toolbar.swift @@ -0,0 +1,398 @@ +// +// IQKeyboardManager+Toolbar.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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 - UIKit contains Foundation +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 + + /** 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 = responderViews(), !siblings.isEmpty, + let textField = textFieldView, textField.responds(to: #selector(setter: UITextField.inputAccessoryView)), + (textField.inputAccessoryView == nil || + textField.inputAccessoryView?.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag || + textField.inputAccessoryView?.tag == IQKeyboardManager.kIQDoneButtonToolbarTag) else { + return + } + + let startTime = CACurrentMediaTime() + showLog(">>>>> \(#function) started >>>>>", indentation: 1) + + showLog("Found \(siblings.count) responder sibling(s)") + + let rightConfiguration: IQBarButtonItemConfiguration + + if let doneBarButtonItemImage = toolbarDoneBarButtonItemImage { + rightConfiguration = IQBarButtonItemConfiguration(image: doneBarButtonItemImage, action: #selector(self.doneAction(_:))) + } else if let doneBarButtonItemText = toolbarDoneBarButtonItemText { + rightConfiguration = IQBarButtonItemConfiguration(title: doneBarButtonItemText, action: #selector(self.doneAction(_:))) + } else { + rightConfiguration = IQBarButtonItemConfiguration(barButtonSystemItem: .done, action: #selector(self.doneAction(_:))) + } + rightConfiguration.accessibilityLabel = toolbarDoneBarButtonItemAccessibilityLabel ?? "Done" + + let isTableCollectionView: Bool + if textField.superviewOfClassType(UITableView.self) != nil || + textField.superviewOfClassType(UICollectionView.self) != nil { + isTableCollectionView = true + } else { + isTableCollectionView = false + } + + let shouldHavePreviousNext: 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 { + shouldHavePreviousNext = true + } else if siblings.count <= 1 { + // If only one object is found, then adding only Done button. + shouldHavePreviousNext = false + } else { + shouldHavePreviousNext = true + } + case .alwaysShow: + shouldHavePreviousNext = true + case .alwaysHide: + shouldHavePreviousNext = false + } + + if shouldHavePreviousNext { + let prevConfiguration: IQBarButtonItemConfiguration + + if let doneBarButtonItemImage = toolbarPreviousBarButtonItemImage { + prevConfiguration = IQBarButtonItemConfiguration(image: doneBarButtonItemImage, action: #selector(self.previousAction(_:))) + } else if let doneBarButtonItemText = toolbarPreviousBarButtonItemText { + prevConfiguration = IQBarButtonItemConfiguration(title: doneBarButtonItemText, action: #selector(self.previousAction(_:))) + } else { + prevConfiguration = IQBarButtonItemConfiguration(image: (UIImage.keyboardPreviousImage() ?? UIImage()), action: #selector(self.previousAction(_:))) + } + prevConfiguration.accessibilityLabel = toolbarPreviousBarButtonItemAccessibilityLabel ?? "Previous" + + let nextConfiguration: IQBarButtonItemConfiguration + + if let doneBarButtonItemImage = toolbarNextBarButtonItemImage { + nextConfiguration = IQBarButtonItemConfiguration(image: doneBarButtonItemImage, action: #selector(self.nextAction(_:))) + } else if let doneBarButtonItemText = toolbarNextBarButtonItemText { + nextConfiguration = IQBarButtonItemConfiguration(title: doneBarButtonItemText, action: #selector(self.nextAction(_:))) + } else { + nextConfiguration = IQBarButtonItemConfiguration(image: (UIImage.keyboardNextImage() ?? UIImage()), action: #selector(self.nextAction(_:))) + } + nextConfiguration.accessibilityLabel = toolbarNextBarButtonItemAccessibilityLabel ?? "Next" + + textField.addKeyboardToolbarWithTarget(target: self, titleText: (shouldShowToolbarPlaceholder ? textField.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: toolbarTitlBarButtonItemAccessibilityLabel, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: prevConfiguration, nextBarButtonConfiguration: nextConfiguration) + + textField.inputAccessoryView?.tag = IQKeyboardManager.kIQPreviousNextButtonToolbarTag // (Bug ID: #78) + + if isTableCollectionView { + // In case of UITableView (Special), the next/previous buttons should always be enabled. (Bug ID: #56) + textField.keyboardToolbar.previousBarButton.isEnabled = true + textField.keyboardToolbar.nextBarButton.isEnabled = true + } else { + // If firstTextField, then previous should not be enabled. + textField.keyboardToolbar.previousBarButton.isEnabled = (siblings.first != textField) + // If lastTextField then next should not be enaled. + textField.keyboardToolbar.nextBarButton.isEnabled = (siblings.last != textField) + } + + } else { + textField.addKeyboardToolbarWithTarget(target: self, titleText: (shouldShowToolbarPlaceholder ? textField.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: toolbarTitlBarButtonItemAccessibilityLabel, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: nil, nextBarButtonConfiguration: nil) + + textField.inputAccessoryView?.tag = IQKeyboardManager.kIQDoneButtonToolbarTag // (Bug ID: #78) + } + + let toolbar = textField.keyboardToolbar + + // Setting toolbar tintColor // (Enhancement ID: #30) + toolbar.tintColor = shouldToolbarUsesTextFieldTintColor ? textField.tintColor : toolbarTintColor + + // Setting toolbar to keyboard. + if let textFieldView = 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 = toolbarBarTintColor + } + } + + // Setting toolbar title font. // (Enhancement ID: #30) + if shouldShowToolbarPlaceholder, !textField.shouldHideToolbarPlaceholder { + + // Updating placeholder font to toolbar. //(Bug ID: #148, #272) + if toolbar.titleBarButton.title == nil || + toolbar.titleBarButton.title != textField.drawingToolbarPlaceholder { + toolbar.titleBarButton.title = textField.drawingToolbarPlaceholder + } + + // Setting toolbar title font. // (Enhancement ID: #30) + toolbar.titleBarButton.titleFont = placeholderFont + + // Setting toolbar title color. // (Enhancement ID: #880) + toolbar.titleBarButton.titleColor = placeholderColor + + // Setting toolbar button title color. // (Enhancement ID: #880) + toolbar.titleBarButton.selectableTitleColor = placeholderButtonColor + + } else { + toolbar.titleBarButton.title = nil + } + + let elapsedTime = CACurrentMediaTime() - startTime + showLog("<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) + } + + /** Remove any toolbar if it is IQToolbar. */ + internal func removeToolbarIfRequired() { // (Bug ID: #18) + + guard let siblings = responderViews(), !siblings.isEmpty, + let textField = textFieldView, textField.responds(to: #selector(setter: UITextField.inputAccessoryView)), + (textField.inputAccessoryView == nil || + textField.inputAccessoryView?.tag == IQKeyboardManager.kIQPreviousNextButtonToolbarTag || + textField.inputAccessoryView?.tag == IQKeyboardManager.kIQDoneButtonToolbarTag) else { + return + } + + let startTime = CACurrentMediaTime() + showLog(">>>>> \(#function) started >>>>>", indentation: 1) + + showLog("Found \(siblings.count) responder sibling(s)") + + for view in siblings { + if let toolbar = 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 = view as? UITextField { + textField.inputAccessoryView = nil + } else if let textView = view as? UITextView { + textView.inputAccessoryView = nil + } + + view.reloadInputViews() + } + } + } + + let elapsedTime = 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() + } + } +} + +// 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 = responderViews(), let textFieldRetain = textFieldView, let index = 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 = responderViews(), let textFieldRetain = textFieldView, let index = textFields.firstIndex(of: textFieldRetain), index < textFields.count-1 else { + return false + } + return true + } + + /** + Navigate to previous responder textField/textView. + */ + @objc @discardableResult func goPrevious() -> Bool { + + // If it is not first textField. then it's previous object becomeFirstResponder. + guard let textFields = responderViews(), let textFieldRetain = textFieldView, let index = textFields.firstIndex(of: textFieldRetain), index > 0 else { + return false + } + + let nextTextField = textFields[index-1] + + let isAcceptAsFirstResponder = nextTextField.becomeFirstResponder() + + // If it refuses then becoming previous textFieldView as first responder again. (Bug ID: #96) + if isAcceptAsFirstResponder == false { + showLog("Refuses to become first responder: \(nextTextField)") + } + + return isAcceptAsFirstResponder + } + + /** + Navigate to next responder textField/textView. + */ + @objc @discardableResult func goNext() -> Bool { + + // If it is not first textField. then it's previous object becomeFirstResponder. + guard let textFields = responderViews(), let textFieldRetain = textFieldView, let index = textFields.firstIndex(of: textFieldRetain), index < textFields.count-1 else { + return false + } + + let nextTextField = textFields[index+1] + + let isAcceptAsFirstResponder = nextTextField.becomeFirstResponder() + + // If it refuses then becoming previous textFieldView as first responder again. (Bug ID: #96) + if isAcceptAsFirstResponder == false { + 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 shouldPlayInputClicks { + // Play Input Click Sound. + UIDevice.current.playInputClick() + } + + guard canGoPrevious, let textFieldRetain = textFieldView else { + return + } + + let isAcceptAsFirstResponder = goPrevious() + + var invocation = barButton.invocation + var sender = textFieldRetain + + // Handling search bar special case + do { + if let searchBar = textFieldRetain.textFieldSearchBar() { + invocation = searchBar.keyboardToolbar.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 shouldPlayInputClicks { + // Play Input Click Sound. + UIDevice.current.playInputClick() + } + + guard canGoNext, let textFieldRetain = textFieldView else { + return + } + + let isAcceptAsFirstResponder = goNext() + + var invocation = barButton.invocation + var sender = textFieldRetain + + // Handling search bar special case + do { + if let searchBar = textFieldRetain.textFieldSearchBar() { + invocation = searchBar.keyboardToolbar.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 shouldPlayInputClicks { + // Play Input Click Sound. + UIDevice.current.playInputClick() + } + + guard let textFieldRetain = textFieldView else { + return + } + + // Resign textFieldView. + let isResignedFirstResponder = resignFirstResponder() + + var invocation = barButton.invocation + var sender = textFieldRetain + + // Handling search bar special case + do { + if let searchBar = textFieldRetain.textFieldSearchBar() { + invocation = searchBar.keyboardToolbar.doneBarButton.invocation + sender = searchBar + } + } + + if isResignedFirstResponder { + invocation?.invoke(from: sender) + } + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UIKeyboardNotification.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UIKeyboardNotification.swift new file mode 100644 index 0000000..d2e436e --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UIKeyboardNotification.swift @@ -0,0 +1,341 @@ +// +// IQKeyboardManager+UIKeyboardNotification.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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 - UIKit contains Foundation +import UIKit + +// MARK: UIKeyboard Notifications +@available(iOSApplicationExtension, unavailable) +public extension IQKeyboardManager { + + typealias SizeBlock = (_ size: CGSize) -> Void + + private final class KeyboardSizeObserver: NSObject { + weak var observer: NSObject? + var sizeHandler: (_ size: CGSize) -> Void + + init(observer: NSObject?, sizeHandler: @escaping (_ size: CGSize) -> Void) { + self.observer = observer + self.sizeHandler = sizeHandler + } + } + + private struct AssociatedKeys { + static var keyboardSizeObservers: Int = 0 + static var keyboardLastNotifySize: Int = 0 + static var keyboardShowing: Int = 0 + static var keyboardShowNotification: Int = 0 + static var keyboardFrame: Int = 0 + static var animationDuration: Int = 0 + static var animationCurve: Int = 0 + } + + private var keyboardLastNotifySize: CGSize { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.keyboardLastNotifySize) as? CGSize ?? .zero + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.keyboardLastNotifySize, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + private var keyboardSizeObservers: [AnyHashable: SizeBlock] { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.keyboardSizeObservers) as? [AnyHashable: SizeBlock] ?? [:] + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.keyboardSizeObservers, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + @objc func registerKeyboardSizeChange(identifier: AnyHashable, sizeHandler: @escaping SizeBlock) { + keyboardSizeObservers[identifier] = sizeHandler + } + + @objc func unregisterKeyboardSizeChange(identifier: AnyHashable) { + keyboardSizeObservers[identifier] = nil + } + + internal func notifyKeyboardSize(size: CGSize) { + + guard !size.equalTo(keyboardLastNotifySize) else { + return + } + + keyboardLastNotifySize = size + + for block in keyboardSizeObservers.values { + block(size) + } + } + + /** + Boolean to know if keyboard is showing. + */ + @objc private(set) var keyboardShowing: Bool { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.keyboardShowing) as? Bool ?? false + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.keyboardShowing, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** To save keyboardWillShowNotification. Needed for enable keyboard functionality. */ + internal var keyboardShowNotification: Notification? { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.keyboardShowNotification) as? Notification + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.keyboardShowNotification, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** To save keyboard rame. */ + @objc private(set) var keyboardFrame: CGRect { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.keyboardFrame) as? CGRect ?? .zero + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.keyboardFrame, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** To save keyboard animation duration. */ + internal var animationDuration: TimeInterval { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.animationDuration) as? TimeInterval ?? 0.25 + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.animationDuration, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** To mimic the keyboard animation */ + internal var animationCurve: UIView.AnimationOptions { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.animationCurve) as? UIView.AnimationOptions ?? .curveEaseOut + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.animationCurve, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /* UIKeyboardWillShowNotification. */ + @objc internal func keyboardWillShow(_ notification: Notification) { + + keyboardShowNotification = notification + + // Boolean to know keyboard is showing/hiding + keyboardShowing = true + + let oldKBFrame = keyboardFrame + + if let info = notification.userInfo { + + // Getting keyboard animation. + if let curve = info[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt { + animationCurve = UIView.AnimationOptions(rawValue: curve).union(.beginFromCurrentState) + } else { + animationCurve = UIView.AnimationOptions.curveEaseOut.union(.beginFromCurrentState) + } + + // Getting keyboard animation duration + if let duration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval, duration != 0 { + animationDuration = duration + } else { + animationDuration = 0.25 + } + + // Getting UIKeyboardSize. + if let kbFrame = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect { + + keyboardFrame = kbFrame + notifyKeyboardSize(size: keyboardFrame.size) + showLog("UIKeyboard Frame: \(keyboardFrame)") + } + } + + guard privateIsEnabled() else { + restorePosition() + topViewBeginOrigin = IQKeyboardManager.kIQCGPointInvalid + topViewBeginSafeAreaInsets = .zero + return + } + + let startTime = CACurrentMediaTime() + showLog("⌨️>>>>> \(#function) started >>>>>", indentation: 1) + + showLog("Notification Object:\(notification.object ?? "NULL")") + + // (Bug ID: #5) + if let textFieldView = textFieldView, topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) { + + // keyboard is not showing(At the beginning only). We should save rootViewRect. + rootViewController = textFieldView.parentContainerViewController() + if let controller = rootViewController { + + if rootViewControllerWhilePopGestureRecognizerActive == controller { + topViewBeginOrigin = topViewBeginOriginWhilePopGestureRecognizerActive + } else { + topViewBeginOrigin = controller.view.frame.origin + topViewBeginSafeAreaInsets = controller.view.safeAreaInsets + } + + rootViewControllerWhilePopGestureRecognizerActive = nil + topViewBeginOriginWhilePopGestureRecognizerActive = IQKeyboardManager.kIQCGPointInvalid + + self.showLog("Saving \(controller) beginning origin: \(self.topViewBeginOrigin)") + } + } + + // If last restored keyboard size is different(any orientation accure), then refresh. otherwise not. + if keyboardFrame.equalTo(oldKBFrame) == false { + + // If textFieldView is inside UITableViewController then let UITableViewController to handle it (Bug ID: #37) (Bug ID: #76) See note:- https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html If it is UIAlertView textField then do not affect anything (Bug ID: #70). + + if keyboardShowing, + let textFieldView = textFieldView, + textFieldView.isAlertViewTextField() == false { + + // keyboard is already showing. adjust position. + self.adjustPosition() + } + } + + let elapsedTime = CACurrentMediaTime() - startTime + showLog("⌨️<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) + } + + /* UIKeyboardWillHideNotification. So setting rootViewController to it's default frame. */ + @objc internal func keyboardWillHide(_ notification: Notification?) { + + // If it's not a fake notification generated by [self setEnable:NO]. + if notification != nil { + keyboardShowNotification = nil + } + + // Boolean to know keyboard is showing/hiding + keyboardShowing = false + + if let info = notification?.userInfo { + + // Getting keyboard animation. + if let curve = info[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt { + animationCurve = UIView.AnimationOptions(rawValue: curve).union(.beginFromCurrentState) + } else { + animationCurve = UIView.AnimationOptions.curveEaseOut.union(.beginFromCurrentState) + } + + // Getting keyboard animation duration + if let duration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval, duration != 0 { + animationDuration = duration + } else { + animationDuration = 0.25 + } + } + + // If not enabled then do nothing. + guard privateIsEnabled() else { + return + } + + let startTime = CACurrentMediaTime() + showLog("⌨️>>>>> \(#function) started >>>>>", indentation: 1) + showLog("Notification Object:\(notification?.object ?? "NULL")") + + // Commented due to #56. Added all the conditions below to handle WKWebView's textFields. (Bug ID: #56) + // We are unable to get textField object while keyboard showing on WKWebView's textField. (Bug ID: #11) + // if (_textFieldView == nil) return + + // Restoring the contentOffset of the lastScrollView + if let lastScrollView = lastScrollView { + + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in + + if lastScrollView.contentInset != self.startingContentInsets { + self.showLog("Restoring contentInset to: \(self.startingContentInsets)") + lastScrollView.contentInset = self.startingContentInsets + lastScrollView.scrollIndicatorInsets = self.startingScrollIndicatorInsets + } + + if lastScrollView.shouldRestoreScrollViewContentOffset, !lastScrollView.contentOffset.equalTo(self.startingContentOffset) { + self.showLog("Restoring contentOffset to: \(self.startingContentOffset)") + + let animatedContentOffset = self.textFieldView?.superviewOfClassType(UIStackView.self, belowView: lastScrollView) != nil // (Bug ID: #1365, #1508, #1541) + + if animatedContentOffset { + lastScrollView.setContentOffset(self.startingContentOffset, animated: UIView.areAnimationsEnabled) + } else { + lastScrollView.contentOffset = self.startingContentOffset + } + } + + // TODO: restore scrollView state + // This is temporary solution. Have to implement the save and restore scrollView state + var superScrollView: UIScrollView? = lastScrollView + + while let scrollView = superScrollView { + + let contentSize = CGSize(width: max(scrollView.contentSize.width, scrollView.frame.width), height: max(scrollView.contentSize.height, scrollView.frame.height)) + + let minimumY = contentSize.height - scrollView.frame.height + + if minimumY < scrollView.contentOffset.y { + + let newContentOffset = CGPoint(x: scrollView.contentOffset.x, y: minimumY) + if scrollView.contentOffset.equalTo(newContentOffset) == false { + + let animatedContentOffset = self.textFieldView?.superviewOfClassType(UIStackView.self, belowView: scrollView) != nil // (Bug ID: #1365, #1508, #1541) + + if animatedContentOffset { + scrollView.setContentOffset(newContentOffset, animated: UIView.areAnimationsEnabled) + } else { + scrollView.contentOffset = newContentOffset + } + + self.showLog("Restoring contentOffset to: \(self.startingContentOffset)") + } + } + + superScrollView = scrollView.superviewOfClassType(UIScrollView.self) as? UIScrollView + } + }) + } + + restorePosition() + + // Reset all values + lastScrollView = nil + keyboardFrame = .zero + notifyKeyboardSize(size: keyboardFrame.size) + startingContentInsets = .zero + startingScrollIndicatorInsets = .zero + startingContentOffset = CGPoint.zero + topViewBeginOrigin = IQKeyboardManager.kIQCGPointInvalid + topViewBeginSafeAreaInsets = .zero + + let elapsedTime = CACurrentMediaTime() - startTime + showLog("⌨️<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UITextFieldViewNotification.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UITextFieldViewNotification.swift new file mode 100644 index 0000000..dd707f2 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager+UITextFieldViewNotification.swift @@ -0,0 +1,230 @@ +// +// IQKeyboardManager+UITextFieldViewNotification.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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 - UIKit contains Foundation +import UIKit + +// MARK: UITextField/UITextView Notifications +@available(iOSApplicationExtension, unavailable) +internal extension IQKeyboardManager { + + private struct AssociatedKeys { + static var textFieldView: Int = 0 + static var topViewBeginOrigin: Int = 0 + static var topViewBeginSafeAreaInsets: Int = 0 + static var rootViewController: Int = 0 + static var rootViewControllerWhilePopGestureRecognizerActive: Int = 0 + static var topViewBeginOriginWhilePopGestureRecognizerActive: Int = 0 + } + + /** To save UITextField/UITextView object voa textField/textView notifications. */ + weak var textFieldView: UIView? { + get { + return (objc_getAssociatedObject(self, &AssociatedKeys.textFieldView) as? WeakObjectContainer)?.object as? UIView + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.textFieldView, WeakObjectContainer(object: newValue), .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + var topViewBeginOrigin: CGPoint { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.topViewBeginOrigin) as? CGPoint ?? IQKeyboardManager.kIQCGPointInvalid + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.topViewBeginOrigin, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + var topViewBeginSafeAreaInsets: UIEdgeInsets { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.topViewBeginSafeAreaInsets) as? UIEdgeInsets ?? .zero + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.topViewBeginSafeAreaInsets, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** To save rootViewController */ + weak var rootViewController: UIViewController? { + get { + return (objc_getAssociatedObject(self, &AssociatedKeys.rootViewController) as? WeakObjectContainer)?.object as? UIViewController + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.rootViewController, WeakObjectContainer(object: newValue), .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** To overcome with popGestureRecognizer issue Bug ID: #1361 */ + weak var rootViewControllerWhilePopGestureRecognizerActive: UIViewController? { + get { + return (objc_getAssociatedObject(self, &AssociatedKeys.rootViewControllerWhilePopGestureRecognizerActive) as? WeakObjectContainer)?.object as? UIViewController + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.rootViewControllerWhilePopGestureRecognizerActive, WeakObjectContainer(object: newValue), .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + var topViewBeginOriginWhilePopGestureRecognizerActive: CGPoint { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.topViewBeginOriginWhilePopGestureRecognizerActive) as? CGPoint ?? IQKeyboardManager.kIQCGPointInvalid + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.topViewBeginOriginWhilePopGestureRecognizerActive, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + } + + /** UITextFieldTextDidBeginEditingNotification, UITextViewTextDidBeginEditingNotification. Fetching UITextFieldView object. */ + @objc func textFieldViewDidBeginEditing(_ notification: Notification) { + + guard let object = notification.object as? UIView, let isKeyWindow = object.window?.isKeyWindow, isKeyWindow else { + return + } + + let startTime = CACurrentMediaTime() + showLog("📝>>>>> \(#function) started >>>>>", indentation: 1) + showLog("Notification Object:\(notification.object ?? "NULL")") + + // Getting object + textFieldView = notification.object as? UIView + + if overrideKeyboardAppearance, let textInput = textFieldView as? UITextInput, textInput.keyboardAppearance != keyboardAppearance { + // Setting textField keyboard appearance and reloading inputViews. + if let textFieldView = textFieldView as? UITextField { + textFieldView.keyboardAppearance = keyboardAppearance + } else if let textFieldView = textFieldView as? UITextView { + textFieldView.keyboardAppearance = keyboardAppearance + } + textFieldView?.reloadInputViews() + } + + // If autoToolbar enable, then add toolbar on all the UITextField/UITextView's if required. + if privateIsEnableAutoToolbar() { + + // UITextView special case. Keyboard Notification is firing before textView notification so we need to resign it first and then again set it as first responder to add toolbar on it. + if let textView = textFieldView as? UIScrollView, textView.responds(to: #selector(getter: UITextView.isEditable)), + textView.inputAccessoryView == nil { + self.addToolbarIfRequired() + } else { + // Adding toolbar + addToolbarIfRequired() + } + } else { + removeToolbarIfRequired() + } + + resignFirstResponderGesture.isEnabled = privateShouldResignOnTouchOutside() + textFieldView?.window?.addGestureRecognizer(resignFirstResponderGesture) // (Enhancement ID: #14) + + if privateIsEnabled() == false { + restorePosition() + topViewBeginOrigin = IQKeyboardManager.kIQCGPointInvalid + topViewBeginSafeAreaInsets = .zero + } else { + if topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) { // (Bug ID: #5) + + rootViewController = textFieldView?.parentContainerViewController() + + if let controller = rootViewController { + + if rootViewControllerWhilePopGestureRecognizerActive == controller { + topViewBeginOrigin = topViewBeginOriginWhilePopGestureRecognizerActive + } else { + topViewBeginOrigin = controller.view.frame.origin + topViewBeginSafeAreaInsets = controller.view.safeAreaInsets + } + + rootViewControllerWhilePopGestureRecognizerActive = nil + topViewBeginOriginWhilePopGestureRecognizerActive = IQKeyboardManager.kIQCGPointInvalid + + self.showLog("Saving \(controller) beginning origin: \(self.topViewBeginOrigin)") + } + } + + // If textFieldView is inside ignored responder then do nothing. (Bug ID: #37, #74, #76) + // See notes:- https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html If it is UIAlertView textField then do not affect anything (Bug ID: #70). + if keyboardShowing, + let textFieldView = textFieldView, + textFieldView.isAlertViewTextField() == false { + + // keyboard is already showing. adjust position. + self.adjustPosition() + } + } + + let elapsedTime = CACurrentMediaTime() - startTime + showLog("📝<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) + } + + /** UITextFieldTextDidEndEditingNotification, UITextViewTextDidEndEditingNotification. Removing fetched object. */ + @objc func textFieldViewDidEndEditing(_ notification: Notification) { + + guard let object = notification.object as? UIView, let isKeyWindow = object.window?.isKeyWindow, isKeyWindow else { + return + } + + let startTime = CACurrentMediaTime() + showLog("📝>>>>> \(#function) started >>>>>", indentation: 1) + showLog("Notification Object:\(notification.object ?? "NULL")") + + // Removing gesture recognizer (Enhancement ID: #14) + textFieldView?.window?.removeGestureRecognizer(resignFirstResponderGesture) + + // We check if there's a change in original frame or not. + + if let textView = textFieldView as? UIScrollView, textView.responds(to: #selector(getter: UITextView.isEditable)) { + + if isTextViewContentInsetChanged { + self.isTextViewContentInsetChanged = false + + if textView.contentInset != self.startingTextViewContentInsets { + self.showLog("Restoring textView.contentInset to: \(self.startingTextViewContentInsets)") + + UIView.animate(withDuration: animationDuration, delay: 0, options: animationCurve, animations: { () -> Void in + + // Setting textField to it's initial contentInset + textView.contentInset = self.startingTextViewContentInsets + textView.scrollIndicatorInsets = self.startingTextViewScrollIndicatorInsets + + }, completion: { (_) -> Void in }) + } + } + } + + // Setting object to nil +#if swift(>=5.7) + if #available(iOS 16.0, *), let textView = object as? UITextView, textView.isFindInteractionEnabled { + // Not setting it nil, because it may be doing find interaction. + // As of now, here textView.findInteraction?.isFindNavigatorVisible returns false + // So there is no way to detect if this is dismissed due to findInteraction + } else { + textFieldView = nil + } + #else + textFieldView = nil +#endif + + let elapsedTime = CACurrentMediaTime() - startTime + showLog("📝<<<<< \(#function) ended: \(elapsedTime) seconds <<<<<", indentation: -1) + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager.swift new file mode 100644 index 0000000..c0580a6 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQKeyboardManager.swift @@ -0,0 +1,427 @@ +// +// IQKeyboardManager.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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 - UIKit contains Foundation +import UIKit +import CoreGraphics +import QuartzCore + +// MARK: IQToolbar tags + +/** +Codeless 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. A generic version of KeyboardManagement. https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html +*/ + +@available(iOSApplicationExtension, unavailable) +@objc public final class IQKeyboardManager: NSObject { + + /** + Returns the default singleton instance. + */ + @objc public static let shared = IQKeyboardManager() + + /** + Invalid point value. + */ + internal static let kIQCGPointInvalid = CGPoint.init(x: CGFloat.greatestFiniteMagnitude, y: CGFloat.greatestFiniteMagnitude) + + // 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 = false { + + didSet { + // If not enable, enable it. + if enable, !oldValue { + // If keyboard is currently showing. Sending a fake notification for keyboardWillHide to retain view's original position. + if let notification = keyboardShowNotification { + keyboardWillShow(notification) + } + showLog("Enabled") + } else if !enable, oldValue { // If not disable, desable it. + keyboardWillHide(nil) + 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 = true { + didSet { + if privateIsEnableAutoToolbar() { + addToolbarIfRequired() + } else { + removeToolbarIfRequired() + } + + let enableToolbar = enableAutoToolbar ? "Yes" : "NO" + + showLog("enableAutoToolbar: \(enableToolbar)") + } + } + + /** + /** + IQAutoToolbarBySubviews: Creates Toolbar according to subview's hirarchy 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 behaviour. Default is IQAutoToolbarBySubviews. + */ + @objc public var toolbarManageBehaviour = IQAutoToolbarManageBehaviour.bySubviews + + /** + If YES, then uses textField's tintColor property for IQToolbar, otherwise tint color is default. Default is NO. + */ + @objc public var shouldToolbarUsesTextFieldTintColor = false + + /** + This is used for toolbar.tintColor when textfield.keyboardAppearance is UIKeyboardAppearanceDefault. If shouldToolbarUsesTextFieldTintColor is YES then this property is ignored. Default is nil and uses black color. + */ + @objc public var toolbarTintColor: UIColor? + + /** + This is used for toolbar.barTintColor. Default is nil. + */ + @objc public var toolbarBarTintColor: 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 + + /** + Toolbar previous/next/done button icon, If nothing is provided then check toolbarDoneBarButtonItemText to draw done button. + */ + @objc public var toolbarPreviousBarButtonItemImage: UIImage? + @objc public var toolbarNextBarButtonItemImage: UIImage? + @objc public var toolbarDoneBarButtonItemImage: UIImage? + + /** + Toolbar previous/next/done button text, If nothing is provided then system default 'UIBarButtonSystemItemDone' will be used. + */ + @objc public var toolbarPreviousBarButtonItemText: String? + @objc public var toolbarPreviousBarButtonItemAccessibilityLabel: String? + @objc public var toolbarNextBarButtonItemText: String? + @objc public var toolbarNextBarButtonItemAccessibilityLabel: String? + @objc public var toolbarDoneBarButtonItemText: String? + @objc public var toolbarDoneBarButtonItemAccessibilityLabel: String? + @objc public var toolbarTitlBarButtonItemAccessibilityLabel: String? + /** + If YES, then it add the textField's placeholder text on IQToolbar. Default is YES. + */ + @objc public var shouldShowToolbarPlaceholder = true + + /** + Placeholder Font. Default is nil. + */ + @objc public var placeholderFont: UIFont? + + /** + Placeholder Color. Default is nil. Which means lightGray + */ + @objc public var placeholderColor: UIColor? + + /** + Placeholder Button Color when it's treated as button. Default is nil. + */ + @objc public var placeholderButtonColor: UIColor? + + // MARK: UIKeyboard appearance overriding + + /** + Override the keyboardAppearance for all textField/textView. Default is NO. + */ + @objc public var overrideKeyboardAppearance = false + + /** + If overrideKeyboardAppearance is YES, then all the textField keyboardAppearance is set using this property. + */ + @objc public var keyboardAppearance = UIKeyboardAppearance.default + + // MARK: UITextField/UITextView Next/Previous/Resign handling + + /** + Resigns Keyboard on touching outside of UITextField/View. Default is NO. + */ + @objc public var shouldResignOnTouchOutside = false { + + didSet { + resignFirstResponderGesture.isEnabled = privateShouldResignOnTouchOutside() + + let shouldResign = shouldResignOnTouchOutside ? "Yes" : "NO" + + showLog("shouldResignOnTouchOutside: \(shouldResign)") + } + } + + /** 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 lazy public 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. + */ + @objc @discardableResult public func resignFirstResponder() -> Bool { + + guard let textFieldRetain = 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 shouldPlayInputClicks = true + + // MARK: UIAnimation handling + + /** + If YES, then calls 'setNeedsLayout' and 'layoutIfNeeded' on any frame update of to viewController's view. + */ + @objc public var layoutIfNeededOnUpdate = 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 'shouldResignOnTouchOutside' property, Class should be kind of UIViewController. + */ + @objc public var disabledTouchResignedClasses = [UIViewController.Type]() + + /** + Enabled classes to forcefully enable 'shouldResignOnTouchOutsite' 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 shouldResignOnTouchOutside is enabled then you can customise the behaviour to not recognise 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 customised Notifications. For example while using YYTextView https://github.com/ibireme/YYText + + /** + Add/Remove customised Notification for third party customised TextField/TextView. Please be aware that the Notification object must be idential to UITextField/UITextView Notification objects and customised TextField/TextView support must be idential to UITextField/UITextView. + @param didBeginEditingNotificationName This should be identical to UITextViewTextDidBeginEditingNotification + @param didEndEditingNotificationName This should be identical to UITextViewTextDidEndEditingNotification + */ + + @objc public func registerTextFieldViewClass(_ aClass: UIView.Type, didBeginEditingNotificationName: String, didEndEditingNotificationName: String) { + + NotificationCenter.default.addObserver(self, selector: #selector(self.textFieldViewDidBeginEditing(_:)), name: Notification.Name(rawValue: didBeginEditingNotificationName), object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.textFieldViewDidEndEditing(_:)), name: Notification.Name(rawValue: didEndEditingNotificationName), object: nil) + } + + @objc public func unregisterTextFieldViewClass(_ aClass: UIView.Type, didBeginEditingNotificationName: String, didEndEditingNotificationName: String) { + + NotificationCenter.default.removeObserver(self, name: Notification.Name(rawValue: didBeginEditingNotificationName), object: nil) + NotificationCenter.default.removeObserver(self, name: Notification.Name(rawValue: didEndEditingNotificationName), object: nil) + } + + /**************************************************************************************/ + internal struct WeakObjectContainer { + weak var object: AnyObject? + } + + /**************************************************************************************/ + + // MARK: Initialization/Deinitialization + + /* Singleton Object Initialization. */ + override init() { + + super.init() + + self.registerAllNotifications() + + // Creating gesture for @shouldResignOnTouchOutside. (Enhancement ID: #14) + resignFirstResponderGesture.isEnabled = shouldResignOnTouchOutside + + disabledDistanceHandlingClasses.append(UITableViewController.self) + disabledDistanceHandlingClasses.append(UIAlertController.self) + disabledToolbarClasses.append(UIAlertController.self) + disabledTouchResignedClasses.append(UIAlertController.self) + toolbarPreviousNextAllowedClasses.append(UITableView.self) + toolbarPreviousNextAllowedClasses.append(UICollectionView.self) + toolbarPreviousNextAllowedClasses.append(IQPreviousNextView.self) + touchResignedGestureIgnoreClasses.append(UIControl.self) + touchResignedGestureIgnoreClasses.append(UINavigationBar.self) + + // Loading IQToolbar, IQTitleBarButtonItem, IQBarButtonItem to fix first time keyboard appearance delay (Bug ID: #550) + // 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 = UITextField() + textField.addDoneOnKeyboardWithTarget(nil, action: #selector(self.doneAction(_:))) + textField.addPreviousNextDoneOnKeyboardWithTarget(nil, previousAction: #selector(self.previousAction(_:)), nextAction: #selector(self.nextAction(_:)), doneAction: #selector(self.doneAction(_:))) + } + } + + deinit { + // Disable the keyboard manager. + enable = false + } + + /** Getting keyWindow. */ + internal func keyWindow() -> UIWindow? { + + if let keyWindow = textFieldView?.window { + return keyWindow + } else { + + struct Static { + /** @abstract Save keyWindow object for reuse. + @discussion Sometimes [[UIApplication sharedApplication] keyWindow] is returning nil between the app. */ + static weak var keyWindow: UIWindow? + } + + var originalKeyWindow: UIWindow? + + #if swift(>=5.1) + if #available(iOS 13, *) { + originalKeyWindow = UIApplication.shared.connectedScenes + .compactMap { $0 as? UIWindowScene } + .flatMap { $0.windows } + .first(where: { $0.isKeyWindow }) + } else { + originalKeyWindow = UIApplication.shared.keyWindow + } + #else + originalKeyWindow = UIApplication.shared.keyWindow + #endif + + // If original key window is not nil and the cached keywindow is also not original keywindow then changing keywindow. + if let originalKeyWindow = originalKeyWindow { + Static.keyWindow = originalKeyWindow + } + + // Return KeyWindow + return Static.keyWindow + } + } + + // MARK: Public Methods + + /* Refreshes textField/textView position if any external changes is explicitly made by user. */ + @objc public func reloadLayoutIfNeeded() { + + guard privateIsEnabled(), + keyboardShowing, + topViewBeginOrigin.equalTo(IQKeyboardManager.kIQCGPointInvalid) == false, let textFieldView = textFieldView, + textFieldView.isAlertViewTextField() == false else { + return + } + self.adjustPosition() + } +} + +@available(iOSApplicationExtension, unavailable) +extension IQKeyboardManager: UIGestureRecognizerDelegate { + + /** Resigning on tap gesture. (Enhancement ID: #14)*/ + @objc internal 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 { + // Should not recognize gesture if the clicked view is either UIControl or UINavigationBar( IQTextFieldViewInfoModal? { + + for model in textFieldInfoCache { + + if let view = model.textFieldView { + + if view == textField { + return model + } + } + } + + return nil + } + + private 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 disabledClass in IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses { + + superConsideredView = view.superviewOfClassType(disabledClass) + + 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 = superConsideredView { // (Enhancement ID: #22) + textFields = unwrappedTableView.deepResponderViews() + } else { // Otherwise fetching all the siblings + + textFields = view.responderSiblings() + + // Sorting textFields according to behaviour + switch IQKeyboardManager.shared.toolbarManageBehaviour { + // If needs to sort it by tag + case .byTag: textFields = textFields.sortedArrayByTag() + // If needs to sort it by Position + case .byPosition: textFields = textFields.sortedArrayByPosition() + default: break + } + } + + if let lastView = textFields.last { + + if let textField = 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 = 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 intance. 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 = view as? UITextField { + let model = IQTextFieldViewInfoModal(textField: textField) + textFieldInfoCache.append(model) + textField.delegate = self + + } else if let textView = view as? UITextView { + let model = IQTextFieldViewInfoModal(textView: textView) + textFieldInfoCache.append(model) + textView.delegate = self + } + } + + /** + Should pass UITextField/UITextView intance. 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 = textFieldViewCachedInfo(view) { + model.restore() + + if let index = 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 = view.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 = view.deepResponderViews() + + for textField in textFields { + + removeTextFieldView(textField) + } + } + + @discardableResult private 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 disabledClass in IQKeyboardManager.shared.toolbarPreviousNextAllowedClasses { + + superConsideredView = view.superviewOfClassType(disabledClass) + + 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 = superConsideredView { // (Enhancement ID: #22) + textFields = unwrappedTableView.deepResponderViews() + } else { // Otherwise fetching all the siblings + + textFields = view.responderSiblings() + + // Sorting textFields according to behaviour + switch IQKeyboardManager.shared.toolbarManageBehaviour { + // If needs to sort it by tag + case .byTag: textFields = textFields.sortedArrayByTag() + // If needs to sort it by Position + case .byPosition: textFields = textFields.sortedArrayByPosition() + default: + break + } + } + + // Getting index of current textField. + if let index = textFields.firstIndex(of: view) { + // If it is not last textField. then it's next object becomeFirstResponder. + if index < (textFields.count - 1) { + + let nextTextField = textFields[index+1] + nextTextField.becomeFirstResponder() + return false + } else { + + view.resignFirstResponder() + return true + } + } else { + return true + } + } +} + +// MARK: UITextFieldDelegate +@available(iOSApplicationExtension, unavailable) +extension IQKeyboardReturnKeyHandler: UITextFieldDelegate { + + @objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { + + if delegate == nil { + + if let unwrapDelegate = 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 = 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 = textFieldViewCachedInfo(textField) { + aDelegate = model.textFieldDelegate + } + } + + aDelegate?.textFieldDidBeginEditing?(textField) + } + + @objc public func textFieldDidEndEditing(_ textField: UITextField) { + + var aDelegate: UITextFieldDelegate? = delegate + + if aDelegate == nil { + + if let model = 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 = 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 = textFieldViewCachedInfo(textField)?.textFieldDelegate { + if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textField(_:shouldChangeCharactersIn:replacementString:))) { + return unwrapDelegate.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) ?? false + } + } + } + return true + } + + @objc public func textFieldShouldClear(_ textField: UITextField) -> Bool { + + if delegate == nil { + + if let unwrapDelegate = 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 shouldReturn = true + + if delegate == nil { + + if let unwrapDelegate = textFieldViewCachedInfo(textField)?.textFieldDelegate { + if unwrapDelegate.responds(to: #selector(UITextFieldDelegate.textFieldShouldReturn(_:))) { + shouldReturn = unwrapDelegate.textFieldShouldReturn?(textField) ?? false + } + } + } + + if shouldReturn { + goToNextResponderOrResign(textField) + return true + } else { + return goToNextResponderOrResign(textField) + } + } +} + +// MARK: UITextViewDelegate +@available(iOSApplicationExtension, unavailable) +extension IQKeyboardReturnKeyHandler: UITextViewDelegate { + + @objc public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool { + + if delegate == nil { + + if let unwrapDelegate = 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 = 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 = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textViewDidBeginEditing?(textView) + } + + @objc public func textViewDidEndEditing(_ textView: UITextView) { + + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textViewDidEndEditing?(textView) + } + + @objc public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { + + var shouldReturn = true + + if delegate == nil { + + if let unwrapDelegate = textFieldViewCachedInfo(textView)?.textViewDelegate { + if unwrapDelegate.responds(to: #selector(UITextViewDelegate.textView(_:shouldChangeTextIn:replacementText:))) { + shouldReturn = (unwrapDelegate.textView?(textView, shouldChangeTextIn: range, replacementText: text)) ?? false + } + } + } + + if shouldReturn, text == "\n" { + shouldReturn = goToNextResponderOrResign(textView) + } + + return shouldReturn + } + + @objc public func textViewDidChange(_ textView: UITextView) { + + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model = textFieldViewCachedInfo(textView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textViewDidChange?(textView) + } + + @objc public func textViewDidChangeSelection(_ textView: UITextView) { + + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model = 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 = textFieldViewCachedInfo(aTextView)?.textViewDelegate { + if unwrapDelegate.responds(to: #selector(textView as (UITextView, URL, NSRange, UITextItemInteraction) -> Bool)) { + 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 = textFieldViewCachedInfo(aTextView)?.textViewDelegate { + if unwrapDelegate.responds(to: #selector(textView as (UITextView, NSTextAttachment, NSRange, UITextItemInteraction) -> Bool)) { + 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 = 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 = 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(iOSApplicationExtension, unavailable) +extension IQKeyboardReturnKeyHandler { + @available(iOS 16.0, *) + public func textView(_ aTextView: UITextView, editMenuForTextIn range: NSRange, suggestedActions: [UIMenuElement]) -> UIMenu? { + if delegate == nil { + + if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { + if unwrapDelegate.responds(to: #selector(textView as (UITextView, NSRange, [UIMenuElement]) -> UIMenu?)) { + return unwrapDelegate.textView?(aTextView, editMenuForTextIn: range, suggestedActions: suggestedActions) + } + } + } + + return nil + } + + @available(iOS 16.0, *) + public func textView(_ aTextView: UITextView, willPresentEditMenuWith animator: UIEditMenuInteractionAnimating) { + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model = textFieldViewCachedInfo(aTextView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textView?(aTextView, willPresentEditMenuWith: animator) + } + + @available(iOS 16.0, *) + public func textView(_ aTextView: UITextView, willDismissEditMenuWith animator: UIEditMenuInteractionAnimating) { + var aDelegate: UITextViewDelegate? = delegate + + if aDelegate == nil { + + if let model = textFieldViewCachedInfo(aTextView) { + aDelegate = model.textViewDelegate + } + } + + aDelegate?.textView?(aTextView, willDismissEditMenuWith: animator) + } +} +#endif + +#if swift(>=5.9) +@available(iOSApplicationExtension, unavailable) +extension IQKeyboardReturnKeyHandler { + + @available(iOS 17.0, *) + 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 + } + + @available(iOS 17.0, *) + public func textView(_ aTextView: UITextView, menuConfigurationFor textItem: UITextItem, defaultMenu: UIMenu) -> UITextItem.MenuConfiguration? { + if delegate == nil { + + if let unwrapDelegate = textFieldViewCachedInfo(aTextView)?.textViewDelegate { + if unwrapDelegate.responds(to: #selector(textView as (UITextView, UITextItem, UIMenu) -> UITextItem.MenuConfiguration?)) { + return unwrapDelegate.textView?(aTextView, menuConfigurationFor: textItem, defaultMenu: defaultMenu) + } + } + } + + return nil + } + + @available(iOS 17.0, *) + 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) + } + + @available(iOS 17.0, *) + 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/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift new file mode 100644 index 0000000..d8021b4 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift @@ -0,0 +1,38 @@ +// +// IQPlaceholderable.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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) +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/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift new file mode 100644 index 0000000..329d486 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQTextView/IQTextView.swift @@ -0,0 +1,186 @@ +// +// IQTextView.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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) +@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 { + return UIEdgeInsets(top: self.textContainerInset.top, left: self.textContainerInset.left + self.textContainer.lineFragmentPadding, bottom: self.textContainerInset.bottom, right: self.textContainerInset.right + self.textContainer.lineFragmentPadding) + } + + private var placeholderExpectedFrame: CGRect { + let placeholderInsets = self.placeholderInsets + let maxWidth = self.frame.width-placeholderInsets.left-placeholderInsets.right + let expectedSize = placeholderLabel.sizeThatFits(CGSize(width: maxWidth, height: self.frame.height-placeholderInsets.top-placeholderInsets.bottom)) + + return CGRect(x: placeholderInsets.left, y: placeholderInsets.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 + #if swift(>=5.1) + label.textColor = UIColor.systemGray + #else + label.textColor = UIColor.lightText + #endif + 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 internal 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 = 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 = super.intrinsicContentSize + let placeholderInsets = self.placeholderInsets + newSize.height = placeholderExpectedFrame.height + placeholderInsets.top + placeholderInsets.bottom + + return newSize + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift new file mode 100644 index 0000000..0adf974 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift @@ -0,0 +1,112 @@ +// +// IQBarButtonItem.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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 - UIKit contains Foundation +import UIKit + +@available(iOSApplicationExtension, unavailable) +@objc open class IQBarButtonItem: UIBarButtonItem { + + @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 = 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 + */ + @objc internal var isSystemItem = 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 = target, let action = 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/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift new file mode 100644 index 0000000..f43cd6e --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift @@ -0,0 +1,45 @@ +// +// IQInvocation.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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) +@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 = target { + UIApplication.shared.sendAction(action, to: target, from: from, for: UIEvent()) + } + } + + deinit { + target = nil + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift new file mode 100644 index 0000000..f2add12 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift @@ -0,0 +1,29 @@ +// +// IQPreviousNextView.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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) +@objc open class IQPreviousNextView: UIView { + +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift new file mode 100644 index 0000000..396e376 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift @@ -0,0 +1,138 @@ +// +// IQTitleBarButtonItem.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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) +@objc open class IQTitleBarButtonItem: IQBarButtonItem { + + @objc open var titleFont: UIFont? { + + didSet { + if let unwrappedFont = 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) + } + } + + /** + titleColor to be used for displaying button text when displaying title (disabled state). + */ + @objc open var titleColor: UIColor? { + + didSet { + + if let color = 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 = selectableTitleColor { + titleButton?.setTitleColor(color, for: .normal) + } else { + #if swift(>=5.1) + titleButton?.setTitleColor(UIColor.systemBlue, for: .normal) + #else + titleButton?.setTitleColor(UIColor(red: 0.0, green: 0.5, blue: 1.0, alpha: 1), for: .normal) + #endif + } + } + } + + 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?.isEnabled = false + titleButton?.titleLabel?.numberOfLines = 3 + titleButton?.setTitleColor(UIColor.lightGray, for: .disabled) + #if swift(>=5.1) + titleButton?.setTitleColor(UIColor.systemBlue, for: .normal) + #else + titleButton?.setTitleColor(UIColor(red: 0.0, green: 0.5, blue: 1.0, alpha: 1), for: .normal) + #endif + 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 layoutDefaultLowPriority = UILayoutPriority(rawValue: UILayoutPriority.defaultLow.rawValue-1) + let layoutDefaultHighPriority = UILayoutPriority(rawValue: UILayoutPriority.defaultHigh.rawValue-1) + + _titleView?.translatesAutoresizingMaskIntoConstraints = false + _titleView?.setContentHuggingPriority(layoutDefaultLowPriority, for: .vertical) + _titleView?.setContentHuggingPriority(layoutDefaultLowPriority, for: .horizontal) + _titleView?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .vertical) + _titleView?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .horizontal) + + titleButton?.translatesAutoresizingMaskIntoConstraints = false + titleButton?.setContentHuggingPriority(layoutDefaultLowPriority, for: .vertical) + titleButton?.setContentHuggingPriority(layoutDefaultLowPriority, for: .horizontal) + titleButton?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .vertical) + titleButton?.setContentCompressionResistancePriority(layoutDefaultHighPriority, for: .horizontal) + + let top = NSLayoutConstraint.init(item: titleButton!, attribute: .top, relatedBy: .equal, toItem: _titleView, attribute: .top, multiplier: 1, constant: 0) + let bottom = NSLayoutConstraint.init(item: titleButton!, attribute: .bottom, relatedBy: .equal, toItem: _titleView, attribute: .bottom, multiplier: 1, constant: 0) + let leading = NSLayoutConstraint.init(item: titleButton!, attribute: .leading, relatedBy: .equal, toItem: _titleView, attribute: .leading, multiplier: 1, constant: 0) + let trailing = NSLayoutConstraint.init(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) + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift new file mode 100644 index 0000000..6597663 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift @@ -0,0 +1,172 @@ +// +// IQToolbar.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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) +@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 + } + + /** + 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) + privateTitleBarButton?.accessibilityLabel = "Title" + privateTitleBarButton?.accessibilityIdentifier = privateTitleBarButton?.accessibilityLabel + } + 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 = super.sizeThatFits(size) + sizeThatFit.height = 44 + return sizeThatFit + } + + @objc override open var tintColor: UIColor! { + + didSet { + if let unwrappedItems = items { + for item in unwrappedItems { + item.tintColor = tintColor + } + } + } + } + + @objc open var enableInputClicksWhenVisible: Bool { + return true + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift new file mode 100644 index 0000000..9587cfb --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift @@ -0,0 +1,513 @@ +// +// IQUIView+IQKeyboardToolbar.swift +// https://github.com/hackiftekhar/IQKeyboardManager +// Copyright (c) 2013-20 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) +@objc public final class IQBarButtonItemConfiguration: NSObject { + + @objc public init(barButtonSystemItem: UIBarButtonItem.SystemItem, action: Selector) { + self.barButtonSystemItem = barButtonSystemItem + self.image = nil + self.title = nil + self.action = action + super.init() + } + + @objc public init(image: UIImage, action: Selector) { + self.barButtonSystemItem = nil + self.image = image + self.title = nil + self.action = action + super.init() + } + + @objc public init(title: String, action: Selector) { + self.barButtonSystemItem = nil + self.image = nil + self.title = title + self.action = action + super.init() + } + + public let barButtonSystemItem: 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 let action: Selector? // action for bar button item. Usually 'doneAction:(IQBarButtonItem*)item'. +} + +/** + UIImage category methods to get next/prev images + */ +@available(iOSApplicationExtension, unavailable) +@objc public extension UIImage { + + static func keyboardPreviousImage() -> UIImage? { + + struct Static { + static var keyboardUpImage: UIImage? + } + + if Static.keyboardUpImage == nil { + + // swiftlint:disable line_length + let base64Data = "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" + // swiftlint:enable line_length + + if let data = Data(base64Encoded: base64Data, options: .ignoreUnknownCharacters) { + Static.keyboardUpImage = UIImage(data: data, scale: 3) + } + + // Support for RTL languages like Arabic, Persia etc... (Bug ID: #448) + Static.keyboardUpImage = Static.keyboardUpImage?.imageFlippedForRightToLeftLayoutDirection() + } + + return Static.keyboardUpImage + } + + static func keyboardNextImage() -> UIImage? { + + struct Static { + static var keyboardDownImage: UIImage? + } + + if Static.keyboardDownImage == nil { + + // swiftlint:disable line_length + let base64Data = "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" + // swiftlint:enable line_length + + if let data = Data(base64Encoded: base64Data, options: .ignoreUnknownCharacters) { + Static.keyboardDownImage = UIImage(data: data, scale: 3) + } + + // Support for RTL languages like Arabic, Persia etc... (Bug ID: #448) + Static.keyboardDownImage = Static.keyboardDownImage?.imageFlippedForRightToLeftLayoutDirection() + } + + return Static.keyboardDownImage + } +} + +/** +UIView category methods to add IQToolbar on UIKeyboard. +*/ +@available(iOSApplicationExtension, unavailable) +@objc public extension UIView { + + private struct AssociatedKeys { + static var keyboardToolbar: Int = 0 + static var shouldHideToolbarPlaceholder: Int = 0 + static var toolbarPlaceholder: Int = 0 + } + + // MARK: Toolbar + + /** + IQToolbar references for better customization control. + */ + var keyboardToolbar: IQToolbar { + var toolbar = inputAccessoryView as? IQToolbar + + if toolbar == nil { + toolbar = objc_getAssociatedObject(self, &AssociatedKeys.keyboardToolbar) as? IQToolbar + } + + if let unwrappedToolbar = toolbar { + return unwrappedToolbar + } else { + + var width: CGFloat = 0 + + if #available(iOS 13.0, *) { + width = window?.windowScene?.screen.bounds.width ?? .zero + } else { + width = UIScreen.main.bounds.width + } + + let frame = CGRect(origin: .zero, size: .init(width: width, height: 44)) + let newToolbar = IQToolbar(frame: frame) + + objc_setAssociatedObject(self, &AssociatedKeys.keyboardToolbar, newToolbar, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + + return newToolbar + } + } + + // MARK: Toolbar title + + /** + If `shouldHideToolbarPlaceholder` is YES, then title will not be added to the toolbar. Default to NO. + */ + var shouldHideToolbarPlaceholder: Bool { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.shouldHideToolbarPlaceholder) as? Bool ?? false + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.shouldHideToolbarPlaceholder, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + self.keyboardToolbar.titleBarButton.title = self.drawingToolbarPlaceholder + } + } + + /** + `toolbarPlaceholder` to override default `placeholder` text when drawing text on toolbar. + */ + var toolbarPlaceholder: String? { + get { + return objc_getAssociatedObject(self, &AssociatedKeys.toolbarPlaceholder) as? String + } + set(newValue) { + objc_setAssociatedObject(self, &AssociatedKeys.toolbarPlaceholder, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + self.keyboardToolbar.titleBarButton.title = self.drawingToolbarPlaceholder + } + } + + /** + `drawingToolbarPlaceholder` will be actual text used to draw on toolbar. This would either `placeholder` or `toolbarPlaceholder`. + */ + var drawingToolbarPlaceholder: String? { + + if self.shouldHideToolbarPlaceholder { + return nil + } else if self.toolbarPlaceholder?.isEmpty == false { + return self.toolbarPlaceholder + } else if let placeholderable: IQPlaceholderable = self 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: Private helper + + private static func flexibleBarButtonItem () -> IQBarButtonItem { + + struct Static { + + static let nilButton = IQBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) + } + + Static.nilButton.isSystemItem = true + return Static.nilButton + } + + // MARK: Common + + // swiftlint:disable function_body_length + func addKeyboardToolbarWithTarget(target: AnyObject?, + titleText: String?, + titleAccessibilityLabel: String? = nil, + rightBarButtonConfiguration: IQBarButtonItemConfiguration?, + previousBarButtonConfiguration: IQBarButtonItemConfiguration? = nil, + nextBarButtonConfiguration: IQBarButtonItemConfiguration? = nil) { + + // If can't set InputAccessoryView. Then return + if self.responds(to: #selector(setter: UITextField.inputAccessoryView)) { + + // Creating a toolBar for phoneNumber keyboard + let toolbar = self.keyboardToolbar + + var items: [IQBarButtonItem] = [] + + if let prevConfig = previousBarButtonConfiguration { + + var prev = toolbar.previousBarButton + + if prevConfig.barButtonSystemItem == nil, !prev.isSystemItem { + prev.title = prevConfig.title + prev.accessibilityLabel = prevConfig.accessibilityLabel + prev.accessibilityIdentifier = prev.accessibilityLabel + prev.image = prevConfig.image + prev.target = target + prev.action = prevConfig.action + } else { + if let systemItem = prevConfig.barButtonSystemItem { + prev = IQBarButtonItem(barButtonSystemItem: systemItem, target: target, action: prevConfig.action) + prev.isSystemItem = true + } else if let image = prevConfig.image { + prev = IQBarButtonItem(image: image, style: .plain, target: target, action: prevConfig.action) + } else { + prev = IQBarButtonItem(title: prevConfig.title, style: .plain, target: target, action: prevConfig.action) + } + + prev.invocation = toolbar.previousBarButton.invocation + prev.accessibilityLabel = prevConfig.accessibilityLabel + prev.accessibilityIdentifier = prev.accessibilityLabel + prev.isEnabled = toolbar.previousBarButton.isEnabled + prev.tag = toolbar.previousBarButton.tag + toolbar.previousBarButton = prev + } + + items.append(prev) + } + + if previousBarButtonConfiguration != nil, nextBarButtonConfiguration != nil { + + items.append(toolbar.fixedSpaceBarButton) + } + + if let nextConfig = nextBarButtonConfiguration { + + var next = toolbar.nextBarButton + + if nextConfig.barButtonSystemItem == nil, !next.isSystemItem { + next.title = nextConfig.title + next.accessibilityLabel = nextConfig.accessibilityLabel + next.accessibilityIdentifier = next.accessibilityLabel + next.image = nextConfig.image + next.target = target + next.action = nextConfig.action + } else { + if let systemItem = nextConfig.barButtonSystemItem { + next = IQBarButtonItem(barButtonSystemItem: systemItem, target: target, action: nextConfig.action) + next.isSystemItem = true + } else if let image = nextConfig.image { + next = IQBarButtonItem(image: image, style: .plain, target: target, action: nextConfig.action) + } else { + next = IQBarButtonItem(title: nextConfig.title, style: .plain, target: target, action: nextConfig.action) + } + + next.invocation = toolbar.nextBarButton.invocation + next.accessibilityLabel = nextConfig.accessibilityLabel + next.accessibilityIdentifier = next.accessibilityLabel + next.isEnabled = toolbar.nextBarButton.isEnabled + next.tag = toolbar.nextBarButton.tag + toolbar.nextBarButton = next + } + + items.append(next) + } + + // Title bar button item + do { + // Flexible space + items.append(UIView.flexibleBarButtonItem()) + + // Title button + toolbar.titleBarButton.title = titleText + toolbar.titleBarButton.accessibilityLabel = titleAccessibilityLabel + toolbar.titleBarButton.accessibilityIdentifier = titleAccessibilityLabel + + toolbar.titleBarButton.customView?.frame = CGRect.zero + + items.append(toolbar.titleBarButton) + + // Flexible space + items.append(UIView.flexibleBarButtonItem()) + } + + if let rightConfig = rightBarButtonConfiguration { + + var done = toolbar.doneBarButton + + if rightConfig.barButtonSystemItem == nil, !done.isSystemItem { + done.title = rightConfig.title + done.accessibilityLabel = rightConfig.accessibilityLabel + done.accessibilityIdentifier = done.accessibilityLabel + done.image = rightConfig.image + done.target = target + done.action = rightConfig.action + } else { + if let systemItem = rightConfig.barButtonSystemItem { + done = IQBarButtonItem(barButtonSystemItem: systemItem, target: target, action: rightConfig.action) + done.isSystemItem = true + } else if let image = rightConfig.image { + done = IQBarButtonItem(image: image, style: .plain, target: target, action: rightConfig.action) + } else { + done = IQBarButtonItem(title: rightConfig.title, style: .plain, target: target, action: rightConfig.action) + } + + done.invocation = toolbar.doneBarButton.invocation + done.accessibilityLabel = rightConfig.accessibilityLabel + done.accessibilityIdentifier = done.accessibilityLabel + done.isEnabled = toolbar.doneBarButton.isEnabled + done.tag = toolbar.doneBarButton.tag + toolbar.doneBarButton = done + } + + items.append(done) + } + + // Adding button to toolBar. + toolbar.items = items + + if let textInput = self as? UITextInput { + switch textInput.keyboardAppearance { + case .dark?: + toolbar.barStyle = .black + default: + toolbar.barStyle = .default + } + } + + // Setting toolbar to keyboard. + let shouldReloadInputViews: Bool = self.inputAccessoryView == nil + if let textField = self as? UITextField { + textField.inputAccessoryView = toolbar + } else if let textView = self as? UITextView { + textView.inputAccessoryView = toolbar + } + if shouldReloadInputViews { + self.reloadInputViews() + } + } + } + // swiftlint:enable function_body_length + + // MARK: Right + + func addDoneOnKeyboardWithTarget(_ target: AnyObject?, action: Selector, shouldShowPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + + addDoneOnKeyboardWithTarget(target, action: action, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addDoneOnKeyboardWithTarget(_ target: AnyObject?, action: Selector, titleText: String?, titleAccessibilityLabel: String? = nil) { + + let rightConfiguration = IQBarButtonItemConfiguration(barButtonSystemItem: .done, action: action) + + addKeyboardToolbarWithTarget(target: target, titleText: titleText, rightBarButtonConfiguration: rightConfiguration) + } + + func addRightButtonOnKeyboardWithImage(_ image: UIImage, target: AnyObject?, action: Selector, shouldShowPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + + addRightButtonOnKeyboardWithImage(image, target: target, action: action, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addRightButtonOnKeyboardWithImage(_ image: UIImage, target: AnyObject?, action: Selector, titleText: String?, titleAccessibilityLabel: String? = nil) { + + let rightConfiguration = IQBarButtonItemConfiguration(image: image, action: action) + + addKeyboardToolbarWithTarget(target: target, titleText: titleText, titleAccessibilityLabel: titleAccessibilityLabel, rightBarButtonConfiguration: rightConfiguration) + } + + func addRightButtonOnKeyboardWithText(_ text: String, target: AnyObject?, action: Selector, shouldShowPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + + addRightButtonOnKeyboardWithText(text, target: target, action: action, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addRightButtonOnKeyboardWithText(_ text: String, target: AnyObject?, action: Selector, titleText: String?, titleAccessibilityLabel: String? = nil) { + + let rightConfiguration = IQBarButtonItemConfiguration(title: text, action: action) + + addKeyboardToolbarWithTarget(target: target, titleText: titleText, titleAccessibilityLabel: titleAccessibilityLabel, rightBarButtonConfiguration: rightConfiguration) + } + + // MARK: Right/Left + + func addCancelDoneOnKeyboardWithTarget(_ target: AnyObject?, cancelAction: Selector, doneAction: Selector, shouldShowPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + + addCancelDoneOnKeyboardWithTarget(target, cancelAction: cancelAction, doneAction: doneAction, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addRightLeftOnKeyboardWithTarget(_ target: AnyObject?, leftButtonTitle: String, rightButtonTitle: String, leftButtonAction: Selector, rightButtonAction: Selector, shouldShowPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + + addRightLeftOnKeyboardWithTarget(target, leftButtonTitle: leftButtonTitle, rightButtonTitle: rightButtonTitle, leftButtonAction: leftButtonAction, rightButtonAction: rightButtonAction, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addRightLeftOnKeyboardWithTarget(_ target: AnyObject?, leftButtonImage: UIImage, rightButtonImage: UIImage, leftButtonAction: Selector, rightButtonAction: Selector, shouldShowPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + + addRightLeftOnKeyboardWithTarget(target, leftButtonImage: leftButtonImage, rightButtonImage: rightButtonImage, leftButtonAction: leftButtonAction, rightButtonAction: rightButtonAction, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addCancelDoneOnKeyboardWithTarget(_ target: AnyObject?, cancelAction: Selector, doneAction: Selector, titleText: String?, titleAccessibilityLabel: String? = nil) { + + let leftConfiguration = IQBarButtonItemConfiguration(barButtonSystemItem: .cancel, action: cancelAction) + let rightConfiguration = IQBarButtonItemConfiguration(barButtonSystemItem: .done, action: doneAction) + + addKeyboardToolbarWithTarget(target: target, titleText: titleText, titleAccessibilityLabel: titleAccessibilityLabel, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: leftConfiguration) + } + + func addRightLeftOnKeyboardWithTarget(_ target: AnyObject?, leftButtonTitle: String, rightButtonTitle: String, leftButtonAction: Selector, rightButtonAction: Selector, titleText: String?, titleAccessibilityLabel: String? = nil) { + + let leftConfiguration = IQBarButtonItemConfiguration(title: leftButtonTitle, action: leftButtonAction) + let rightConfiguration = IQBarButtonItemConfiguration(title: rightButtonTitle, action: rightButtonAction) + + addKeyboardToolbarWithTarget(target: target, titleText: titleText, titleAccessibilityLabel: titleAccessibilityLabel, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: leftConfiguration) + } + + func addRightLeftOnKeyboardWithTarget(_ target: AnyObject?, leftButtonImage: UIImage, rightButtonImage: UIImage, leftButtonAction: Selector, rightButtonAction: Selector, titleText: String?, titleAccessibilityLabel: String? = nil) { + + let leftConfiguration = IQBarButtonItemConfiguration(image: leftButtonImage, action: leftButtonAction) + let rightConfiguration = IQBarButtonItemConfiguration(image: rightButtonImage, action: rightButtonAction) + + addKeyboardToolbarWithTarget(target: target, titleText: titleText, titleAccessibilityLabel: titleAccessibilityLabel, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: leftConfiguration) + } + + // MARK: Previous/Next/Right + + func addPreviousNextDoneOnKeyboardWithTarget (_ target: AnyObject?, previousAction: Selector, nextAction: Selector, doneAction: Selector, shouldShowPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + + addPreviousNextDoneOnKeyboardWithTarget(target, previousAction: previousAction, nextAction: nextAction, doneAction: doneAction, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addPreviousNextRightOnKeyboardWithTarget(_ target: AnyObject?, rightButtonImage: UIImage, previousAction: Selector, nextAction: Selector, rightButtonAction: Selector, shouldShowPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + + addPreviousNextRightOnKeyboardWithTarget(target, rightButtonImage: rightButtonImage, previousAction: previousAction, nextAction: nextAction, rightButtonAction: rightButtonAction, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addPreviousNextRightOnKeyboardWithTarget(_ target: AnyObject?, rightButtonTitle: String, previousAction: Selector, nextAction: Selector, rightButtonAction: Selector, shouldShowPlaceholder: Bool = false, titleAccessibilityLabel: String? = nil) { + + addPreviousNextRightOnKeyboardWithTarget(target, rightButtonTitle: rightButtonTitle, previousAction: previousAction, nextAction: nextAction, rightButtonAction: rightButtonAction, titleText: (shouldShowPlaceholder ? self.drawingToolbarPlaceholder: nil), titleAccessibilityLabel: titleAccessibilityLabel) + } + + func addPreviousNextDoneOnKeyboardWithTarget (_ target: AnyObject?, previousAction: Selector, nextAction: Selector, doneAction: Selector, titleText: String?, titleAccessibilityLabel: String? = nil) { + + let rightConfiguration = IQBarButtonItemConfiguration(barButtonSystemItem: .done, action: doneAction) + let nextConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardNextImage() ?? UIImage(), action: nextAction) + let prevConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardPreviousImage() ?? UIImage(), action: previousAction) + + addKeyboardToolbarWithTarget(target: target, titleText: titleText, titleAccessibilityLabel: titleAccessibilityLabel, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: prevConfiguration, nextBarButtonConfiguration: nextConfiguration) + } + + func addPreviousNextRightOnKeyboardWithTarget(_ target: AnyObject?, rightButtonImage: UIImage, previousAction: Selector, nextAction: Selector, rightButtonAction: Selector, titleText: String?, titleAccessibilityLabel: String? = nil) { + + let rightConfiguration = IQBarButtonItemConfiguration(image: rightButtonImage, action: rightButtonAction) + let nextConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardNextImage() ?? UIImage(), action: nextAction) + let prevConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardPreviousImage() ?? UIImage(), action: previousAction) + + addKeyboardToolbarWithTarget(target: target, titleText: titleText, titleAccessibilityLabel: titleAccessibilityLabel, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: prevConfiguration, nextBarButtonConfiguration: nextConfiguration) + } + + func addPreviousNextRightOnKeyboardWithTarget(_ target: AnyObject?, rightButtonTitle: String, previousAction: Selector, nextAction: Selector, rightButtonAction: Selector, titleText: String?, titleAccessibilityLabel: String? = nil) { + + let rightConfiguration = IQBarButtonItemConfiguration(title: rightButtonTitle, action: rightButtonAction) + let nextConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardNextImage() ?? UIImage(), action: nextAction) + let prevConfiguration = IQBarButtonItemConfiguration(image: UIImage.keyboardPreviousImage() ?? UIImage(), action: previousAction) + + addKeyboardToolbarWithTarget(target: target, titleText: titleText, titleAccessibilityLabel: titleAccessibilityLabel, rightBarButtonConfiguration: rightConfiguration, previousBarButtonConfiguration: prevConfiguration, nextBarButtonConfiguration: nextConfiguration) + } +} diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/PrivacyInfo.xcprivacy b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..fcfc9b9 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/IQKeyboardManagerSwift/PrivacyInfo.xcprivacy @@ -0,0 +1,10 @@ + + + + + NSPrivacyCollectedDataTypes + + NSPrivacyTracking + + + diff --git a/SampleApp/Pods/IQKeyboardManagerSwift/LICENSE.md b/SampleApp/Pods/IQKeyboardManagerSwift/LICENSE.md new file mode 100644 index 0000000..c17c107 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2013-2017 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/SampleApp/Pods/IQKeyboardManagerSwift/README.md b/SampleApp/Pods/IQKeyboardManagerSwift/README.md new file mode 100644 index 0000000..86ed653 --- /dev/null +++ b/SampleApp/Pods/IQKeyboardManagerSwift/README.md @@ -0,0 +1,223 @@ +

+ Icon +

+

IQKeyboardManager

+

+ GitHub license + + +[![Build Status](https://travis-ci.org/hackiftekhar/IQKeyboardManager.svg)](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 +[![IQKeyboardManager](https://raw.githubusercontent.com/hackiftekhar/IQKeyboardManager/v3.3.0/Screenshot/IQKeyboardManagerScreenshot.png)](http://youtu.be/6nhLw6hju2A) +[![Settings](https://raw.githubusercontent.com/hackiftekhar/IQKeyboardManager/v3.3.0/Screenshot/IQKeyboardManagerSettings.png)](http://youtu.be/6nhLw6hju2A) + +## GIF animation +[![IQKeyboardManager](https://raw.githubusercontent.com/hackiftekhar/IQKeyboardManager/v3.3.0/Screenshot/IQKeyboardManager.gif)](http://youtu.be/6nhLw6hju2A) + +## Video + + + +## 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: + + + +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 +[![Platform iOS](https://img.shields.io/badge/Platform-iOS-blue.svg?style=fla)]() + +| | Language | Minimum iOS Target | Minimum Xcode Version | +|------------------------|----------|--------------------|-----------------------| +| IQKeyboardManager | Obj-C | iOS 8.0 | Xcode 9 | +| IQKeyboardManagerSwift | Swift | iOS 8.0 | Xcode 9 | +| Demo Project | | | Xcode 11 | + +#### Swift versions support + +| Swift | Xcode | IQKeyboardManagerSwift | +|-------------------|-------|------------------------| +| 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 | + +Installation +========================== + +#### Installation with CocoaPods + +[![CocoaPods](https://img.shields.io/cocoapods/v/IQKeyboardManager.svg)](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' #iOS8 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.1, 5.0, 4.2, 4.0, 3.2, 3.0 (Xcode 11)* + +```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 + +[![Github tag](https://img.shields.io/github/tag/hackiftekhar/iqkeyboardmanager.svg)]() + + + +***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 IQKeyboardManager package into your packages, add a reference to IQKeyboardManager and a targeting release version in the dependencies section in `Package.swift` file: + +```swift +import PackageDescription + +let package = Package( + name: "YOUR_PROJECT_NAME", + products: [], + dependencies: [ + .package(url: "https://github.com/hackiftekhar/IQKeyboardManager.git", from: "6.5.0") + ] +) +``` + +To install IQKeyboardManager 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) + +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 +[![IQKeyboardManager CFD](https://raw.githubusercontent.com/hackiftekhar/IQKeyboardManager/master/Screenshot/IQKeyboardManagerFlowDiagram.jpg)](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/SampleApp/Pods/Local Podspecs/PayFortSDK.podspec.json b/SampleApp/Pods/Local Podspecs/PayFortSDK.podspec.json new file mode 100644 index 0000000..aa28e75 --- /dev/null +++ b/SampleApp/Pods/Local Podspecs/PayFortSDK.podspec.json @@ -0,0 +1,26 @@ +{ + "name": "PayFortSDK", + "version": "3.2.0", + "summary": "The Amazon Payment Services IOS SDK allows Merchants to securely integrate the payment functions and easily accept In-App payments.Instead of the traditional, time-consuming, and complex way of being redirected to the mobile browser to complete the payment, In-App payments can be completed through our APS Mobile SDK. In turn, this gives the Merchant’s consumers a smooth, pleasing user-experience by using In-App payment functions through the native applications.", + "homepage": "https://github.com/payfort/fort-ios-sdk", + "authors": { + "Amazon Payment Service": "merchantsupport-ps@amazon.com" + }, + "license": { + "type": "MIT", + "file": "LICENSE.md" + }, + "platforms": { + "ios": "11.0" + }, + "source": { + "git": "https://github.com/payfort/fort-ios-sdk.git", + "tag": "3.2.0" + }, + "ios": { + "vendored_frameworks": "PayFortSDK.xcframework" + }, + "requires_arc": true, + "swift_versions": "5.0", + "swift_version": "5.0" +} diff --git a/SampleApp/Pods/MBProgressHUD/LICENSE b/SampleApp/Pods/MBProgressHUD/LICENSE new file mode 100644 index 0000000..d7f0647 --- /dev/null +++ b/SampleApp/Pods/MBProgressHUD/LICENSE @@ -0,0 +1,19 @@ +Copyright © 2009-2020 Matej Bukovinski + +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. \ No newline at end of file diff --git a/SampleApp/Pods/MBProgressHUD/MBProgressHUD.h b/SampleApp/Pods/MBProgressHUD/MBProgressHUD.h new file mode 100644 index 0000000..38b5004 --- /dev/null +++ b/SampleApp/Pods/MBProgressHUD/MBProgressHUD.h @@ -0,0 +1,411 @@ +// +// MBProgressHUD.h +// Version 1.2.0 +// Created by Matej Bukovinski on 2.4.09. +// + +// This code is distributed under the terms and conditions of the MIT license. + +// Copyright © 2009-2016 Matej Bukovinski +// +// 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 +#import +#import + +@class MBBackgroundView; +@protocol MBProgressHUDDelegate; + + +extern CGFloat const MBProgressMaxOffset; + +typedef NS_ENUM(NSInteger, MBProgressHUDMode) { + /// UIActivityIndicatorView. + MBProgressHUDModeIndeterminate, + /// A round, pie-chart like, progress view. + MBProgressHUDModeDeterminate, + /// Horizontal progress bar. + MBProgressHUDModeDeterminateHorizontalBar, + /// Ring-shaped progress view. + MBProgressHUDModeAnnularDeterminate, + /// Shows a custom view. + MBProgressHUDModeCustomView, + /// Shows only labels. + MBProgressHUDModeText +}; + +typedef NS_ENUM(NSInteger, MBProgressHUDAnimation) { + /// Opacity animation + MBProgressHUDAnimationFade, + /// Opacity + scale animation (zoom in when appearing zoom out when disappearing) + MBProgressHUDAnimationZoom, + /// Opacity + scale animation (zoom out style) + MBProgressHUDAnimationZoomOut, + /// Opacity + scale animation (zoom in style) + MBProgressHUDAnimationZoomIn +}; + +typedef NS_ENUM(NSInteger, MBProgressHUDBackgroundStyle) { + /// Solid color background + MBProgressHUDBackgroundStyleSolidColor, + /// UIVisualEffectView or UIToolbar.layer background view + MBProgressHUDBackgroundStyleBlur +}; + +typedef void (^MBProgressHUDCompletionBlock)(void); + + +NS_ASSUME_NONNULL_BEGIN + + +/** + * Displays a simple HUD window containing a progress indicator and two optional labels for short messages. + * + * This is a simple drop-in class for displaying a progress HUD view similar to Apple's private UIProgressHUD class. + * The MBProgressHUD window spans over the entire space given to it by the initWithFrame: constructor and catches all + * user input on this region, thereby preventing the user operations on components below the view. + * + * @note To still allow touches to pass through the HUD, you can set hud.userInteractionEnabled = NO. + * @attention MBProgressHUD is a UI class and should therefore only be accessed on the main thread. + */ +@interface MBProgressHUD : UIView + +/** + * Creates a new HUD, adds it to provided view and shows it. The counterpart to this method is hideHUDForView:animated:. + * + * @note This method sets removeFromSuperViewOnHide. The HUD will automatically be removed from the view hierarchy when hidden. + * + * @param view The view that the HUD will be added to + * @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use + * animations while appearing. + * @return A reference to the created HUD. + * + * @see hideHUDForView:animated: + * @see animationType + */ ++ (instancetype)showHUDAddedTo:(UIView *)view animated:(BOOL)animated; + +/// @name Showing and hiding + +/** + * Finds the top-most HUD subview that hasn't finished and hides it. The counterpart to this method is showHUDAddedTo:animated:. + * + * @note This method sets removeFromSuperViewOnHide. The HUD will automatically be removed from the view hierarchy when hidden. + * + * @param view The view that is going to be searched for a HUD subview. + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use + * animations while disappearing. + * @return YES if a HUD was found and removed, NO otherwise. + * + * @see showHUDAddedTo:animated: + * @see animationType + */ ++ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated; + +/** + * Finds the top-most HUD subview that hasn't finished and returns it. + * + * @param view The view that is going to be searched. + * @return A reference to the last HUD subview discovered. + */ ++ (nullable MBProgressHUD *)HUDForView:(UIView *)view NS_SWIFT_NAME(forView(_:)); + +/** + * A convenience constructor that initializes the HUD with the view's bounds. Calls the designated constructor with + * view.bounds as the parameter. + * + * @param view The view instance that will provide the bounds for the HUD. Should be the same instance as + * the HUD's superview (i.e., the view that the HUD will be added to). + */ +- (instancetype)initWithView:(UIView *)view; + +/** + * Displays the HUD. + * + * @note You need to make sure that the main thread completes its run loop soon after this method call so that + * the user interface can be updated. Call this method when your task is already set up to be executed in a new thread + * (e.g., when using something like NSOperation or making an asynchronous call like NSURLRequest). + * + * @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use + * animations while appearing. + * + * @see animationType + */ +- (void)showAnimated:(BOOL)animated; + +/** + * Hides the HUD. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to + * hide the HUD when your task completes. + * + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use + * animations while disappearing. + * + * @see animationType + */ +- (void)hideAnimated:(BOOL)animated; + +/** + * Hides the HUD after a delay. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to + * hide the HUD when your task completes. + * + * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use + * animations while disappearing. + * @param delay Delay in seconds until the HUD is hidden. + * + * @see animationType + */ +- (void)hideAnimated:(BOOL)animated afterDelay:(NSTimeInterval)delay; + +/** + * The HUD delegate object. Receives HUD state notifications. + */ +@property (weak, nonatomic) id delegate; + +/** + * Called after the HUD is hidden. + */ +@property (copy, nullable) MBProgressHUDCompletionBlock completionBlock; + +/** + * Grace period is the time (in seconds) that the invoked method may be run without + * showing the HUD. If the task finishes before the grace time runs out, the HUD will + * not be shown at all. + * This may be used to prevent HUD display for very short tasks. + * Defaults to 0 (no grace time). + * @note The graceTime needs to be set before the hud is shown. You thus can't use `showHUDAddedTo:animated:`, + * but instead need to alloc / init the HUD, configure the grace time and than show it manually. + */ +@property (assign, nonatomic) NSTimeInterval graceTime; + +/** + * The minimum time (in seconds) that the HUD is shown. + * This avoids the problem of the HUD being shown and than instantly hidden. + * Defaults to 0 (no minimum show time). + */ +@property (assign, nonatomic) NSTimeInterval minShowTime; + +/** + * Removes the HUD from its parent view when hidden. + * Defaults to NO. + */ +@property (assign, nonatomic) BOOL removeFromSuperViewOnHide; + +/// @name Appearance + +/** + * MBProgressHUD operation mode. The default is MBProgressHUDModeIndeterminate. + */ +@property (assign, nonatomic) MBProgressHUDMode mode; + +/** + * A color that gets forwarded to all labels and supported indicators. Also sets the tintColor + * for custom views on iOS 7+. Set to nil to manage color individually. + * Defaults to semi-translucent black on iOS 7 and later and white on earlier iOS versions. + */ +@property (strong, nonatomic, nullable) UIColor *contentColor UI_APPEARANCE_SELECTOR; + +/** + * The animation type that should be used when the HUD is shown and hidden. + */ +@property (assign, nonatomic) MBProgressHUDAnimation animationType UI_APPEARANCE_SELECTOR; + +/** + * The bezel offset relative to the center of the view. You can use MBProgressMaxOffset + * and -MBProgressMaxOffset to move the HUD all the way to the screen edge in each direction. + * E.g., CGPointMake(0.f, MBProgressMaxOffset) would position the HUD centered on the bottom edge. + */ +@property (assign, nonatomic) CGPoint offset UI_APPEARANCE_SELECTOR; + +/** + * The amount of space between the HUD edge and the HUD elements (labels, indicators or custom views). + * This also represents the minimum bezel distance to the edge of the HUD view. + * Defaults to 20.f + */ +@property (assign, nonatomic) CGFloat margin UI_APPEARANCE_SELECTOR; + +/** + * The minimum size of the HUD bezel. Defaults to CGSizeZero (no minimum size). + */ +@property (assign, nonatomic) CGSize minSize UI_APPEARANCE_SELECTOR; + +/** + * Force the HUD dimensions to be equal if possible. + */ +@property (assign, nonatomic, getter = isSquare) BOOL square UI_APPEARANCE_SELECTOR; + +/** + * When enabled, the bezel center gets slightly affected by the device accelerometer data. + * Defaults to NO. + * + * @note This can cause main thread checker assertions on certain devices. https://github.com/jdg/MBProgressHUD/issues/552 + */ +@property (assign, nonatomic, getter=areDefaultMotionEffectsEnabled) BOOL defaultMotionEffectsEnabled UI_APPEARANCE_SELECTOR; + +/// @name Progress + +/** + * The progress of the progress indicator, from 0.0 to 1.0. Defaults to 0.0. + */ +@property (assign, nonatomic) float progress; + +/// @name ProgressObject + +/** + * The NSProgress object feeding the progress information to the progress indicator. + */ +@property (strong, nonatomic, nullable) NSProgress *progressObject; + +/// @name Views + +/** + * The view containing the labels and indicator (or customView). + */ +@property (strong, nonatomic, readonly) MBBackgroundView *bezelView; + +/** + * View covering the entire HUD area, placed behind bezelView. + */ +@property (strong, nonatomic, readonly) MBBackgroundView *backgroundView; + +/** + * The UIView (e.g., a UIImageView) to be shown when the HUD is in MBProgressHUDModeCustomView. + * The view should implement intrinsicContentSize for proper sizing. For best results use approximately 37 by 37 pixels. + */ +@property (strong, nonatomic, nullable) UIView *customView; + +/** + * A label that holds an optional short message to be displayed below the activity indicator. The HUD is automatically resized to fit + * the entire text. + */ +@property (strong, nonatomic, readonly) UILabel *label; + +/** + * A label that holds an optional details message displayed below the labelText message. The details text can span multiple lines. + */ +@property (strong, nonatomic, readonly) UILabel *detailsLabel; + +/** + * A button that is placed below the labels. Visible only if a target / action is added and a title is assigned.. + */ +@property (strong, nonatomic, readonly) UIButton *button; + +@end + + +@protocol MBProgressHUDDelegate + +@optional + +/** + * Called after the HUD was fully hidden from the screen. + */ +- (void)hudWasHidden:(MBProgressHUD *)hud; + +@end + + +/** + * A progress view for showing definite progress by filling up a circle (pie chart). + */ +@interface MBRoundProgressView : UIView + +/** + * Progress (0.0 to 1.0) + */ +@property (nonatomic, assign) float progress; + +/** + * Indicator progress color. + * Defaults to white [UIColor whiteColor]. + */ +@property (nonatomic, strong) UIColor *progressTintColor; + +/** + * Indicator background (non-progress) color. + * Only applicable on iOS versions older than iOS 7. + * Defaults to translucent white (alpha 0.1). + */ +@property (nonatomic, strong) UIColor *backgroundTintColor; + +/* + * Display mode - NO = round or YES = annular. Defaults to round. + */ +@property (nonatomic, assign, getter = isAnnular) BOOL annular; + +@end + + +/** + * A flat bar progress view. + */ +@interface MBBarProgressView : UIView + +/** + * Progress (0.0 to 1.0) + */ +@property (nonatomic, assign) float progress; + +/** + * Bar border line color. + * Defaults to white [UIColor whiteColor]. + */ +@property (nonatomic, strong) UIColor *lineColor; + +/** + * Bar background color. + * Defaults to clear [UIColor clearColor]; + */ +@property (nonatomic, strong) UIColor *progressRemainingColor; + +/** + * Bar progress color. + * Defaults to white [UIColor whiteColor]. + */ +@property (nonatomic, strong) UIColor *progressColor; + +@end + + +@interface MBBackgroundView : UIView + +/** + * The background style. + * Defaults to MBProgressHUDBackgroundStyleBlur. + */ +@property (nonatomic) MBProgressHUDBackgroundStyle style; + +/** + * The blur effect style, when using MBProgressHUDBackgroundStyleBlur. + * Defaults to UIBlurEffectStyleLight. + */ +@property (nonatomic) UIBlurEffectStyle blurEffectStyle; + +/** + * The background color or the blur tint color. + * + * Defaults to nil on iOS 13 and later and + * `[UIColor colorWithWhite:0.8f alpha:0.6f]` + * on older systems. + */ +@property (nonatomic, strong, nullable) UIColor *color; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SampleApp/Pods/MBProgressHUD/MBProgressHUD.m b/SampleApp/Pods/MBProgressHUD/MBProgressHUD.m new file mode 100644 index 0000000..a2829a3 --- /dev/null +++ b/SampleApp/Pods/MBProgressHUD/MBProgressHUD.m @@ -0,0 +1,1194 @@ +// +// MBProgressHUD.m +// Version 1.2.0 +// Created by Matej Bukovinski on 2.4.09. +// + +#import "MBProgressHUD.h" +#import + +#define MBMainThreadAssert() NSAssert([NSThread isMainThread], @"MBProgressHUD needs to be accessed on the main thread."); + +CGFloat const MBProgressMaxOffset = 1000000.f; + +static const CGFloat MBDefaultPadding = 4.f; +static const CGFloat MBDefaultLabelFontSize = 16.f; +static const CGFloat MBDefaultDetailsLabelFontSize = 12.f; + + +@interface MBProgressHUD () + +@property (nonatomic, assign) BOOL useAnimation; +@property (nonatomic, assign, getter=hasFinished) BOOL finished; +@property (nonatomic, strong) UIView *indicator; +@property (nonatomic, strong) NSDate *showStarted; +@property (nonatomic, strong) NSArray *paddingConstraints; +@property (nonatomic, strong) NSArray *bezelConstraints; +@property (nonatomic, strong) UIView *topSpacer; +@property (nonatomic, strong) UIView *bottomSpacer; +@property (nonatomic, strong) UIMotionEffectGroup *bezelMotionEffects; +@property (nonatomic, weak) NSTimer *graceTimer; +@property (nonatomic, weak) NSTimer *minShowTimer; +@property (nonatomic, weak) NSTimer *hideDelayTimer; +@property (nonatomic, weak) CADisplayLink *progressObjectDisplayLink; + +@end + + +@interface MBProgressHUDRoundedButton : UIButton +@end + + +@implementation MBProgressHUD + +#pragma mark - Class methods + ++ (instancetype)showHUDAddedTo:(UIView *)view animated:(BOOL)animated { + MBProgressHUD *hud = [[self alloc] initWithView:view]; + hud.removeFromSuperViewOnHide = YES; + [view addSubview:hud]; + [hud showAnimated:animated]; + return hud; +} + ++ (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated { + MBProgressHUD *hud = [self HUDForView:view]; + if (hud != nil) { + hud.removeFromSuperViewOnHide = YES; + [hud hideAnimated:animated]; + return YES; + } + return NO; +} + ++ (MBProgressHUD *)HUDForView:(UIView *)view { + NSEnumerator *subviewsEnum = [view.subviews reverseObjectEnumerator]; + for (UIView *subview in subviewsEnum) { + if ([subview isKindOfClass:self]) { + MBProgressHUD *hud = (MBProgressHUD *)subview; + if (hud.hasFinished == NO) { + return hud; + } + } + } + return nil; +} + +#pragma mark - Lifecycle + +- (void)commonInit { + // Set default values for properties + _animationType = MBProgressHUDAnimationFade; + _mode = MBProgressHUDModeIndeterminate; + _margin = 20.0f; + _defaultMotionEffectsEnabled = NO; + + if (@available(iOS 13.0, tvOS 13, *)) { + _contentColor = [[UIColor labelColor] colorWithAlphaComponent:0.7f]; + } else { + _contentColor = [UIColor colorWithWhite:0.f alpha:0.7f]; + } + + // Transparent background + self.opaque = NO; + self.backgroundColor = [UIColor clearColor]; + // Make it invisible for now + self.alpha = 0.0f; + self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.layer.allowsGroupOpacity = NO; + + [self setupViews]; + [self updateIndicators]; + [self registerForNotifications]; +} + +- (instancetype)initWithFrame:(CGRect)frame { + if ((self = [super initWithFrame:frame])) { + [self commonInit]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if ((self = [super initWithCoder:aDecoder])) { + [self commonInit]; + } + return self; +} + +- (id)initWithView:(UIView *)view { + NSAssert(view, @"View must not be nil."); + return [self initWithFrame:view.bounds]; +} + +- (void)dealloc { + [self unregisterFromNotifications]; +} + +#pragma mark - Show & hide + +- (void)showAnimated:(BOOL)animated { + MBMainThreadAssert(); + [self.minShowTimer invalidate]; + self.useAnimation = animated; + self.finished = NO; + // If the grace time is set, postpone the HUD display + if (self.graceTime > 0.0) { + NSTimer *timer = [NSTimer timerWithTimeInterval:self.graceTime target:self selector:@selector(handleGraceTimer:) userInfo:nil repeats:NO]; + [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; + self.graceTimer = timer; + } + // ... otherwise show the HUD immediately + else { + [self showUsingAnimation:self.useAnimation]; + } +} + +- (void)hideAnimated:(BOOL)animated { + MBMainThreadAssert(); + [self.graceTimer invalidate]; + self.useAnimation = animated; + self.finished = YES; + // If the minShow time is set, calculate how long the HUD was shown, + // and postpone the hiding operation if necessary + if (self.minShowTime > 0.0 && self.showStarted) { + NSTimeInterval interv = [[NSDate date] timeIntervalSinceDate:self.showStarted]; + if (interv < self.minShowTime) { + NSTimer *timer = [NSTimer timerWithTimeInterval:(self.minShowTime - interv) target:self selector:@selector(handleMinShowTimer:) userInfo:nil repeats:NO]; + [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; + self.minShowTimer = timer; + return; + } + } + // ... otherwise hide the HUD immediately + [self hideUsingAnimation:self.useAnimation]; +} + +- (void)hideAnimated:(BOOL)animated afterDelay:(NSTimeInterval)delay { + // Cancel any scheduled hideAnimated:afterDelay: calls + [self.hideDelayTimer invalidate]; + + NSTimer *timer = [NSTimer timerWithTimeInterval:delay target:self selector:@selector(handleHideTimer:) userInfo:@(animated) repeats:NO]; + [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; + self.hideDelayTimer = timer; +} + +#pragma mark - Timer callbacks + +- (void)handleGraceTimer:(NSTimer *)theTimer { + // Show the HUD only if the task is still running + if (!self.hasFinished) { + [self showUsingAnimation:self.useAnimation]; + } +} + +- (void)handleMinShowTimer:(NSTimer *)theTimer { + [self hideUsingAnimation:self.useAnimation]; +} + +- (void)handleHideTimer:(NSTimer *)timer { + [self hideAnimated:[timer.userInfo boolValue]]; +} + +#pragma mark - View Hierrarchy + +- (void)didMoveToSuperview { + [self updateForCurrentOrientationAnimated:NO]; +} + +#pragma mark - Internal show & hide operations + +- (void)showUsingAnimation:(BOOL)animated { + // Cancel any previous animations + [self.bezelView.layer removeAllAnimations]; + [self.backgroundView.layer removeAllAnimations]; + + // Cancel any scheduled hideAnimated:afterDelay: calls + [self.hideDelayTimer invalidate]; + + self.showStarted = [NSDate date]; + self.alpha = 1.f; + + // Needed in case we hide and re-show with the same NSProgress object attached. + [self setNSProgressDisplayLinkEnabled:YES]; + + // Set up motion effects only at this point to avoid needlessly + // creating the effect if it was disabled after initialization. + [self updateBezelMotionEffects]; + + if (animated) { + [self animateIn:YES withType:self.animationType completion:NULL]; + } else { + self.bezelView.alpha = 1.f; + self.backgroundView.alpha = 1.f; + } +} + +- (void)hideUsingAnimation:(BOOL)animated { + // Cancel any scheduled hideAnimated:afterDelay: calls. + // This needs to happen here instead of in done, + // to avoid races if another hideAnimated:afterDelay: + // call comes in while the HUD is animating out. + [self.hideDelayTimer invalidate]; + + if (animated && self.showStarted) { + self.showStarted = nil; + [self animateIn:NO withType:self.animationType completion:^(BOOL finished) { + [self done]; + }]; + } else { + self.showStarted = nil; + self.bezelView.alpha = 0.f; + self.backgroundView.alpha = 1.f; + [self done]; + } +} + +- (void)animateIn:(BOOL)animatingIn withType:(MBProgressHUDAnimation)type completion:(void(^)(BOOL finished))completion { + // Automatically determine the correct zoom animation type + if (type == MBProgressHUDAnimationZoom) { + type = animatingIn ? MBProgressHUDAnimationZoomIn : MBProgressHUDAnimationZoomOut; + } + + CGAffineTransform small = CGAffineTransformMakeScale(0.5f, 0.5f); + CGAffineTransform large = CGAffineTransformMakeScale(1.5f, 1.5f); + + // Set starting state + UIView *bezelView = self.bezelView; + if (animatingIn && bezelView.alpha == 0.f && type == MBProgressHUDAnimationZoomIn) { + bezelView.transform = small; + } else if (animatingIn && bezelView.alpha == 0.f && type == MBProgressHUDAnimationZoomOut) { + bezelView.transform = large; + } + + // Perform animations + dispatch_block_t animations = ^{ + if (animatingIn) { + bezelView.transform = CGAffineTransformIdentity; + } else if (!animatingIn && type == MBProgressHUDAnimationZoomIn) { + bezelView.transform = large; + } else if (!animatingIn && type == MBProgressHUDAnimationZoomOut) { + bezelView.transform = small; + } + CGFloat alpha = animatingIn ? 1.f : 0.f; + bezelView.alpha = alpha; + self.backgroundView.alpha = alpha; + }; + [UIView animateWithDuration:0.3 delay:0. usingSpringWithDamping:1.f initialSpringVelocity:0.f options:UIViewAnimationOptionBeginFromCurrentState animations:animations completion:completion]; +} + +- (void)done { + [self setNSProgressDisplayLinkEnabled:NO]; + + if (self.hasFinished) { + self.alpha = 0.0f; + if (self.removeFromSuperViewOnHide) { + [self removeFromSuperview]; + } + } + MBProgressHUDCompletionBlock completionBlock = self.completionBlock; + if (completionBlock) { + completionBlock(); + } + id delegate = self.delegate; + if ([delegate respondsToSelector:@selector(hudWasHidden:)]) { + [delegate performSelector:@selector(hudWasHidden:) withObject:self]; + } +} + +#pragma mark - UI + +- (void)setupViews { + UIColor *defaultColor = self.contentColor; + + MBBackgroundView *backgroundView = [[MBBackgroundView alloc] initWithFrame:self.bounds]; + backgroundView.style = MBProgressHUDBackgroundStyleSolidColor; + backgroundView.backgroundColor = [UIColor clearColor]; + backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + backgroundView.alpha = 0.f; + [self addSubview:backgroundView]; + _backgroundView = backgroundView; + + MBBackgroundView *bezelView = [MBBackgroundView new]; + bezelView.translatesAutoresizingMaskIntoConstraints = NO; + bezelView.layer.cornerRadius = 5.f; + bezelView.alpha = 0.f; + [self addSubview:bezelView]; + _bezelView = bezelView; + + UILabel *label = [UILabel new]; + label.adjustsFontSizeToFitWidth = NO; + label.textAlignment = NSTextAlignmentCenter; + label.textColor = defaultColor; + label.font = [UIFont boldSystemFontOfSize:MBDefaultLabelFontSize]; + label.opaque = NO; + label.backgroundColor = [UIColor clearColor]; + _label = label; + + UILabel *detailsLabel = [UILabel new]; + detailsLabel.adjustsFontSizeToFitWidth = NO; + detailsLabel.textAlignment = NSTextAlignmentCenter; + detailsLabel.textColor = defaultColor; + detailsLabel.numberOfLines = 0; + detailsLabel.font = [UIFont boldSystemFontOfSize:MBDefaultDetailsLabelFontSize]; + detailsLabel.opaque = NO; + detailsLabel.backgroundColor = [UIColor clearColor]; + _detailsLabel = detailsLabel; + + UIButton *button = [MBProgressHUDRoundedButton buttonWithType:UIButtonTypeCustom]; + button.titleLabel.textAlignment = NSTextAlignmentCenter; + button.titleLabel.font = [UIFont boldSystemFontOfSize:MBDefaultDetailsLabelFontSize]; + [button setTitleColor:defaultColor forState:UIControlStateNormal]; + _button = button; + + for (UIView *view in @[label, detailsLabel, button]) { + view.translatesAutoresizingMaskIntoConstraints = NO; + [view setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisHorizontal]; + [view setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisVertical]; + [bezelView addSubview:view]; + } + + UIView *topSpacer = [UIView new]; + topSpacer.translatesAutoresizingMaskIntoConstraints = NO; + topSpacer.hidden = YES; + [bezelView addSubview:topSpacer]; + _topSpacer = topSpacer; + + UIView *bottomSpacer = [UIView new]; + bottomSpacer.translatesAutoresizingMaskIntoConstraints = NO; + bottomSpacer.hidden = YES; + [bezelView addSubview:bottomSpacer]; + _bottomSpacer = bottomSpacer; +} + +- (void)updateIndicators { + UIView *indicator = self.indicator; + BOOL isActivityIndicator = [indicator isKindOfClass:[UIActivityIndicatorView class]]; + BOOL isRoundIndicator = [indicator isKindOfClass:[MBRoundProgressView class]]; + + MBProgressHUDMode mode = self.mode; + if (mode == MBProgressHUDModeIndeterminate) { + if (!isActivityIndicator) { + // Update to indeterminate indicator + UIActivityIndicatorView *activityIndicator; + [indicator removeFromSuperview]; +#if !TARGET_OS_MACCATALYST + if (@available(iOS 13.0, tvOS 13.0, *)) { +#endif + activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge]; + activityIndicator.color = [UIColor whiteColor]; +#if !TARGET_OS_MACCATALYST + } else { + activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; + } +#endif + [activityIndicator startAnimating]; + indicator = activityIndicator; + [self.bezelView addSubview:indicator]; + } + } + else if (mode == MBProgressHUDModeDeterminateHorizontalBar) { + // Update to bar determinate indicator + [indicator removeFromSuperview]; + indicator = [[MBBarProgressView alloc] init]; + [self.bezelView addSubview:indicator]; + } + else if (mode == MBProgressHUDModeDeterminate || mode == MBProgressHUDModeAnnularDeterminate) { + if (!isRoundIndicator) { + // Update to determinante indicator + [indicator removeFromSuperview]; + indicator = [[MBRoundProgressView alloc] init]; + [self.bezelView addSubview:indicator]; + } + if (mode == MBProgressHUDModeAnnularDeterminate) { + [(MBRoundProgressView *)indicator setAnnular:YES]; + } + } + else if (mode == MBProgressHUDModeCustomView && self.customView != indicator) { + // Update custom view indicator + [indicator removeFromSuperview]; + indicator = self.customView; + [self.bezelView addSubview:indicator]; + } + else if (mode == MBProgressHUDModeText) { + [indicator removeFromSuperview]; + indicator = nil; + } + indicator.translatesAutoresizingMaskIntoConstraints = NO; + self.indicator = indicator; + + if ([indicator respondsToSelector:@selector(setProgress:)]) { + [(id)indicator setValue:@(self.progress) forKey:@"progress"]; + } + + [indicator setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisHorizontal]; + [indicator setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisVertical]; + + [self updateViewsForColor:self.contentColor]; + [self setNeedsUpdateConstraints]; +} + +- (void)updateViewsForColor:(UIColor *)color { + if (!color) return; + + self.label.textColor = color; + self.detailsLabel.textColor = color; + [self.button setTitleColor:color forState:UIControlStateNormal]; + + // UIAppearance settings are prioritized. If they are preset the set color is ignored. + + UIView *indicator = self.indicator; + if ([indicator isKindOfClass:[UIActivityIndicatorView class]]) { + UIActivityIndicatorView *appearance = nil; +#if __IPHONE_OS_VERSION_MIN_REQUIRED < 90000 + appearance = [UIActivityIndicatorView appearanceWhenContainedIn:[MBProgressHUD class], nil]; +#else + // For iOS 9+ + appearance = [UIActivityIndicatorView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]]; +#endif + + if (appearance.color == nil) { + ((UIActivityIndicatorView *)indicator).color = color; + } + } else if ([indicator isKindOfClass:[MBRoundProgressView class]]) { + MBRoundProgressView *appearance = nil; +#if __IPHONE_OS_VERSION_MIN_REQUIRED < 90000 + appearance = [MBRoundProgressView appearanceWhenContainedIn:[MBProgressHUD class], nil]; +#else + appearance = [MBRoundProgressView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]]; +#endif + if (appearance.progressTintColor == nil) { + ((MBRoundProgressView *)indicator).progressTintColor = color; + } + if (appearance.backgroundTintColor == nil) { + ((MBRoundProgressView *)indicator).backgroundTintColor = [color colorWithAlphaComponent:0.1]; + } + } else if ([indicator isKindOfClass:[MBBarProgressView class]]) { + MBBarProgressView *appearance = nil; +#if __IPHONE_OS_VERSION_MIN_REQUIRED < 90000 + appearance = [MBBarProgressView appearanceWhenContainedIn:[MBProgressHUD class], nil]; +#else + appearance = [MBBarProgressView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]]; +#endif + if (appearance.progressColor == nil) { + ((MBBarProgressView *)indicator).progressColor = color; + } + if (appearance.lineColor == nil) { + ((MBBarProgressView *)indicator).lineColor = color; + } + } else { + [indicator setTintColor:color]; + } +} + +- (void)updateBezelMotionEffects { + MBBackgroundView *bezelView = self.bezelView; + UIMotionEffectGroup *bezelMotionEffects = self.bezelMotionEffects; + + if (self.defaultMotionEffectsEnabled && !bezelMotionEffects) { + CGFloat effectOffset = 10.f; + UIInterpolatingMotionEffect *effectX = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; + effectX.maximumRelativeValue = @(effectOffset); + effectX.minimumRelativeValue = @(-effectOffset); + + UIInterpolatingMotionEffect *effectY = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; + effectY.maximumRelativeValue = @(effectOffset); + effectY.minimumRelativeValue = @(-effectOffset); + + UIMotionEffectGroup *group = [[UIMotionEffectGroup alloc] init]; + group.motionEffects = @[effectX, effectY]; + + self.bezelMotionEffects = group; + [bezelView addMotionEffect:group]; + } else if (bezelMotionEffects) { + self.bezelMotionEffects = nil; + [bezelView removeMotionEffect:bezelMotionEffects]; + } +} + +#pragma mark - Layout + +- (void)updateConstraints { + UIView *bezel = self.bezelView; + UIView *topSpacer = self.topSpacer; + UIView *bottomSpacer = self.bottomSpacer; + CGFloat margin = self.margin; + NSMutableArray *bezelConstraints = [NSMutableArray array]; + NSDictionary *metrics = @{@"margin": @(margin)}; + + NSMutableArray *subviews = [NSMutableArray arrayWithObjects:self.topSpacer, self.label, self.detailsLabel, self.button, self.bottomSpacer, nil]; + if (self.indicator) [subviews insertObject:self.indicator atIndex:1]; + + // Remove existing constraints + [self removeConstraints:self.constraints]; + [topSpacer removeConstraints:topSpacer.constraints]; + [bottomSpacer removeConstraints:bottomSpacer.constraints]; + if (self.bezelConstraints) { + [bezel removeConstraints:self.bezelConstraints]; + self.bezelConstraints = nil; + } + + // Center bezel in container (self), applying the offset if set + CGPoint offset = self.offset; + NSMutableArray *centeringConstraints = [NSMutableArray array]; + [centeringConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.f constant:offset.x]]; + [centeringConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.f constant:offset.y]]; + [self applyPriority:998.f toConstraints:centeringConstraints]; + [self addConstraints:centeringConstraints]; + + // Ensure minimum side margin is kept + NSMutableArray *sideConstraints = [NSMutableArray array]; + [sideConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>=margin)-[bezel]-(>=margin)-|" options:0 metrics:metrics views:NSDictionaryOfVariableBindings(bezel)]]; + [sideConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(>=margin)-[bezel]-(>=margin)-|" options:0 metrics:metrics views:NSDictionaryOfVariableBindings(bezel)]]; + [self applyPriority:999.f toConstraints:sideConstraints]; + [self addConstraints:sideConstraints]; + + // Minimum bezel size, if set + CGSize minimumSize = self.minSize; + if (!CGSizeEqualToSize(minimumSize, CGSizeZero)) { + NSMutableArray *minSizeConstraints = [NSMutableArray array]; + [minSizeConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:minimumSize.width]]; + [minSizeConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:minimumSize.height]]; + [self applyPriority:997.f toConstraints:minSizeConstraints]; + [bezelConstraints addObjectsFromArray:minSizeConstraints]; + } + + // Square aspect ratio, if set + if (self.square) { + NSLayoutConstraint *square = [NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeWidth multiplier:1.f constant:0]; + square.priority = 997.f; + [bezelConstraints addObject:square]; + } + + // Top and bottom spacing + [topSpacer addConstraint:[NSLayoutConstraint constraintWithItem:topSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:margin]]; + [bottomSpacer addConstraint:[NSLayoutConstraint constraintWithItem:bottomSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:margin]]; + // Top and bottom spaces should be equal + [bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:topSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:bottomSpacer attribute:NSLayoutAttributeHeight multiplier:1.f constant:0.f]]; + + // Layout subviews in bezel + NSMutableArray *paddingConstraints = [NSMutableArray new]; + [subviews enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop) { + // Center in bezel + [bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeCenterX multiplier:1.f constant:0.f]]; + // Ensure the minimum edge margin is kept + [bezelConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>=margin)-[view]-(>=margin)-|" options:0 metrics:metrics views:NSDictionaryOfVariableBindings(view)]]; + // Element spacing + if (idx == 0) { + // First, ensure spacing to bezel edge + [bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeTop multiplier:1.f constant:0.f]]; + } else if (idx == subviews.count - 1) { + // Last, ensure spacing to bezel edge + [bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]]; + } + if (idx > 0) { + // Has previous + NSLayoutConstraint *padding = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:subviews[idx - 1] attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]; + [bezelConstraints addObject:padding]; + [paddingConstraints addObject:padding]; + } + }]; + + [bezel addConstraints:bezelConstraints]; + self.bezelConstraints = bezelConstraints; + + self.paddingConstraints = [paddingConstraints copy]; + [self updatePaddingConstraints]; + + [super updateConstraints]; +} + +- (void)layoutSubviews { + // There is no need to update constraints if they are going to + // be recreated in [super layoutSubviews] due to needsUpdateConstraints being set. + // This also avoids an issue on iOS 8, where updatePaddingConstraints + // would trigger a zombie object access. + if (!self.needsUpdateConstraints) { + [self updatePaddingConstraints]; + } + [super layoutSubviews]; +} + +- (void)updatePaddingConstraints { + // Set padding dynamically, depending on whether the view is visible or not + __block BOOL hasVisibleAncestors = NO; + [self.paddingConstraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *padding, NSUInteger idx, BOOL *stop) { + UIView *firstView = (UIView *)padding.firstItem; + UIView *secondView = (UIView *)padding.secondItem; + BOOL firstVisible = !firstView.hidden && !CGSizeEqualToSize(firstView.intrinsicContentSize, CGSizeZero); + BOOL secondVisible = !secondView.hidden && !CGSizeEqualToSize(secondView.intrinsicContentSize, CGSizeZero); + // Set if both views are visible or if there's a visible view on top that doesn't have padding + // added relative to the current view yet + padding.constant = (firstVisible && (secondVisible || hasVisibleAncestors)) ? MBDefaultPadding : 0.f; + hasVisibleAncestors |= secondVisible; + }]; +} + +- (void)applyPriority:(UILayoutPriority)priority toConstraints:(NSArray *)constraints { + for (NSLayoutConstraint *constraint in constraints) { + constraint.priority = priority; + } +} + +#pragma mark - Properties + +- (void)setMode:(MBProgressHUDMode)mode { + if (mode != _mode) { + _mode = mode; + [self updateIndicators]; + } +} + +- (void)setCustomView:(UIView *)customView { + if (customView != _customView) { + _customView = customView; + if (self.mode == MBProgressHUDModeCustomView) { + [self updateIndicators]; + } + } +} + +- (void)setOffset:(CGPoint)offset { + if (!CGPointEqualToPoint(offset, _offset)) { + _offset = offset; + [self setNeedsUpdateConstraints]; + } +} + +- (void)setMargin:(CGFloat)margin { + if (margin != _margin) { + _margin = margin; + [self setNeedsUpdateConstraints]; + } +} + +- (void)setMinSize:(CGSize)minSize { + if (!CGSizeEqualToSize(minSize, _minSize)) { + _minSize = minSize; + [self setNeedsUpdateConstraints]; + } +} + +- (void)setSquare:(BOOL)square { + if (square != _square) { + _square = square; + [self setNeedsUpdateConstraints]; + } +} + +- (void)setProgressObjectDisplayLink:(CADisplayLink *)progressObjectDisplayLink { + if (progressObjectDisplayLink != _progressObjectDisplayLink) { + [_progressObjectDisplayLink invalidate]; + + _progressObjectDisplayLink = progressObjectDisplayLink; + + [_progressObjectDisplayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; + } +} + +- (void)setProgressObject:(NSProgress *)progressObject { + if (progressObject != _progressObject) { + _progressObject = progressObject; + [self setNSProgressDisplayLinkEnabled:YES]; + } +} + +- (void)setProgress:(float)progress { + if (progress != _progress) { + _progress = progress; + UIView *indicator = self.indicator; + if ([indicator respondsToSelector:@selector(setProgress:)]) { + [(id)indicator setValue:@(self.progress) forKey:@"progress"]; + } + } +} + +- (void)setContentColor:(UIColor *)contentColor { + if (contentColor != _contentColor && ![contentColor isEqual:_contentColor]) { + _contentColor = contentColor; + [self updateViewsForColor:contentColor]; + } +} + +- (void)setDefaultMotionEffectsEnabled:(BOOL)defaultMotionEffectsEnabled { + if (defaultMotionEffectsEnabled != _defaultMotionEffectsEnabled) { + _defaultMotionEffectsEnabled = defaultMotionEffectsEnabled; + [self updateBezelMotionEffects]; + } +} + +#pragma mark - NSProgress + +- (void)setNSProgressDisplayLinkEnabled:(BOOL)enabled { + // We're using CADisplayLink, because NSProgress can change very quickly and observing it may starve the main thread, + // so we're refreshing the progress only every frame draw + if (enabled && self.progressObject) { + // Only create if not already active. + if (!self.progressObjectDisplayLink) { + self.progressObjectDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateProgressFromProgressObject)]; + } + } else { + self.progressObjectDisplayLink = nil; + } +} + +- (void)updateProgressFromProgressObject { + self.progress = self.progressObject.fractionCompleted; +} + +#pragma mark - Notifications + +- (void)registerForNotifications { +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + + [nc addObserver:self selector:@selector(statusBarOrientationDidChange:) + name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; +#endif +} + +- (void)unregisterFromNotifications { +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; +#endif +} + +#if !TARGET_OS_TV && !TARGET_OS_MACCATALYST +- (void)statusBarOrientationDidChange:(NSNotification *)notification { + UIView *superview = self.superview; + if (!superview) { + return; + } else { + [self updateForCurrentOrientationAnimated:YES]; + } +} +#endif + +- (void)updateForCurrentOrientationAnimated:(BOOL)animated { + // Stay in sync with the superview in any case + if (self.superview) { + self.frame = self.superview.bounds; + } + + // Not needed on iOS 8+, compile out when the deployment target allows, + // to avoid sharedApplication problems on extension targets +#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 + // Only needed pre iOS 8 when added to a window + BOOL iOS8OrLater = kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0; + if (iOS8OrLater || ![self.superview isKindOfClass:[UIWindow class]]) return; + + // Make extension friendly. Will not get called on extensions (iOS 8+) due to the above check. + // This just ensures we don't get a warning about extension-unsafe API. + Class UIApplicationClass = NSClassFromString(@"UIApplication"); + if (!UIApplicationClass || ![UIApplicationClass respondsToSelector:@selector(sharedApplication)]) return; + + UIApplication *application = [UIApplication performSelector:@selector(sharedApplication)]; + UIInterfaceOrientation orientation = application.statusBarOrientation; + CGFloat radians = 0; + + if (UIInterfaceOrientationIsLandscape(orientation)) { + radians = orientation == UIInterfaceOrientationLandscapeLeft ? -(CGFloat)M_PI_2 : (CGFloat)M_PI_2; + // Window coordinates differ! + self.bounds = CGRectMake(0, 0, self.bounds.size.height, self.bounds.size.width); + } else { + radians = orientation == UIInterfaceOrientationPortraitUpsideDown ? (CGFloat)M_PI : 0.f; + } + + if (animated) { + [UIView animateWithDuration:0.3 animations:^{ + self.transform = CGAffineTransformMakeRotation(radians); + }]; + } else { + self.transform = CGAffineTransformMakeRotation(radians); + } +#endif +} + +@end + + +@implementation MBRoundProgressView + +#pragma mark - Lifecycle + +- (id)init { + return [self initWithFrame:CGRectMake(0.f, 0.f, 37.f, 37.f)]; +} + +- (id)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + self.backgroundColor = [UIColor clearColor]; + self.opaque = NO; + _progress = 0.f; + _annular = NO; + _progressTintColor = [[UIColor alloc] initWithWhite:1.f alpha:1.f]; + _backgroundTintColor = [[UIColor alloc] initWithWhite:1.f alpha:.1f]; + } + return self; +} + +#pragma mark - Layout + +- (CGSize)intrinsicContentSize { + return CGSizeMake(37.f, 37.f); +} + +#pragma mark - Properties + +- (void)setProgress:(float)progress { + if (progress != _progress) { + _progress = progress; + [self setNeedsDisplay]; + } +} + +- (void)setProgressTintColor:(UIColor *)progressTintColor { + NSAssert(progressTintColor, @"The color should not be nil."); + if (progressTintColor != _progressTintColor && ![progressTintColor isEqual:_progressTintColor]) { + _progressTintColor = progressTintColor; + [self setNeedsDisplay]; + } +} + +- (void)setBackgroundTintColor:(UIColor *)backgroundTintColor { + NSAssert(backgroundTintColor, @"The color should not be nil."); + if (backgroundTintColor != _backgroundTintColor && ![backgroundTintColor isEqual:_backgroundTintColor]) { + _backgroundTintColor = backgroundTintColor; + [self setNeedsDisplay]; + } +} + +#pragma mark - Drawing + +- (void)drawRect:(CGRect)rect { + CGContextRef context = UIGraphicsGetCurrentContext(); + + if (_annular) { + // Draw background + CGFloat lineWidth = 2.f; + UIBezierPath *processBackgroundPath = [UIBezierPath bezierPath]; + processBackgroundPath.lineWidth = lineWidth; + processBackgroundPath.lineCapStyle = kCGLineCapButt; + CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); + CGFloat radius = (self.bounds.size.width - lineWidth)/2; + CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees + CGFloat endAngle = (2 * (float)M_PI) + startAngle; + [processBackgroundPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; + [_backgroundTintColor set]; + [processBackgroundPath stroke]; + // Draw progress + UIBezierPath *processPath = [UIBezierPath bezierPath]; + processPath.lineCapStyle = kCGLineCapSquare; + processPath.lineWidth = lineWidth; + endAngle = (self.progress * 2 * (float)M_PI) + startAngle; + [processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; + [_progressTintColor set]; + [processPath stroke]; + } else { + // Draw background + CGFloat lineWidth = 2.f; + CGRect allRect = self.bounds; + CGRect circleRect = CGRectInset(allRect, lineWidth/2.f, lineWidth/2.f); + CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); + [_progressTintColor setStroke]; + [_backgroundTintColor setFill]; + CGContextSetLineWidth(context, lineWidth); + CGContextStrokeEllipseInRect(context, circleRect); + // 90 degrees + CGFloat startAngle = - ((float)M_PI / 2.f); + // Draw progress + UIBezierPath *processPath = [UIBezierPath bezierPath]; + processPath.lineCapStyle = kCGLineCapButt; + processPath.lineWidth = lineWidth * 2.f; + CGFloat radius = (CGRectGetWidth(self.bounds) / 2.f) - (processPath.lineWidth / 2.f); + CGFloat endAngle = (self.progress * 2.f * (float)M_PI) + startAngle; + [processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; + // Ensure that we don't get color overlapping when _progressTintColor alpha < 1.f. + CGContextSetBlendMode(context, kCGBlendModeCopy); + [_progressTintColor set]; + [processPath stroke]; + } +} + +@end + + +@implementation MBBarProgressView + +#pragma mark - Lifecycle + +- (id)init { + return [self initWithFrame:CGRectMake(.0f, .0f, 120.0f, 20.0f)]; +} + +- (id)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + _progress = 0.f; + _lineColor = [UIColor whiteColor]; + _progressColor = [UIColor whiteColor]; + _progressRemainingColor = [UIColor clearColor]; + self.backgroundColor = [UIColor clearColor]; + self.opaque = NO; + } + return self; +} + +#pragma mark - Layout + +- (CGSize)intrinsicContentSize { + return CGSizeMake(120.f, 10.f); +} + +#pragma mark - Properties + +- (void)setProgress:(float)progress { + if (progress != _progress) { + _progress = progress; + [self setNeedsDisplay]; + } +} + +- (void)setProgressColor:(UIColor *)progressColor { + NSAssert(progressColor, @"The color should not be nil."); + if (progressColor != _progressColor && ![progressColor isEqual:_progressColor]) { + _progressColor = progressColor; + [self setNeedsDisplay]; + } +} + +- (void)setProgressRemainingColor:(UIColor *)progressRemainingColor { + NSAssert(progressRemainingColor, @"The color should not be nil."); + if (progressRemainingColor != _progressRemainingColor && ![progressRemainingColor isEqual:_progressRemainingColor]) { + _progressRemainingColor = progressRemainingColor; + [self setNeedsDisplay]; + } +} + +#pragma mark - Drawing + +- (void)drawRect:(CGRect)rect { + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGContextSetLineWidth(context, 2); + CGContextSetStrokeColorWithColor(context,[_lineColor CGColor]); + CGContextSetFillColorWithColor(context, [_progressRemainingColor CGColor]); + + // Draw background and Border + CGFloat radius = (rect.size.height / 2) - 2; + CGContextMoveToPoint(context, 2, rect.size.height/2); + CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius); + CGContextAddArcToPoint(context, rect.size.width - 2, 2, rect.size.width - 2, rect.size.height / 2, radius); + CGContextAddArcToPoint(context, rect.size.width - 2, rect.size.height - 2, rect.size.width - radius - 2, rect.size.height - 2, radius); + CGContextAddArcToPoint(context, 2, rect.size.height - 2, 2, rect.size.height/2, radius); + CGContextDrawPath(context, kCGPathFillStroke); + + CGContextSetFillColorWithColor(context, [_progressColor CGColor]); + radius = radius - 2; + CGFloat amount = self.progress * rect.size.width; + + // Progress in the middle area + if (amount >= radius + 4 && amount <= (rect.size.width - radius - 4)) { + CGContextMoveToPoint(context, 4, rect.size.height/2); + CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius); + CGContextAddLineToPoint(context, amount, 4); + CGContextAddLineToPoint(context, amount, radius + 4); + + CGContextMoveToPoint(context, 4, rect.size.height/2); + CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius); + CGContextAddLineToPoint(context, amount, rect.size.height - 4); + CGContextAddLineToPoint(context, amount, radius + 4); + + CGContextFillPath(context); + } + + // Progress in the right arc + else if (amount > radius + 4) { + CGFloat x = amount - (rect.size.width - radius - 4); + + CGContextMoveToPoint(context, 4, rect.size.height/2); + CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius); + CGContextAddLineToPoint(context, rect.size.width - radius - 4, 4); + CGFloat angle = -acos(x/radius); + if (isnan(angle)) angle = 0; + CGContextAddArc(context, rect.size.width - radius - 4, rect.size.height/2, radius, M_PI, angle, 0); + CGContextAddLineToPoint(context, amount, rect.size.height/2); + + CGContextMoveToPoint(context, 4, rect.size.height/2); + CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius); + CGContextAddLineToPoint(context, rect.size.width - radius - 4, rect.size.height - 4); + angle = acos(x/radius); + if (isnan(angle)) angle = 0; + CGContextAddArc(context, rect.size.width - radius - 4, rect.size.height/2, radius, -M_PI, angle, 1); + CGContextAddLineToPoint(context, amount, rect.size.height/2); + + CGContextFillPath(context); + } + + // Progress is in the left arc + else if (amount < radius + 4 && amount > 0) { + CGContextMoveToPoint(context, 4, rect.size.height/2); + CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius); + CGContextAddLineToPoint(context, radius + 4, rect.size.height/2); + + CGContextMoveToPoint(context, 4, rect.size.height/2); + CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius); + CGContextAddLineToPoint(context, radius + 4, rect.size.height/2); + + CGContextFillPath(context); + } +} + +@end + + +@interface MBBackgroundView () + +@property UIVisualEffectView *effectView; + +@end + + +@implementation MBBackgroundView + +#pragma mark - Lifecycle + +- (instancetype)initWithFrame:(CGRect)frame { + if ((self = [super initWithFrame:frame])) { + _style = MBProgressHUDBackgroundStyleBlur; + if (@available(iOS 13.0, *)) { + #if TARGET_OS_TV + _blurEffectStyle = UIBlurEffectStyleRegular; + #else + _blurEffectStyle = UIBlurEffectStyleSystemThickMaterial; + #endif + // Leaving the color unassigned yields best results. + } else { + _blurEffectStyle = UIBlurEffectStyleLight; + _color = [UIColor colorWithWhite:0.8f alpha:0.6f]; + } + + self.clipsToBounds = YES; + + [self updateForBackgroundStyle]; + } + return self; +} + +#pragma mark - Layout + +- (CGSize)intrinsicContentSize { + // Smallest size possible. Content pushes against this. + return CGSizeZero; +} + +#pragma mark - Appearance + +- (void)setStyle:(MBProgressHUDBackgroundStyle)style { + if (_style != style) { + _style = style; + [self updateForBackgroundStyle]; + } +} + +- (void)setColor:(UIColor *)color { + NSAssert(color, @"The color should not be nil."); + if (color != _color && ![color isEqual:_color]) { + _color = color; + [self updateViewsForColor:color]; + } +} + +- (void)setBlurEffectStyle:(UIBlurEffectStyle)blurEffectStyle { + if (_blurEffectStyle == blurEffectStyle) { + return; + } + + _blurEffectStyle = blurEffectStyle; + + [self updateForBackgroundStyle]; +} + +/////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - Views + +- (void)updateForBackgroundStyle { + [self.effectView removeFromSuperview]; + self.effectView = nil; + + MBProgressHUDBackgroundStyle style = self.style; + if (style == MBProgressHUDBackgroundStyleBlur) { + UIBlurEffect *effect = [UIBlurEffect effectWithStyle:self.blurEffectStyle]; + UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect]; + [self insertSubview:effectView atIndex:0]; + effectView.frame = self.bounds; + effectView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; + self.backgroundColor = self.color; + self.layer.allowsGroupOpacity = NO; + self.effectView = effectView; + } else { + self.backgroundColor = self.color; + } +} + +- (void)updateViewsForColor:(UIColor *)color { + if (self.style == MBProgressHUDBackgroundStyleBlur) { + self.backgroundColor = self.color; + } else { + self.backgroundColor = self.color; + } +} + +@end + + +@implementation MBProgressHUDRoundedButton + +#pragma mark - Lifecycle + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + CALayer *layer = self.layer; + layer.borderWidth = 1.f; + } + return self; +} + +#pragma mark - Layout + +- (void)layoutSubviews { + [super layoutSubviews]; + // Fully rounded corners + CGFloat height = CGRectGetHeight(self.bounds); + self.layer.cornerRadius = ceil(height / 2.f); +} + +- (CGSize)intrinsicContentSize { + // Only show if we have associated control events and a title + if ((self.allControlEvents == 0) || ([self titleForState:UIControlStateNormal].length == 0)) + return CGSizeZero; + CGSize size = [super intrinsicContentSize]; + // Add some side padding + size.width += 20.f; + return size; +} + +#pragma mark - Color + +- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state { + [super setTitleColor:color forState:state]; + // Update related colors + [self setHighlighted:self.highlighted]; + self.layer.borderColor = color.CGColor; +} + +- (void)setHighlighted:(BOOL)highlighted { + [super setHighlighted:highlighted]; + UIColor *baseColor = [self titleColorForState:UIControlStateSelected]; + self.backgroundColor = highlighted ? [baseColor colorWithAlphaComponent:0.1f] : [UIColor clearColor]; +} + +@end diff --git a/SampleApp/Pods/MBProgressHUD/README.mdown b/SampleApp/Pods/MBProgressHUD/README.mdown new file mode 100644 index 0000000..c90f5c6 --- /dev/null +++ b/SampleApp/Pods/MBProgressHUD/README.mdown @@ -0,0 +1,138 @@ +# MBProgressHUD + +[![Build Status](https://travis-ci.org/matej/MBProgressHUD.svg?branch=master)](https://travis-ci.org/matej/MBProgressHUD) [![codecov.io](https://codecov.io/github/matej/MBProgressHUD/coverage.svg?branch=master)](https://codecov.io/github/matej/MBProgressHUD?branch=master) + [![SwiftPM compatible](https://img.shields.io/badge/SwiftPM-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) [![Accio supported](https://img.shields.io/badge/Accio-supported-0A7CF5.svg?style=flat)](https://github.com/JamitLabs/Accio) [![CocoaPods compatible](https://img.shields.io/cocoapods/v/MBProgressHUD.svg?style=flat)](https://cocoapods.org/pods/MBProgressHUD) [![License: MIT](https://img.shields.io/cocoapods/l/MBProgressHUD.svg?style=flat)](http://opensource.org/licenses/MIT) + +`MBProgressHUD` is an iOS drop-in class that displays a translucent HUD with an indicator and/or labels while work is being done in a background thread. The HUD is meant as a replacement for the undocumented, private `UIKit` `UIProgressHUD` with some additional features. + +[![](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/1-small.png)](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/1.png) +[![](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/2-small.png)](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/2.png) +[![](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/3-small.png)](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/3.png) +[![](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/4-small.png)](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/4.png) +[![](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/5-small.png)](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/5.png) +[![](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/6-small.png)](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/6.png) +[![](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/7-small.png)](https://raw.githubusercontent.com/wiki/matej/MBProgressHUD/Screenshots/7.png) + +**NOTE:** The class has recently undergone a major rewrite. The old version is available in the [legacy](https://github.com/jdg/MBProgressHUD/tree/legacy) branch, should you need it. + +## Requirements + +`MBProgressHUD` works on iOS 9.0+. It depends on the following Apple frameworks, which should already be included with most Xcode templates: + +* Foundation.framework +* UIKit.framework +* CoreGraphics.framework + +You will need the latest developer tools in order to build `MBProgressHUD`. Old Xcode versions might work, but compatibility will not be explicitly maintained. + +## Adding MBProgressHUD to your project + +### CocoaPods + +[CocoaPods](http://cocoapods.org) is the recommended way to add MBProgressHUD to your project. + +1. Add a pod entry for MBProgressHUD to your Podfile `pod 'MBProgressHUD', '~> 1.2.0'` +2. Install the pod(s) by running `pod install`. +3. Include MBProgressHUD wherever you need it with `#import "MBProgressHUD.h"`. + +### Carthage + +1. Add MBProgressHUD to your Cartfile. e.g., `github "jdg/MBProgressHUD" ~> 1.2.0` +2. Run `carthage update` +3. Follow the rest of the [standard Carthage installation instructions](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) to add MBProgressHUD to your project. + +### SwiftPM / Accio + +1. Add the following to your `Package.swift`: + ```swift + .package(url: "https://github.com/jdg/MBProgressHUD.git", .upToNextMajor(from: "1.2.0")), + ``` +2. Next, add `MBProgressHUD` to your App targets dependencies like so: + ```swift + .target(name: "App", dependencies: ["MBProgressHUD"]), + ``` +3. Then open your project in Xcode 11+ (SwiftPM) or run `accio update` (Accio). + +### Source files + +Alternatively you can directly add the `MBProgressHUD.h` and `MBProgressHUD.m` source files to your project. + +1. Download the [latest code version](https://github.com/matej/MBProgressHUD/archive/master.zip) or add the repository as a git submodule to your git-tracked project. +2. Open your project in Xcode, then drag and drop `MBProgressHUD.h` and `MBProgressHUD.m` onto your project (use the "Product Navigator view"). Make sure to select Copy items when asked if you extracted the code archive outside of your project. +3. Include MBProgressHUD wherever you need it with `#import "MBProgressHUD.h"`. + +### Static library + +You can also add MBProgressHUD as a static library to your project or workspace. + +1. Download the [latest code version](https://github.com/matej/MBProgressHUD/downloads) or add the repository as a git submodule to your git-tracked project. +2. Open your project in Xcode, then drag and drop `MBProgressHUD.xcodeproj` onto your project or workspace (use the "Product Navigator view"). +3. Select your target and go to the Build phases tab. In the Link Binary With Libraries section select the add button. On the sheet find and add `libMBProgressHUD.a`. You might also need to add `MBProgressHUD` to the Target Dependencies list. +4. Include MBProgressHUD wherever you need it with `#import `. + +## Usage + +The main guideline you need to follow when dealing with MBProgressHUD while running long-running tasks is keeping the main thread work-free, so the UI can be updated promptly. The recommended way of using MBProgressHUD is therefore to set it up on the main thread and then spinning the task, that you want to perform, off onto a new thread. + +```objective-c +[MBProgressHUD showHUDAddedTo:self.view animated:YES]; +dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ + // Do something... + dispatch_async(dispatch_get_main_queue(), ^{ + [MBProgressHUD hideHUDForView:self.view animated:YES]; + }); +}); +``` + +You can add the HUD on any view or window. It is however a good idea to avoid adding the HUD to certain `UIKit` views with complex view hierarchies - like `UITableView` or `UICollectionView`. Those can mutate their subviews in unexpected ways and thereby break HUD display. + +If you need to configure the HUD you can do this by using the MBProgressHUD reference that showHUDAddedTo:animated: returns. + +```objective-c +MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; +hud.mode = MBProgressHUDModeAnnularDeterminate; +hud.label.text = @"Loading"; +[self doSomethingInBackgroundWithProgressCallback:^(float progress) { + hud.progress = progress; +} completionCallback:^{ + [hud hideAnimated:YES]; +}]; +``` + +You can also use a `NSProgress` object and MBProgressHUD will update itself when there is progress reported through that object. + +```objective-c +MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; +hud.mode = MBProgressHUDModeAnnularDeterminate; +hud.label.text = @"Loading"; +NSProgress *progress = [self doSomethingInBackgroundCompletion:^{ + [hud hideAnimated:YES]; +}]; +hud.progressObject = progress; +``` + +Keep in mind that UI updates, inclining calls to MBProgressHUD should always be done on the main thread. + +If you need to run your long-running task in the main thread, you should perform it with a slight delay, so UIKit will have enough time to update the UI (i.e., draw the HUD) before you block the main thread with your task. + +```objective-c +[MBProgressHUD showHUDAddedTo:self.view animated:YES]; +dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC); +dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ + // Do something... + [MBProgressHUD hideHUDForView:self.view animated:YES]; +}); +``` + +You should be aware that any HUD updates issued inside the above block won't be displayed until the block completes. + +For more examples, including how to use MBProgressHUD with asynchronous operations such as NSURLConnection, take a look at the bundled demo project. Extensive API documentation is provided in the header file (MBProgressHUD.h). + + +## License + +This code is distributed under the terms and conditions of the [MIT license](LICENSE). + +## Change-log + +A brief summary of each MBProgressHUD release can be found in the [CHANGELOG](CHANGELOG.mdown). diff --git a/SampleApp/Pods/Manifest.lock b/SampleApp/Pods/Manifest.lock new file mode 100644 index 0000000..3a08354 --- /dev/null +++ b/SampleApp/Pods/Manifest.lock @@ -0,0 +1,27 @@ +PODS: + - IQKeyboardManagerSwift (6.5.16) + - MBProgressHUD (1.2.0) + - PayFortSDK (3.2.0) + +DEPENDENCIES: + - IQKeyboardManagerSwift + - MBProgressHUD + - PayFortSDK (from `/Users/cetozgen/gitprivaterepos/fort-ios-sdk-localtest/`) + +SPEC REPOS: + trunk: + - IQKeyboardManagerSwift + - MBProgressHUD + +EXTERNAL SOURCES: + PayFortSDK: + :path: "/Users/cetozgen/gitprivaterepos/fort-ios-sdk-localtest/" + +SPEC CHECKSUMS: + IQKeyboardManagerSwift: 12d89768845bb77b55cc092ecc2b1f9370f06b76 + MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406 + PayFortSDK: 92d7df56734bd520241250ebc9b93987782b33b9 + +PODFILE CHECKSUM: 8037295a3735c99e78f5a1b1d37cac6edcee2814 + +COCOAPODS: 1.14.3 diff --git a/SampleApp/Pods/Pods.xcodeproj/project.pbxproj b/SampleApp/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..6787ecb --- /dev/null +++ b/SampleApp/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,1242 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 662261F7D9ECF9ED37726F62D8D69AC4 /* PayFortSDK */ = { + isa = PBXAggregateTarget; + buildConfigurationList = E2603FA0411795062C7DD4C333C7B8D6 /* Build configuration list for PBXAggregateTarget "PayFortSDK" */; + buildPhases = ( + A6D33E6929B694CB81D0D996B1FB2EC2 /* [CP] Copy XCFrameworks */, + ); + dependencies = ( + ); + name = PayFortSDK; + productName = PayFortSDK; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 0097064E7F7D3F413161738CC5C25EEC /* MBProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = A43F4159C8CD2DC1B000549C8AE913ED /* MBProgressHUD.m */; }; + 07F83DE63FB5CC8015F48F7B9B800B6F /* IQPreviousNextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D65979FB5F31186D265B96A66BAAD2FE /* IQPreviousNextView.swift */; }; + 07FD274BC01F578C7B37989F79350C1E /* IQToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B7741F0D8340E5B1F6AC973F542C617 /* IQToolbar.swift */; }; + 0874E6176184E3A1C3E8AB158AE5E98B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 840FA0B75AF62912A30DDC66B647ED98 /* CoreGraphics.framework */; }; + 0AA33EBB857A5205F87C09CCB99EAC74 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79CF7D56C5D50C18B2EA0ED106D998C7 /* Foundation.framework */; }; + 16E5F9C7FE2C499D21F3E7AF1FFC2FA7 /* IQKeyboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB7DE74DEFF1D7CD723BE95DCC308665 /* IQKeyboardManager.swift */; }; + 19C5CA44D4D4D5B711D33A73525D453F /* IQUIView+IQKeyboardToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BD15F5586A3312B66B8589C67AC1D08 /* IQUIView+IQKeyboardToolbar.swift */; }; + 1B4B180E84924CF99663817A2AFFAA92 /* IQKeyboardManager+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 117D43A4DC2D26F369426791AB89B39F /* IQKeyboardManager+Debug.swift */; }; + 373502D50A1B2266D86409E19EC46DDB /* IQTitleBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C4E0A0DA73B1E887E065FABC45D6407 /* IQTitleBarButtonItem.swift */; }; + 41A536E6CE1C85116A756B710B2C660B /* IQKeyboardManagerConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = B72F87F2B565E955CC2CD2E813A722AD /* IQKeyboardManagerConstants.swift */; }; + 4BAE34A926788C6052F2041FB5FA9AFB /* Pods-SampleAppTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CB89A545F0A33DAC71C4D412053C9E3 /* Pods-SampleAppTests-dummy.m */; }; + 506C1EE2968687F178BB2DFA34D185CE /* IQKeyboardReturnKeyHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3226929ED31813356C191E46AE59507 /* IQKeyboardReturnKeyHandler.swift */; }; + 55C0E9FA1EB9D7A703E748483AF7FC5F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79CF7D56C5D50C18B2EA0ED106D998C7 /* Foundation.framework */; }; + 58C91B4AB36E6B16421106CA634C58EF /* MBProgressHUD-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 40D4ACC655D7FFD5AC76B4B3531F28BA /* MBProgressHUD-dummy.m */; }; + 5BAC1EF86D0E57E44E404B2796993561 /* MBProgressHUD-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CBDFCC1E894CD4C7D08BBDC5CDA4F89 /* MBProgressHUD-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5E8E9469BF126E918EADF79EC4BB5CA2 /* IQUIView+Hierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3967DC2E0822F7880DC6646729145D48 /* IQUIView+Hierarchy.swift */; }; + 647D16586EBBE25158E3FD684541A1DD /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79CF7D56C5D50C18B2EA0ED106D998C7 /* Foundation.framework */; }; + 65EF71F9C792D0CDE18F13D1C6AC59A4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79CF7D56C5D50C18B2EA0ED106D998C7 /* Foundation.framework */; }; + 6735E4B11C64D20B4E05A92811F5A721 /* IQKeyboardManager+Internal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615E30F03C2E5D0F243F69D6240308F0 /* IQKeyboardManager+Internal.swift */; }; + 67E941CADB3CDDEEDF8CE4EE4A4A05BB /* MBProgressHUD.h in Headers */ = {isa = PBXBuildFile; fileRef = 32E3535CAF8246F6ED1C1AE63F7D2B7B /* MBProgressHUD.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7E59ABF8A1AC8F61FEFB9B8C72EFB9E5 /* IQKeyboardManager+Position.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2220754CECED28FEE31F212CB88C1168 /* IQKeyboardManager+Position.swift */; }; + 930B495B7A3197730A016E2339A4CBA7 /* IQKeyboardManagerSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = DFEBD86C35F67826AEBFF4B19328A950 /* IQKeyboardManagerSwift-dummy.m */; }; + 97EA46DA072EC4FD4D831606095B92C1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04D60AC13D33197690A05C641925DDDA /* UIKit.framework */; }; + 9C2584A9CCF8CA6C9DF2AD79DB831E70 /* IQKeyboardManager+UIKeyboardNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C652A2BBF1C5C3FF28218AB4A84E26 /* IQKeyboardManager+UIKeyboardNotification.swift */; }; + 9C292E2C761CB97ACD00F95FA4D60E85 /* IQKeyboardManager+OrientationNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B29D922E2395D210E3172969F3260F5 /* IQKeyboardManager+OrientationNotification.swift */; }; + 9E4E278A3C1543798E1912699886023E /* IQKeyboardManager+UITextFieldViewNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 704B239E872F2E1A5D1DB832E9FE6FC6 /* IQKeyboardManager+UITextFieldViewNotification.swift */; }; + A50A72FCD270217D99ECA1D2700CFAD4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 30869E70A08F4DE3DC5EE9819F0E6986 /* PrivacyInfo.xcprivacy */; }; + A8C0CBBC63C39A8C10083CBCA172F7CF /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A42DBD2F42D55606EEBA514009498B87 /* QuartzCore.framework */; }; + A8DD3F39B4D1F0C7B11866484A03336E /* IQInvocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F4A0E82C3AED8706186C9FFB12F6114 /* IQInvocation.swift */; }; + AAC2529A1B4F4832A052B348C5093018 /* IQUIScrollView+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C24B38C65ADECD357CF9CFCBBC7605C /* IQUIScrollView+Additions.swift */; }; + AB651DB3A97A623234B6544AD030406A /* IQNSArray+Sort.swift in Sources */ = {isa = PBXBuildFile; fileRef = D32CF72E3177898F03B4D561825AC9E2 /* IQNSArray+Sort.swift */; }; + AFAC1D4EBD53A048346210536741DF13 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 840FA0B75AF62912A30DDC66B647ED98 /* CoreGraphics.framework */; }; + B0CB5FB63262E1A67317045B8960F363 /* IQBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A87B6C73F69AFC5DA26DA292C0620A5E /* IQBarButtonItem.swift */; }; + B46A36CA19ED6C09341D8E4031F66D5C /* IQUIViewController+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDF66C7D3E2F5CC2B751067F94B129E /* IQUIViewController+Additions.swift */; }; + B52177FF72FDAC3EDB7195DE98F5501E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A42DBD2F42D55606EEBA514009498B87 /* QuartzCore.framework */; }; + BDAD667B60A9D9981738646851C825A0 /* IQKeyboardManager+Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A3AD9443472D230B16226838760E9D2 /* IQKeyboardManager+Toolbar.swift */; }; + BE60EC19FCBB8F301081E9C31BB85F3E /* IQUITextFieldView+Additions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54F857139FF44F7A533E96377E206454 /* IQUITextFieldView+Additions.swift */; }; + C0BF33AED6CF67DF46035C682136A8B8 /* Pods-SampleApp-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = F615AAEF2B52C77CB58F0559C3C06FA3 /* Pods-SampleApp-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C6C54C35A7F00A082F727BBBBCC1AE22 /* Pods-SampleAppTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 94F94E44CDFE480C981D3A0BACE2682C /* Pods-SampleAppTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D0DF994786BCEC54939BC8216B42FBC4 /* IQTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A9512A116A553E8672310AFBEFE2DDB /* IQTextView.swift */; }; + D4E2EAD773A30B252B6AD6B99A7490F4 /* IQKeyboardManagerSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 736E83072B05AF87A5959C615C5ECA4A /* IQKeyboardManagerSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + ECAA15FA3C4560E3287F2226EC8C1ECF /* IQKeyboardManagerConstantsInternal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26FABD4023BA92AB6E87EB272545B9A6 /* IQKeyboardManagerConstantsInternal.swift */; }; + F30DB14958FB08C46E4DFDDD0856634B /* Pods-SampleApp-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = DDDDB402D58ADC1B6D96BCC61F1C812C /* Pods-SampleApp-dummy.m */; }; + F47587932A67D8E3820DAFD9A0E1995E /* IQPlaceholderable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66781881B8546849DC72F0157F6F6AB7 /* IQPlaceholderable.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 1F38A1035ED58E10C702E249B8543C5D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 82B0A41D3031FF27D78E17B0A9A46FB0; + remoteInfo = MBProgressHUD; + }; + 46E140B292283F5A8600F5CEBA9CBB11 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = B490E7485944099E16C9CBD79119D1D4; + remoteInfo = IQKeyboardManagerSwift; + }; + 83EE6A9FF089FEE2CF517B72F3400B76 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 662261F7D9ECF9ED37726F62D8D69AC4; + remoteInfo = PayFortSDK; + }; + 9CA4F29C6244BF0522CE9F488829889C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7EFCCFB3480AA7EDB90F9DDD3E9E1D93; + remoteInfo = "Pods-SampleApp"; + }; +/* 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; }; + 117D43A4DC2D26F369426791AB89B39F /* IQKeyboardManager+Debug.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Debug.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+Debug.swift"; sourceTree = ""; }; + 1286CB6C8D1472DD6F3D2219B38DFF72 /* Pods-SampleApp */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-SampleApp"; path = Pods_SampleApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 17E3631780150F24F8015D04641CB0F4 /* Pods-SampleApp-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SampleApp-frameworks.sh"; sourceTree = ""; }; + 1C7814899343A9719B6447A10B0765A8 /* Pods-SampleAppTests */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-SampleAppTests"; path = Pods_SampleAppTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1CCD80F094CDDAA125D761B2B80BE9C2 /* Pods-SampleAppTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SampleAppTests-acknowledgements.plist"; sourceTree = ""; }; + 1D8B028A6F0097967C37DD5FDF6328C4 /* MBProgressHUD.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MBProgressHUD.debug.xcconfig; sourceTree = ""; }; + 20ED9CB133E893048C9341FDA94EE20C /* Pods-SampleApp-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-SampleApp-acknowledgements.markdown"; sourceTree = ""; }; + 2220754CECED28FEE31F212CB88C1168 /* IQKeyboardManager+Position.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Position.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+Position.swift"; sourceTree = ""; }; + 26FABD4023BA92AB6E87EB272545B9A6 /* IQKeyboardManagerConstantsInternal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManagerConstantsInternal.swift; path = IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstantsInternal.swift; sourceTree = ""; }; + 2B29D922E2395D210E3172969F3260F5 /* IQKeyboardManager+OrientationNotification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+OrientationNotification.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+OrientationNotification.swift"; sourceTree = ""; }; + 30869E70A08F4DE3DC5EE9819F0E6986 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = IQKeyboardManagerSwift/PrivacyInfo.xcprivacy; sourceTree = ""; }; + 32E3535CAF8246F6ED1C1AE63F7D2B7B /* MBProgressHUD.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = MBProgressHUD.h; sourceTree = ""; }; + 37C652A2BBF1C5C3FF28218AB4A84E26 /* IQKeyboardManager+UIKeyboardNotification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+UIKeyboardNotification.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+UIKeyboardNotification.swift"; sourceTree = ""; }; + 38CF4B81A5D0D715415FADC4AB2E2AB5 /* Pods-SampleAppTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-SampleAppTests-acknowledgements.markdown"; sourceTree = ""; }; + 3967DC2E0822F7880DC6646729145D48 /* IQUIView+Hierarchy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIView+Hierarchy.swift"; path = "IQKeyboardManagerSwift/Categories/IQUIView+Hierarchy.swift"; sourceTree = ""; }; + 3A9512A116A553E8672310AFBEFE2DDB /* IQTextView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQTextView.swift; path = IQKeyboardManagerSwift/IQTextView/IQTextView.swift; sourceTree = ""; }; + 3B4A4A68D4EF19CBE3F65987E27F642E /* Pods-SampleApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SampleApp.release.xcconfig"; sourceTree = ""; }; + 3BD15F5586A3312B66B8589C67AC1D08 /* IQUIView+IQKeyboardToolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIView+IQKeyboardToolbar.swift"; path = "IQKeyboardManagerSwift/IQToolbar/IQUIView+IQKeyboardToolbar.swift"; sourceTree = ""; }; + 3C4E0A0DA73B1E887E065FABC45D6407 /* IQTitleBarButtonItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQTitleBarButtonItem.swift; path = IQKeyboardManagerSwift/IQToolbar/IQTitleBarButtonItem.swift; sourceTree = ""; }; + 3F4A0E82C3AED8706186C9FFB12F6114 /* IQInvocation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQInvocation.swift; path = IQKeyboardManagerSwift/IQToolbar/IQInvocation.swift; sourceTree = ""; }; + 40D4ACC655D7FFD5AC76B4B3531F28BA /* MBProgressHUD-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "MBProgressHUD-dummy.m"; sourceTree = ""; }; + 41A578192A77618EB4E3C792FD1993B6 /* Pods-SampleApp.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-SampleApp.modulemap"; sourceTree = ""; }; + 4AAD59A98284115B921AA755FACE8B83 /* PayFortSDK.xcframework */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = wrapper.xcframework; path = PayFortSDK.xcframework; sourceTree = ""; }; + 4CBDFCC1E894CD4C7D08BBDC5CDA4F89 /* MBProgressHUD-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MBProgressHUD-umbrella.h"; sourceTree = ""; }; + 4D7487AE33B3E897F698D0A42D8C49EF /* Pods-SampleAppTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SampleAppTests.release.xcconfig"; sourceTree = ""; }; + 54F857139FF44F7A533E96377E206454 /* IQUITextFieldView+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUITextFieldView+Additions.swift"; path = "IQKeyboardManagerSwift/Categories/IQUITextFieldView+Additions.swift"; sourceTree = ""; }; + 5502D88D920F1D31DFB72943FEEA0E99 /* PayFortSDK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PayFortSDK.release.xcconfig; sourceTree = ""; }; + 575DD70BCFC57BD7EA6254764329EBE5 /* Pods-SampleApp-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SampleApp-acknowledgements.plist"; sourceTree = ""; }; + 5A4528AEAE3B6DA0D388D4C9E2CCB807 /* Pods-SampleAppTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-SampleAppTests.modulemap"; sourceTree = ""; }; + 615E30F03C2E5D0F243F69D6240308F0 /* IQKeyboardManager+Internal.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Internal.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+Internal.swift"; sourceTree = ""; }; + 63648FE3C8FD7C043CE96F3B48842668 /* LICENSE.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; path = LICENSE.md; sourceTree = ""; }; + 66781881B8546849DC72F0157F6F6AB7 /* IQPlaceholderable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQPlaceholderable.swift; path = IQKeyboardManagerSwift/IQTextView/IQPlaceholderable.swift; sourceTree = ""; }; + 6A3AD9443472D230B16226838760E9D2 /* IQKeyboardManager+Toolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+Toolbar.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+Toolbar.swift"; sourceTree = ""; }; + 6B7741F0D8340E5B1F6AC973F542C617 /* IQToolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQToolbar.swift; path = IQKeyboardManagerSwift/IQToolbar/IQToolbar.swift; sourceTree = ""; }; + 6FDF66C7D3E2F5CC2B751067F94B129E /* IQUIViewController+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIViewController+Additions.swift"; path = "IQKeyboardManagerSwift/Categories/IQUIViewController+Additions.swift"; sourceTree = ""; }; + 704A4676BE7F1DC06260B65425456491 /* Pods-SampleApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SampleApp.debug.xcconfig"; sourceTree = ""; }; + 704B239E872F2E1A5D1DB832E9FE6FC6 /* IQKeyboardManager+UITextFieldViewNotification.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQKeyboardManager+UITextFieldViewNotification.swift"; path = "IQKeyboardManagerSwift/IQKeyboardManager+UITextFieldViewNotification.swift"; sourceTree = ""; }; + 736E83072B05AF87A5959C615C5ECA4A /* IQKeyboardManagerSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "IQKeyboardManagerSwift-umbrella.h"; sourceTree = ""; }; + 7370BCABCE52090B619B9926D9ADD202 /* MBProgressHUD-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "MBProgressHUD-Info.plist"; sourceTree = ""; }; + 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; }; + 7A20EBB8E9E84D1391CDC47E522528E1 /* Pods-SampleAppTests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SampleAppTests-Info.plist"; sourceTree = ""; }; + 7AEE48D2020EB0A09C8E778D83583EF6 /* PayFortSDK-xcframeworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "PayFortSDK-xcframeworks.sh"; sourceTree = ""; }; + 8084217B599733E5018E7898D5A9624A /* IQKeyboardManagerSwift.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = IQKeyboardManagerSwift.release.xcconfig; sourceTree = ""; }; + 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; }; + 8B8FAB0D627B17EDE1366984278705D9 /* MBProgressHUD.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MBProgressHUD.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8C24B38C65ADECD357CF9CFCBBC7605C /* IQUIScrollView+Additions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQUIScrollView+Additions.swift"; path = "IQKeyboardManagerSwift/Categories/IQUIScrollView+Additions.swift"; sourceTree = ""; }; + 8DDE14519D9745CD24B9983940DE33D5 /* PayFortSDK.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PayFortSDK.debug.xcconfig; sourceTree = ""; }; + 94F94E44CDFE480C981D3A0BACE2682C /* Pods-SampleAppTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-SampleAppTests-umbrella.h"; sourceTree = ""; }; + 99AB43D243E076CC73376D1AC35937B2 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 9CB89A545F0A33DAC71C4D412053C9E3 /* Pods-SampleAppTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-SampleAppTests-dummy.m"; sourceTree = ""; }; + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; 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; }; + A43F4159C8CD2DC1B000549C8AE913ED /* MBProgressHUD.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = MBProgressHUD.m; sourceTree = ""; }; + A5A404CB6D62C60B401A9F16BB27836C /* IQKeyboardManagerSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "IQKeyboardManagerSwift-prefix.pch"; sourceTree = ""; }; + A7FE0D3059AC245D4B71AD70C571CEF9 /* MBProgressHUD-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MBProgressHUD-prefix.pch"; sourceTree = ""; }; + A87B6C73F69AFC5DA26DA292C0620A5E /* IQBarButtonItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQBarButtonItem.swift; path = IQKeyboardManagerSwift/IQToolbar/IQBarButtonItem.swift; sourceTree = ""; }; + A8E950A16D00F649C54FFB30F81D7842 /* IQKeyboardManagerSwift */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = IQKeyboardManagerSwift; path = IQKeyboardManagerSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + AA8638FDA3F666FA56BA58C711318626 /* Pods-SampleAppTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SampleAppTests.debug.xcconfig"; sourceTree = ""; }; + AD90CF82C03D9A454CA04863E17DFBAE /* PayFortSDK.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; path = PayFortSDK.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + B72F87F2B565E955CC2CD2E813A722AD /* IQKeyboardManagerConstants.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManagerConstants.swift; path = IQKeyboardManagerSwift/Constants/IQKeyboardManagerConstants.swift; sourceTree = ""; }; + BA165F311EFFEDA1B09DB8BB1707D152 /* IQKeyboardManagerSwift-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "IQKeyboardManagerSwift-Info.plist"; sourceTree = ""; }; + BE0F495F7367B2C62B588DE27ECDAF69 /* MBProgressHUD.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MBProgressHUD.release.xcconfig; sourceTree = ""; }; + C6635540598CCD1CEF5F3E5E7C3E2A31 /* MBProgressHUD.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = MBProgressHUD.modulemap; sourceTree = ""; }; + C91C794C439C9997EC14651103FB83F5 /* IQKeyboardManagerSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = IQKeyboardManagerSwift.modulemap; sourceTree = ""; }; + CB7DE74DEFF1D7CD723BE95DCC308665 /* IQKeyboardManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardManager.swift; path = IQKeyboardManagerSwift/IQKeyboardManager.swift; sourceTree = ""; }; + D32CF72E3177898F03B4D561825AC9E2 /* IQNSArray+Sort.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "IQNSArray+Sort.swift"; path = "IQKeyboardManagerSwift/Categories/IQNSArray+Sort.swift"; sourceTree = ""; }; + D65979FB5F31186D265B96A66BAAD2FE /* IQPreviousNextView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQPreviousNextView.swift; path = IQKeyboardManagerSwift/IQToolbar/IQPreviousNextView.swift; sourceTree = ""; }; + D87E768073623C157A4BB54273736809 /* Pods-SampleApp-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SampleApp-Info.plist"; sourceTree = ""; }; + DDDDB402D58ADC1B6D96BCC61F1C812C /* Pods-SampleApp-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-SampleApp-dummy.m"; sourceTree = ""; }; + DFEBD86C35F67826AEBFF4B19328A950 /* IQKeyboardManagerSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "IQKeyboardManagerSwift-dummy.m"; sourceTree = ""; }; + E3226929ED31813356C191E46AE59507 /* IQKeyboardReturnKeyHandler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IQKeyboardReturnKeyHandler.swift; path = IQKeyboardManagerSwift/IQKeyboardReturnKeyHandler.swift; sourceTree = ""; }; + E8672BE1AB69EC66A4471A3BE0C4203A /* IQKeyboardManagerSwift.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = IQKeyboardManagerSwift.debug.xcconfig; sourceTree = ""; }; + F615AAEF2B52C77CB58F0559C3C06FA3 /* Pods-SampleApp-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-SampleApp-umbrella.h"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 59338DF3172C7314CF8E9B1F6414DFD0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 65EF71F9C792D0CDE18F13D1C6AC59A4 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 65BFC75CE1541E38446FFDA8AFF0DBEC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0874E6176184E3A1C3E8AB158AE5E98B /* CoreGraphics.framework in Frameworks */, + 647D16586EBBE25158E3FD684541A1DD /* Foundation.framework in Frameworks */, + A8C0CBBC63C39A8C10083CBCA172F7CF /* QuartzCore.framework in Frameworks */, + 97EA46DA072EC4FD4D831606095B92C1 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BF2ABAD1E82074A808865AD23AE52E6F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 55C0E9FA1EB9D7A703E748483AF7FC5F /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D6DC8F0C2894774845C1DD2E7CA07B0C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + AFAC1D4EBD53A048346210536741DF13 /* CoreGraphics.framework in Frameworks */, + 0AA33EBB857A5205F87C09CCB99EAC74 /* Foundation.framework in Frameworks */, + B52177FF72FDAC3EDB7195DE98F5501E /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 069929FE0F3CE80924EA4789E1C8C0FB /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + 31C944DBF2F670AC22FF90F414C7E6F1 /* Pods-SampleApp */, + 5F72FB039CB871BC0F83A148F64DCC19 /* Pods-SampleAppTests */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 2140F0D95967E9E9B7DADC77C635D043 /* Pod */ = { + isa = PBXGroup; + children = ( + 63648FE3C8FD7C043CE96F3B48842668 /* LICENSE.md */, + AD90CF82C03D9A454CA04863E17DFBAE /* PayFortSDK.podspec */, + 99AB43D243E076CC73376D1AC35937B2 /* README.md */, + ); + name = Pod; + sourceTree = ""; + }; + 31C944DBF2F670AC22FF90F414C7E6F1 /* Pods-SampleApp */ = { + isa = PBXGroup; + children = ( + 41A578192A77618EB4E3C792FD1993B6 /* Pods-SampleApp.modulemap */, + 20ED9CB133E893048C9341FDA94EE20C /* Pods-SampleApp-acknowledgements.markdown */, + 575DD70BCFC57BD7EA6254764329EBE5 /* Pods-SampleApp-acknowledgements.plist */, + DDDDB402D58ADC1B6D96BCC61F1C812C /* Pods-SampleApp-dummy.m */, + 17E3631780150F24F8015D04641CB0F4 /* Pods-SampleApp-frameworks.sh */, + D87E768073623C157A4BB54273736809 /* Pods-SampleApp-Info.plist */, + F615AAEF2B52C77CB58F0559C3C06FA3 /* Pods-SampleApp-umbrella.h */, + 704A4676BE7F1DC06260B65425456491 /* Pods-SampleApp.debug.xcconfig */, + 3B4A4A68D4EF19CBE3F65987E27F642E /* Pods-SampleApp.release.xcconfig */, + ); + name = "Pods-SampleApp"; + path = "Target Support Files/Pods-SampleApp"; + sourceTree = ""; + }; + 4B651E69B902CEFC14B8EAC429E4866D /* Support Files */ = { + isa = PBXGroup; + children = ( + 7AEE48D2020EB0A09C8E778D83583EF6 /* PayFortSDK-xcframeworks.sh */, + 8DDE14519D9745CD24B9983940DE33D5 /* PayFortSDK.debug.xcconfig */, + 5502D88D920F1D31DFB72943FEEA0E99 /* PayFortSDK.release.xcconfig */, + ); + name = "Support Files"; + path = "SampleApp/Pods/Target Support Files/PayFortSDK"; + sourceTree = ""; + }; + 5F72FB039CB871BC0F83A148F64DCC19 /* Pods-SampleAppTests */ = { + isa = PBXGroup; + children = ( + 5A4528AEAE3B6DA0D388D4C9E2CCB807 /* Pods-SampleAppTests.modulemap */, + 38CF4B81A5D0D715415FADC4AB2E2AB5 /* Pods-SampleAppTests-acknowledgements.markdown */, + 1CCD80F094CDDAA125D761B2B80BE9C2 /* Pods-SampleAppTests-acknowledgements.plist */, + 9CB89A545F0A33DAC71C4D412053C9E3 /* Pods-SampleAppTests-dummy.m */, + 7A20EBB8E9E84D1391CDC47E522528E1 /* Pods-SampleAppTests-Info.plist */, + 94F94E44CDFE480C981D3A0BACE2682C /* Pods-SampleAppTests-umbrella.h */, + AA8638FDA3F666FA56BA58C711318626 /* Pods-SampleAppTests.debug.xcconfig */, + 4D7487AE33B3E897F698D0A42D8C49EF /* Pods-SampleAppTests.release.xcconfig */, + ); + name = "Pods-SampleAppTests"; + path = "Target Support Files/Pods-SampleAppTests"; + sourceTree = ""; + }; + 66EF3369F116961B6F7EEA170D2E9E89 /* Pods */ = { + isa = PBXGroup; + children = ( + E7B54B76CB69D792D7445A1E728DD752 /* IQKeyboardManagerSwift */, + 9018DCAF7906C47C72140428B15E2050 /* MBProgressHUD */, + ); + name = Pods; + sourceTree = ""; + }; + 7B774A20EF8875CDD6B24485700B1F4A /* Support Files */ = { + isa = PBXGroup; + children = ( + C6635540598CCD1CEF5F3E5E7C3E2A31 /* MBProgressHUD.modulemap */, + 40D4ACC655D7FFD5AC76B4B3531F28BA /* MBProgressHUD-dummy.m */, + 7370BCABCE52090B619B9926D9ADD202 /* MBProgressHUD-Info.plist */, + A7FE0D3059AC245D4B71AD70C571CEF9 /* MBProgressHUD-prefix.pch */, + 4CBDFCC1E894CD4C7D08BBDC5CDA4F89 /* MBProgressHUD-umbrella.h */, + 1D8B028A6F0097967C37DD5FDF6328C4 /* MBProgressHUD.debug.xcconfig */, + BE0F495F7367B2C62B588DE27ECDAF69 /* MBProgressHUD.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/MBProgressHUD"; + sourceTree = ""; + }; + 80B6F98182269F0625676712154E2950 /* Resources */ = { + isa = PBXGroup; + children = ( + 30869E70A08F4DE3DC5EE9819F0E6986 /* PrivacyInfo.xcprivacy */, + ); + name = Resources; + sourceTree = ""; + }; + 8AC7EBE9C3EE19CFE501437C9E86C3D1 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 4AAD59A98284115B921AA755FACE8B83 /* PayFortSDK.xcframework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 9018DCAF7906C47C72140428B15E2050 /* MBProgressHUD */ = { + isa = PBXGroup; + children = ( + 32E3535CAF8246F6ED1C1AE63F7D2B7B /* MBProgressHUD.h */, + A43F4159C8CD2DC1B000549C8AE913ED /* MBProgressHUD.m */, + 7B774A20EF8875CDD6B24485700B1F4A /* Support Files */, + ); + path = MBProgressHUD; + sourceTree = ""; + }; + B84BD81AC7C02462EFA3F4C113F57178 /* Development Pods */ = { + isa = PBXGroup; + children = ( + DE8EB629BD8B0310F77DEAA3F445183F /* PayFortSDK */, + ); + name = "Development Pods"; + sourceTree = ""; + }; + BA4F31F07263C99FC76E66D632A59F09 /* Frameworks */ = { + isa = PBXGroup; + children = ( + F9D206BABE81E6BF0B9B23880B238CC7 /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + CED4E64019BD6538903DAC33C2CE590D /* Support Files */ = { + isa = PBXGroup; + children = ( + C91C794C439C9997EC14651103FB83F5 /* IQKeyboardManagerSwift.modulemap */, + DFEBD86C35F67826AEBFF4B19328A950 /* IQKeyboardManagerSwift-dummy.m */, + BA165F311EFFEDA1B09DB8BB1707D152 /* IQKeyboardManagerSwift-Info.plist */, + A5A404CB6D62C60B401A9F16BB27836C /* IQKeyboardManagerSwift-prefix.pch */, + 736E83072B05AF87A5959C615C5ECA4A /* IQKeyboardManagerSwift-umbrella.h */, + E8672BE1AB69EC66A4471A3BE0C4203A /* IQKeyboardManagerSwift.debug.xcconfig */, + 8084217B599733E5018E7898D5A9624A /* IQKeyboardManagerSwift.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/IQKeyboardManagerSwift"; + sourceTree = ""; + }; + CF1408CF629C7361332E53B88F7BD30C = { + isa = PBXGroup; + children = ( + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, + B84BD81AC7C02462EFA3F4C113F57178 /* Development Pods */, + BA4F31F07263C99FC76E66D632A59F09 /* Frameworks */, + 66EF3369F116961B6F7EEA170D2E9E89 /* Pods */, + FDE5B111D0EA7E63B2837610B7718584 /* Products */, + 069929FE0F3CE80924EA4789E1C8C0FB /* Targets Support Files */, + ); + sourceTree = ""; + }; + DE8EB629BD8B0310F77DEAA3F445183F /* PayFortSDK */ = { + isa = PBXGroup; + children = ( + 8AC7EBE9C3EE19CFE501437C9E86C3D1 /* Frameworks */, + 2140F0D95967E9E9B7DADC77C635D043 /* Pod */, + 4B651E69B902CEFC14B8EAC429E4866D /* Support Files */, + ); + name = PayFortSDK; + path = "/Users/cetozgen/gitprivaterepos/fort-ios-sdk-localtest"; + sourceTree = ""; + }; + E7B54B76CB69D792D7445A1E728DD752 /* IQKeyboardManagerSwift */ = { + isa = PBXGroup; + children = ( + A87B6C73F69AFC5DA26DA292C0620A5E /* IQBarButtonItem.swift */, + 3F4A0E82C3AED8706186C9FFB12F6114 /* IQInvocation.swift */, + CB7DE74DEFF1D7CD723BE95DCC308665 /* IQKeyboardManager.swift */, + 117D43A4DC2D26F369426791AB89B39F /* IQKeyboardManager+Debug.swift */, + 615E30F03C2E5D0F243F69D6240308F0 /* IQKeyboardManager+Internal.swift */, + 2B29D922E2395D210E3172969F3260F5 /* IQKeyboardManager+OrientationNotification.swift */, + 2220754CECED28FEE31F212CB88C1168 /* IQKeyboardManager+Position.swift */, + 6A3AD9443472D230B16226838760E9D2 /* IQKeyboardManager+Toolbar.swift */, + 37C652A2BBF1C5C3FF28218AB4A84E26 /* IQKeyboardManager+UIKeyboardNotification.swift */, + 704B239E872F2E1A5D1DB832E9FE6FC6 /* IQKeyboardManager+UITextFieldViewNotification.swift */, + B72F87F2B565E955CC2CD2E813A722AD /* IQKeyboardManagerConstants.swift */, + 26FABD4023BA92AB6E87EB272545B9A6 /* IQKeyboardManagerConstantsInternal.swift */, + E3226929ED31813356C191E46AE59507 /* IQKeyboardReturnKeyHandler.swift */, + D32CF72E3177898F03B4D561825AC9E2 /* IQNSArray+Sort.swift */, + 66781881B8546849DC72F0157F6F6AB7 /* IQPlaceholderable.swift */, + D65979FB5F31186D265B96A66BAAD2FE /* IQPreviousNextView.swift */, + 3A9512A116A553E8672310AFBEFE2DDB /* IQTextView.swift */, + 3C4E0A0DA73B1E887E065FABC45D6407 /* IQTitleBarButtonItem.swift */, + 6B7741F0D8340E5B1F6AC973F542C617 /* IQToolbar.swift */, + 8C24B38C65ADECD357CF9CFCBBC7605C /* IQUIScrollView+Additions.swift */, + 54F857139FF44F7A533E96377E206454 /* IQUITextFieldView+Additions.swift */, + 3967DC2E0822F7880DC6646729145D48 /* IQUIView+Hierarchy.swift */, + 3BD15F5586A3312B66B8589C67AC1D08 /* IQUIView+IQKeyboardToolbar.swift */, + 6FDF66C7D3E2F5CC2B751067F94B129E /* IQUIViewController+Additions.swift */, + 80B6F98182269F0625676712154E2950 /* Resources */, + CED4E64019BD6538903DAC33C2CE590D /* Support Files */, + ); + path = IQKeyboardManagerSwift; + sourceTree = ""; + }; + F9D206BABE81E6BF0B9B23880B238CC7 /* iOS */ = { + isa = PBXGroup; + children = ( + 840FA0B75AF62912A30DDC66B647ED98 /* CoreGraphics.framework */, + 79CF7D56C5D50C18B2EA0ED106D998C7 /* Foundation.framework */, + A42DBD2F42D55606EEBA514009498B87 /* QuartzCore.framework */, + 04D60AC13D33197690A05C641925DDDA /* UIKit.framework */, + ); + name = iOS; + sourceTree = ""; + }; + FDE5B111D0EA7E63B2837610B7718584 /* Products */ = { + isa = PBXGroup; + children = ( + A8E950A16D00F649C54FFB30F81D7842 /* IQKeyboardManagerSwift */, + 8B8FAB0D627B17EDE1366984278705D9 /* MBProgressHUD.framework */, + 1286CB6C8D1472DD6F3D2219B38DFF72 /* Pods-SampleApp */, + 1C7814899343A9719B6447A10B0765A8 /* Pods-SampleAppTests */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 592834C6F654EC6711FC39F6D67B256B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + C0BF33AED6CF67DF46035C682136A8B8 /* Pods-SampleApp-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5D82C29ACD851E6EA219B34A73C961F5 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 67E941CADB3CDDEEDF8CE4EE4A4A05BB /* MBProgressHUD.h in Headers */, + 5BAC1EF86D0E57E44E404B2796993561 /* MBProgressHUD-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 85A932520BC40A75F3549F020972CC8B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D4E2EAD773A30B252B6AD6B99A7490F4 /* IQKeyboardManagerSwift-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CD57AEB3211C4FB00B5B8C1D16B75BCC /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + C6C54C35A7F00A082F727BBBBCC1AE22 /* Pods-SampleAppTests-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 7EFCCFB3480AA7EDB90F9DDD3E9E1D93 /* Pods-SampleApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = A85A031FC328A753BBF3EF1C76C923B1 /* Build configuration list for PBXNativeTarget "Pods-SampleApp" */; + buildPhases = ( + 592834C6F654EC6711FC39F6D67B256B /* Headers */, + 7849D5EC03490E54B708DF76E5B504B4 /* Sources */, + 59338DF3172C7314CF8E9B1F6414DFD0 /* Frameworks */, + 365B85521C36E7493CEC91A6ED76B810 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 76EE5CC1CAD99C7A06E9B97B8B49F57E /* PBXTargetDependency */, + 3EFB989B5D810F1B3DCA2393E578668B /* PBXTargetDependency */, + 28B9441536A1FE406DCF3F87109F931F /* PBXTargetDependency */, + ); + name = "Pods-SampleApp"; + productName = Pods_SampleApp; + productReference = 1286CB6C8D1472DD6F3D2219B38DFF72 /* Pods-SampleApp */; + productType = "com.apple.product-type.framework"; + }; + 82B0A41D3031FF27D78E17B0A9A46FB0 /* MBProgressHUD */ = { + isa = PBXNativeTarget; + buildConfigurationList = A7BD2681E97C00DCC2EF91B0EBA76110 /* Build configuration list for PBXNativeTarget "MBProgressHUD" */; + buildPhases = ( + 5D82C29ACD851E6EA219B34A73C961F5 /* Headers */, + 7E957D4020E4C4BC633BF50F7F51E5F6 /* Sources */, + D6DC8F0C2894774845C1DD2E7CA07B0C /* Frameworks */, + C0E0F7D28F4D633128D0F53BEAE34D3D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MBProgressHUD; + productName = MBProgressHUD; + productReference = 8B8FAB0D627B17EDE1366984278705D9 /* MBProgressHUD.framework */; + productType = "com.apple.product-type.framework"; + }; + 96A8DC919B1188F4B4944E916BA36667 /* Pods-SampleAppTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8A94C9272F169AC23DE6C6D95926EE62 /* Build configuration list for PBXNativeTarget "Pods-SampleAppTests" */; + buildPhases = ( + CD57AEB3211C4FB00B5B8C1D16B75BCC /* Headers */, + D8DA5E050E4FFCBE0D1F9AAE39F2E9B8 /* Sources */, + BF2ABAD1E82074A808865AD23AE52E6F /* Frameworks */, + 1EDF5874590593555DFCEB4A93D5D705 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 59E580E0ECA19A27EFB3B8B86E3467F9 /* PBXTargetDependency */, + ); + name = "Pods-SampleAppTests"; + productName = Pods_SampleAppTests; + productReference = 1C7814899343A9719B6447A10B0765A8 /* Pods-SampleAppTests */; + productType = "com.apple.product-type.framework"; + }; + B490E7485944099E16C9CBD79119D1D4 /* IQKeyboardManagerSwift */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6EA57D0428E1F541FC55143B3FEA485B /* Build configuration list for PBXNativeTarget "IQKeyboardManagerSwift" */; + buildPhases = ( + 85A932520BC40A75F3549F020972CC8B /* Headers */, + F15C2AB492606C7255BF91F14E154EC6 /* Sources */, + 65BFC75CE1541E38446FFDA8AFF0DBEC /* Frameworks */, + 7AB4C6E7F42074143BEB486E118CCE8A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = IQKeyboardManagerSwift; + productName = IQKeyboardManagerSwift; + productReference = A8E950A16D00F649C54FFB30F81D7842 /* IQKeyboardManagerSwift */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + BFDFE7DC352907FC980B868725387E98 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1500; + LastUpgradeCheck = 1500; + }; + buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 12.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + Base, + en, + ); + mainGroup = CF1408CF629C7361332E53B88F7BD30C; + productRefGroup = FDE5B111D0EA7E63B2837610B7718584 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + B490E7485944099E16C9CBD79119D1D4 /* IQKeyboardManagerSwift */, + 82B0A41D3031FF27D78E17B0A9A46FB0 /* MBProgressHUD */, + 662261F7D9ECF9ED37726F62D8D69AC4 /* PayFortSDK */, + 7EFCCFB3480AA7EDB90F9DDD3E9E1D93 /* Pods-SampleApp */, + 96A8DC919B1188F4B4944E916BA36667 /* Pods-SampleAppTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1EDF5874590593555DFCEB4A93D5D705 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 365B85521C36E7493CEC91A6ED76B810 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7AB4C6E7F42074143BEB486E118CCE8A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A50A72FCD270217D99ECA1D2700CFAD4 /* PrivacyInfo.xcprivacy in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C0E0F7D28F4D633128D0F53BEAE34D3D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + A6D33E6929B694CB81D0D996B1FB2EC2 /* [CP] Copy XCFrameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks-input-files.xcfilelist", + ); + name = "[CP] Copy XCFrameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 7849D5EC03490E54B708DF76E5B504B4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F30DB14958FB08C46E4DFDDD0856634B /* Pods-SampleApp-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7E957D4020E4C4BC633BF50F7F51E5F6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0097064E7F7D3F413161738CC5C25EEC /* MBProgressHUD.m in Sources */, + 58C91B4AB36E6B16421106CA634C58EF /* MBProgressHUD-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D8DA5E050E4FFCBE0D1F9AAE39F2E9B8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BAE34A926788C6052F2041FB5FA9AFB /* Pods-SampleAppTests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F15C2AB492606C7255BF91F14E154EC6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + B0CB5FB63262E1A67317045B8960F363 /* IQBarButtonItem.swift in Sources */, + A8DD3F39B4D1F0C7B11866484A03336E /* IQInvocation.swift in Sources */, + 16E5F9C7FE2C499D21F3E7AF1FFC2FA7 /* IQKeyboardManager.swift in Sources */, + 1B4B180E84924CF99663817A2AFFAA92 /* IQKeyboardManager+Debug.swift in Sources */, + 6735E4B11C64D20B4E05A92811F5A721 /* IQKeyboardManager+Internal.swift in Sources */, + 9C292E2C761CB97ACD00F95FA4D60E85 /* IQKeyboardManager+OrientationNotification.swift in Sources */, + 7E59ABF8A1AC8F61FEFB9B8C72EFB9E5 /* IQKeyboardManager+Position.swift in Sources */, + BDAD667B60A9D9981738646851C825A0 /* IQKeyboardManager+Toolbar.swift in Sources */, + 9C2584A9CCF8CA6C9DF2AD79DB831E70 /* IQKeyboardManager+UIKeyboardNotification.swift in Sources */, + 9E4E278A3C1543798E1912699886023E /* IQKeyboardManager+UITextFieldViewNotification.swift in Sources */, + 41A536E6CE1C85116A756B710B2C660B /* IQKeyboardManagerConstants.swift in Sources */, + ECAA15FA3C4560E3287F2226EC8C1ECF /* IQKeyboardManagerConstantsInternal.swift in Sources */, + 930B495B7A3197730A016E2339A4CBA7 /* IQKeyboardManagerSwift-dummy.m in Sources */, + 506C1EE2968687F178BB2DFA34D185CE /* IQKeyboardReturnKeyHandler.swift in Sources */, + AB651DB3A97A623234B6544AD030406A /* IQNSArray+Sort.swift in Sources */, + F47587932A67D8E3820DAFD9A0E1995E /* IQPlaceholderable.swift in Sources */, + 07F83DE63FB5CC8015F48F7B9B800B6F /* IQPreviousNextView.swift in Sources */, + D0DF994786BCEC54939BC8216B42FBC4 /* IQTextView.swift in Sources */, + 373502D50A1B2266D86409E19EC46DDB /* IQTitleBarButtonItem.swift in Sources */, + 07FD274BC01F578C7B37989F79350C1E /* IQToolbar.swift in Sources */, + AAC2529A1B4F4832A052B348C5093018 /* IQUIScrollView+Additions.swift in Sources */, + BE60EC19FCBB8F301081E9C31BB85F3E /* IQUITextFieldView+Additions.swift in Sources */, + 5E8E9469BF126E918EADF79EC4BB5CA2 /* IQUIView+Hierarchy.swift in Sources */, + 19C5CA44D4D4D5B711D33A73525D453F /* IQUIView+IQKeyboardToolbar.swift in Sources */, + B46A36CA19ED6C09341D8E4031F66D5C /* IQUIViewController+Additions.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 28B9441536A1FE406DCF3F87109F931F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PayFortSDK; + target = 662261F7D9ECF9ED37726F62D8D69AC4 /* PayFortSDK */; + targetProxy = 83EE6A9FF089FEE2CF517B72F3400B76 /* PBXContainerItemProxy */; + }; + 3EFB989B5D810F1B3DCA2393E578668B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = MBProgressHUD; + target = 82B0A41D3031FF27D78E17B0A9A46FB0 /* MBProgressHUD */; + targetProxy = 1F38A1035ED58E10C702E249B8543C5D /* PBXContainerItemProxy */; + }; + 59E580E0ECA19A27EFB3B8B86E3467F9 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Pods-SampleApp"; + target = 7EFCCFB3480AA7EDB90F9DDD3E9E1D93 /* Pods-SampleApp */; + targetProxy = 9CA4F29C6244BF0522CE9F488829889C /* PBXContainerItemProxy */; + }; + 76EE5CC1CAD99C7A06E9B97B8B49F57E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = IQKeyboardManagerSwift; + target = B490E7485944099E16C9CBD79119D1D4 /* IQKeyboardManagerSwift */; + targetProxy = 46E140B292283F5A8600F5CEBA9CBB11 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 203E8789CE98C5AC6EECB4C10D42B368 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8DDE14519D9745CD24B9983940DE33D5 /* PayFortSDK.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CLANG_ENABLE_OBJC_WEAK = NO; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 231528393B7084E13F97FF9EF804A1C0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + 353D2EB3545D27343B51B709D9C0420B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Release; + }; + 460E78CC92819FA9FEF341A74534A64E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AA8638FDA3F666FA56BA58C711318626 /* Pods-SampleAppTests.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*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.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; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 542790200443CD2366501B457E9C6D70 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3B4A4A68D4EF19CBE3F65987E27F642E /* Pods-SampleApp.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*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-SampleApp/Pods-SampleApp-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-SampleApp/Pods-SampleApp.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; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + A6260E74821A6D83D56C6FD7B057B34D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E8672BE1AB69EC66A4471A3BE0C4203A /* 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 = 11.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; + }; + C3C37B487645A54D043C2C18BF002F24 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BE0F495F7367B2C62B588DE27ECDAF69 /* MBProgressHUD.release.xcconfig */; + buildSettings = { + "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/MBProgressHUD/MBProgressHUD-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/MBProgressHUD/MBProgressHUD-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/MBProgressHUD/MBProgressHUD.modulemap"; + PRODUCT_MODULE_NAME = MBProgressHUD; + PRODUCT_NAME = MBProgressHUD; + 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 = Release; + }; + C72492883174EE663C437FC20F83A4ED /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4D7487AE33B3E897F698D0A42D8C49EF /* Pods-SampleAppTests.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*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.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; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + C8BC900571113E9009881881989A92CE /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 704A4676BE7F1DC06260B65425456491 /* Pods-SampleApp.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*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-SampleApp/Pods-SampleApp-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-SampleApp/Pods-SampleApp.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; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + DE569755C8FE69395D8E6C347DC7A5F8 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 1D8B028A6F0097967C37DD5FDF6328C4 /* MBProgressHUD.debug.xcconfig */; + buildSettings = { + "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/MBProgressHUD/MBProgressHUD-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/MBProgressHUD/MBProgressHUD-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/MBProgressHUD/MBProgressHUD.modulemap"; + PRODUCT_MODULE_NAME = MBProgressHUD; + PRODUCT_NAME = MBProgressHUD; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + F2F06A1D1C8E097E44080D4D47A4B9A0 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 5502D88D920F1D31DFB72943FEEA0E99 /* PayFortSDK.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CLANG_ENABLE_OBJC_WEAK = NO; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + FB818BDDADBD0A197A07D52CF5BB68F5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8084217B599733E5018E7898D5A9624A /* 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 = 11.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 */ + 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 231528393B7084E13F97FF9EF804A1C0 /* Debug */, + 353D2EB3545D27343B51B709D9C0420B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6EA57D0428E1F541FC55143B3FEA485B /* Build configuration list for PBXNativeTarget "IQKeyboardManagerSwift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A6260E74821A6D83D56C6FD7B057B34D /* Debug */, + FB818BDDADBD0A197A07D52CF5BB68F5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8A94C9272F169AC23DE6C6D95926EE62 /* Build configuration list for PBXNativeTarget "Pods-SampleAppTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 460E78CC92819FA9FEF341A74534A64E /* Debug */, + C72492883174EE663C437FC20F83A4ED /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A7BD2681E97C00DCC2EF91B0EBA76110 /* Build configuration list for PBXNativeTarget "MBProgressHUD" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DE569755C8FE69395D8E6C347DC7A5F8 /* Debug */, + C3C37B487645A54D043C2C18BF002F24 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A85A031FC328A753BBF3EF1C76C923B1 /* Build configuration list for PBXNativeTarget "Pods-SampleApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C8BC900571113E9009881881989A92CE /* Debug */, + 542790200443CD2366501B457E9C6D70 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E2603FA0411795062C7DD4C333C7B8D6 /* Build configuration list for PBXAggregateTarget "PayFortSDK" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 203E8789CE98C5AC6EECB4C10D42B368 /* Debug */, + F2F06A1D1C8E097E44080D4D47A4B9A0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; +} diff --git a/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/IQKeyboardManagerSwift.xcscheme b/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/IQKeyboardManagerSwift.xcscheme new file mode 100644 index 0000000..78a923d --- /dev/null +++ b/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/IQKeyboardManagerSwift.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/MBProgressHUD.xcscheme b/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/MBProgressHUD.xcscheme new file mode 100644 index 0000000..d566028 --- /dev/null +++ b/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/MBProgressHUD.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/PayFortSDK.xcscheme b/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/PayFortSDK.xcscheme new file mode 100644 index 0000000..edfe0a5 --- /dev/null +++ b/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/PayFortSDK.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/Pods-SampleApp.xcscheme b/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/Pods-SampleApp.xcscheme new file mode 100644 index 0000000..221f6e7 --- /dev/null +++ b/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/Pods-SampleApp.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/Pods-SampleAppTests.xcscheme b/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/Pods-SampleAppTests.xcscheme new file mode 100644 index 0000000..7027f94 --- /dev/null +++ b/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/Pods-SampleAppTests.xcscheme @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/xcschememanagement.plist b/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..8fc5185 --- /dev/null +++ b/SampleApp/Pods/Pods.xcodeproj/xcuserdata/cetozgen.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,36 @@ + + + + + SchemeUserState + + IQKeyboardManagerSwift.xcscheme + + isShown + + + MBProgressHUD.xcscheme + + isShown + + + PayFortSDK.xcscheme + + isShown + + + Pods-SampleApp.xcscheme + + isShown + + + Pods-SampleAppTests.xcscheme + + isShown + + + + SuppressBuildableAutocreation + + + diff --git a/SampleApp/Pods/Target Support Files/.DS_Store b/SampleApp/Pods/Target Support Files/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5a93a98991da8b2892f4aeb18741d5f08626ee72 GIT binary patch literal 6148 zcmeHK!Ab)$5S_HuZYfF+3OxqAR%}JA;$^M%F0SZ7rS7st7q^?zZSA2H_N+hTm-s!- zB&k@cUIdXc1CuwI%p~Mx$!q{Xv_@eApaK96Dq*gK%@;!BqzjU>9zvn#*ai=L=s_Ri zg=lvCM+WHZ*5M2kgpk7L^XtMfo?|~4r~M#S0mi)s{Wwa8_4=F0_`@v<@9d{}lCn_2GQPLgggedG{$jw!hglgPUqa;jqu4e|E zl2htbs*}m?VY6A2jrz1ECkKs#n%v*3Pp2hkb8F}5yz?0M67_6|75EKmS+h8U7c_p{ z + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 6.5.16 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-dummy.m b/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-dummy.m new file mode 100644 index 0000000..7937f27 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_IQKeyboardManagerSwift : NSObject +@end +@implementation PodsDummy_IQKeyboardManagerSwift +@end diff --git a/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch b/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-umbrella.h b/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-umbrella.h new file mode 100644 index 0000000..e95b398 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#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/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.debug.xcconfig b/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.debug.xcconfig new file mode 100644 index 0000000..1472651 --- /dev/null +++ b/SampleApp/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/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.modulemap b/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.modulemap new file mode 100644 index 0000000..6d9b343 --- /dev/null +++ b/SampleApp/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/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.release.xcconfig b/SampleApp/Pods/Target Support Files/IQKeyboardManagerSwift/IQKeyboardManagerSwift.release.xcconfig new file mode 100644 index 0000000..1472651 --- /dev/null +++ b/SampleApp/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/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-Info.plist b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-Info.plist new file mode 100644 index 0000000..c2e6784 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.2.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-dummy.m b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-dummy.m new file mode 100644 index 0000000..67a74df --- /dev/null +++ b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_MBProgressHUD : NSObject +@end +@implementation PodsDummy_MBProgressHUD +@end diff --git a/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-prefix.pch b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-umbrella.h b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-umbrella.h new file mode 100644 index 0000000..8522a01 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD-umbrella.h @@ -0,0 +1,17 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "MBProgressHUD.h" + +FOUNDATION_EXPORT double MBProgressHUDVersionNumber; +FOUNDATION_EXPORT const unsigned char MBProgressHUDVersionString[]; + diff --git a/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.debug.xcconfig b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.debug.xcconfig new file mode 100644 index 0000000..39dd1b9 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "QuartzCore" +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}/MBProgressHUD +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/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.modulemap b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.modulemap new file mode 100644 index 0000000..dbb3f94 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.modulemap @@ -0,0 +1,6 @@ +framework module MBProgressHUD { + umbrella header "MBProgressHUD-umbrella.h" + + export * + module * { export * } +} diff --git a/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.release.xcconfig b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.release.xcconfig new file mode 100644 index 0000000..39dd1b9 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/MBProgressHUD/MBProgressHUD.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "CoreGraphics" -framework "QuartzCore" +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}/MBProgressHUD +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/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks-input-files.xcfilelist b/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks-input-files.xcfilelist new file mode 100644 index 0000000..42989bc --- /dev/null +++ b/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks-input-files.xcfilelist @@ -0,0 +1,2 @@ +${PODS_ROOT}/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks.sh +${PODS_ROOT}/../../PayFortSDK.xcframework \ No newline at end of file diff --git a/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks-output-files.xcfilelist b/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks-output-files.xcfilelist new file mode 100644 index 0000000..61dbcbc --- /dev/null +++ b/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks-output-files.xcfilelist @@ -0,0 +1 @@ +${PODS_XCFRAMEWORKS_BUILD_DIR}/PayFortSDK/PayFortSDK.framework \ No newline at end of file diff --git a/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks.sh b/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks.sh new file mode 100755 index 0000000..e6dd380 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK-xcframeworks.sh @@ -0,0 +1,121 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + + +variant_for_slice() +{ + case "$1" in + "PayFortSDK.xcframework/ios-arm64") + echo "" + ;; + "PayFortSDK.xcframework/ios-arm64_x86_64-simulator") + echo "simulator" + ;; + esac +} + +archs_for_slice() +{ + case "$1" in + "PayFortSDK.xcframework/ios-arm64") + echo "arm64" + ;; + "PayFortSDK.xcframework/ios-arm64_x86_64-simulator") + echo "arm64 x86_64" + ;; + esac +} + +copy_dir() +{ + local source="$1" + local destination="$2" + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" \"${source}*\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" "${source}"/* "${destination}" +} + +SELECT_SLICE_RETVAL="" + +select_slice() { + local xcframework_name="$1" + xcframework_name="${xcframework_name##*/}" + local paths=("${@:2}") + # Locate the correct slice of the .xcframework for the current architectures + local target_path="" + + # Split archs on space so we can find a slice that has all the needed archs + local target_archs=$(echo $ARCHS | tr " " "\n") + + local target_variant="" + if [[ "$PLATFORM_NAME" == *"simulator" ]]; then + target_variant="simulator" + fi + if [[ ! -z ${EFFECTIVE_PLATFORM_NAME+x} && "$EFFECTIVE_PLATFORM_NAME" == *"maccatalyst" ]]; then + target_variant="maccatalyst" + fi + for i in ${!paths[@]}; do + local matched_all_archs="1" + local slice_archs="$(archs_for_slice "${xcframework_name}/${paths[$i]}")" + local slice_variant="$(variant_for_slice "${xcframework_name}/${paths[$i]}")" + for target_arch in $target_archs; do + if ! [[ "${slice_variant}" == "$target_variant" ]]; then + matched_all_archs="0" + break + fi + + if ! echo "${slice_archs}" | tr " " "\n" | grep -F -q -x "$target_arch"; then + matched_all_archs="0" + break + fi + done + + if [[ "$matched_all_archs" == "1" ]]; then + # Found a matching slice + echo "Selected xcframework slice ${paths[$i]}" + SELECT_SLICE_RETVAL=${paths[$i]} + break + fi + done +} + +install_xcframework() { + local basepath="$1" + local name="$2" + local package_type="$3" + local paths=("${@:4}") + + # Locate the correct slice of the .xcframework for the current architectures + select_slice "${basepath}" "${paths[@]}" + local target_path="$SELECT_SLICE_RETVAL" + if [[ -z "$target_path" ]]; then + echo "warning: [CP] $(basename ${basepath}): Unable to find matching slice in '${paths[@]}' for the current build architectures ($ARCHS) and platform (${EFFECTIVE_PLATFORM_NAME-${PLATFORM_NAME}})." + return + fi + local source="$basepath/$target_path" + + local destination="${PODS_XCFRAMEWORKS_BUILD_DIR}/${name}" + + if [ ! -d "$destination" ]; then + mkdir -p "$destination" + fi + + copy_dir "$source/" "$destination" + echo "Copied $source to $destination" +} + +install_xcframework "${PODS_ROOT}/../../PayFortSDK.xcframework" "PayFortSDK" "framework" "ios-arm64" "ios-arm64_x86_64-simulator" + diff --git a/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK.debug.xcconfig b/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK.debug.xcconfig new file mode 100644 index 0000000..ad01c90 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK.debug.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PayFortSDK +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../.." "${PODS_XCFRAMEWORKS_BUILD_DIR}/PayFortSDK" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +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}/../.. +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/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK.release.xcconfig b/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK.release.xcconfig new file mode 100644 index 0000000..ad01c90 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/PayFortSDK/PayFortSDK.release.xcconfig @@ -0,0 +1,15 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PayFortSDK +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../.." "${PODS_XCFRAMEWORKS_BUILD_DIR}/PayFortSDK" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +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}/../.. +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/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-Info.plist b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-Info.plist new file mode 100644 index 0000000..19cf209 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-acknowledgements.markdown b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-acknowledgements.markdown new file mode 100644 index 0000000..829320e --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-acknowledgements.markdown @@ -0,0 +1,75 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## IQKeyboardManagerSwift + +MIT License + +Copyright (c) 2013-2017 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. + + +## MBProgressHUD + +Copyright © 2009-2020 Matej Bukovinski + +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. + +## PayFortSDK + +The MIT License (MIT) + +Copyright (c) 2021 Amazon Payment Services + +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. + +Generated by CocoaPods - https://cocoapods.org diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-acknowledgements.plist b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-acknowledgements.plist new file mode 100644 index 0000000..34d39c0 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-acknowledgements.plist @@ -0,0 +1,119 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2013-2017 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. + + License + MIT + Title + IQKeyboardManagerSwift + Type + PSGroupSpecifier + + + FooterText + Copyright © 2009-2020 Matej Bukovinski + +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. + License + MIT + Title + MBProgressHUD + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) + +Copyright (c) 2021 Amazon Payment Services + +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. + + License + MIT + Title + PayFortSDK + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-dummy.m b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-dummy.m new file mode 100644 index 0000000..ad113e0 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_SampleApp : NSObject +@end +@implementation PodsDummy_Pods_SampleApp +@end diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Debug-input-files.xcfilelist b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Debug-input-files.xcfilelist new file mode 100644 index 0000000..5b45aaa --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Debug-input-files.xcfilelist @@ -0,0 +1,4 @@ +${PODS_ROOT}/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks.sh +${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework +${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework +${PODS_XCFRAMEWORKS_BUILD_DIR}/PayFortSDK/PayFortSDK.framework/PayFortSDK \ No newline at end of file diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Debug-output-files.xcfilelist b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Debug-output-files.xcfilelist new file mode 100644 index 0000000..eb2dc5d --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Debug-output-files.xcfilelist @@ -0,0 +1,3 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MBProgressHUD.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PayFortSDK.framework \ No newline at end of file diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Release-input-files.xcfilelist b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Release-input-files.xcfilelist new file mode 100644 index 0000000..5b45aaa --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Release-input-files.xcfilelist @@ -0,0 +1,4 @@ +${PODS_ROOT}/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks.sh +${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework +${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework +${PODS_XCFRAMEWORKS_BUILD_DIR}/PayFortSDK/PayFortSDK.framework/PayFortSDK \ No newline at end of file diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Release-output-files.xcfilelist b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Release-output-files.xcfilelist new file mode 100644 index 0000000..eb2dc5d --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-Release-output-files.xcfilelist @@ -0,0 +1,3 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MBProgressHUD.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PayFortSDK.framework \ No newline at end of file diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks.sh b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks.sh new file mode 100755 index 0000000..54a5d7c --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks.sh @@ -0,0 +1,190 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +BCSYMBOLMAP_DIR="BCSymbolMaps" + + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink -f "${source}")" + fi + + if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then + # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied + find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do + echo "Installing $f" + install_bcsymbolmap "$f" "$destination" + rm "$f" + done + rmdir "${source}/${BCSYMBOLMAP_DIR}" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + elif [ -L "${binary}" ]; then + echo "Destination binary is symlinked..." + dirname="$(dirname "${binary}")" + binary="${dirname}/$(readlink "${binary}")" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + warn_missing_arch=${2:-true} + if [ -r "$source" ]; then + # Copy the dSYM into the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .dSYM "$source")" + binary_name="$(ls "$source/Contents/Resources/DWARF")" + binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" + + # Strip invalid architectures from the dSYM. + if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then + strip_invalid_archs "$binary" "$warn_missing_arch" + fi + if [[ $STRIP_BINARY_RETVAL == 0 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + mkdir -p "${DWARF_DSYM_FOLDER_PATH}" + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" + fi + fi +} + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + warn_missing_arch=${2:-true} + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + if [[ "$warn_missing_arch" == "true" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + fi + STRIP_BINARY_RETVAL=1 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=0 +} + +# Copies the bcsymbolmap files of a vendored framework +install_bcsymbolmap() { + local bcsymbolmap_path="$1" + local destination="${BUILT_PRODUCTS_DIR}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identity + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework" + install_framework "${PODS_XCFRAMEWORKS_BUILD_DIR}/PayFortSDK/PayFortSDK.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework" + install_framework "${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework" + install_framework "${PODS_XCFRAMEWORKS_BUILD_DIR}/PayFortSDK/PayFortSDK.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-umbrella.h b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-umbrella.h new file mode 100644 index 0000000..9436e1c --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_SampleAppVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_SampleAppVersionString[]; + diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.debug.xcconfig b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.debug.xcconfig new file mode 100644 index 0000000..873dd8f --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.debug.xcconfig @@ -0,0 +1,15 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_ROOT}/../.." "${PODS_XCFRAMEWORKS_BUILD_DIR}/PayFortSDK" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.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 $(SDKROOT)/usr/lib/swift +OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "MBProgressHUD" -framework "PayFortSDK" -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_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.modulemap b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.modulemap new file mode 100644 index 0000000..25c8475 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.modulemap @@ -0,0 +1,6 @@ +framework module Pods_SampleApp { + umbrella header "Pods-SampleApp-umbrella.h" + + export * + module * { export * } +} diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.release.xcconfig b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.release.xcconfig new file mode 100644 index 0000000..873dd8f --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleApp/Pods-SampleApp.release.xcconfig @@ -0,0 +1,15 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_ROOT}/../.." "${PODS_XCFRAMEWORKS_BUILD_DIR}/PayFortSDK" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.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 $(SDKROOT)/usr/lib/swift +OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "MBProgressHUD" -framework "PayFortSDK" -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_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-Info.plist b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-Info.plist new file mode 100644 index 0000000..19cf209 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-acknowledgements.markdown b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-acknowledgements.markdown new file mode 100644 index 0000000..102af75 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-acknowledgements.markdown @@ -0,0 +1,3 @@ +# Acknowledgements +This application makes use of the following third party libraries: +Generated by CocoaPods - https://cocoapods.org diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-acknowledgements.plist b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-acknowledgements.plist new file mode 100644 index 0000000..7acbad1 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-acknowledgements.plist @@ -0,0 +1,29 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-dummy.m b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-dummy.m new file mode 100644 index 0000000..c65883c --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_SampleAppTests : NSObject +@end +@implementation PodsDummy_Pods_SampleAppTests +@end diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-umbrella.h b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-umbrella.h new file mode 100644 index 0000000..6704ada --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_SampleAppTestsVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_SampleAppTestsVersionString[]; + diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.debug.xcconfig b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.debug.xcconfig new file mode 100644 index 0000000..8db0e9d --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.debug.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_ROOT}/../.." "${PODS_XCFRAMEWORKS_BUILD_DIR}/PayFortSDK" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" +LIBRARY_SEARCH_PATHS = $(inherited) $(SDKROOT)/usr/lib/swift +OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "MBProgressHUD" -framework "PayFortSDK" -framework "QuartzCore" -framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.modulemap b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.modulemap new file mode 100644 index 0000000..d3ccd05 --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.modulemap @@ -0,0 +1,6 @@ +framework module Pods_SampleAppTests { + umbrella header "Pods-SampleAppTests-umbrella.h" + + export * + module * { export * } +} diff --git a/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.release.xcconfig b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.release.xcconfig new file mode 100644 index 0000000..8db0e9d --- /dev/null +++ b/SampleApp/Pods/Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.release.xcconfig @@ -0,0 +1,12 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_ROOT}/../.." "${PODS_XCFRAMEWORKS_BUILD_DIR}/PayFortSDK" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" +LIBRARY_SEARCH_PATHS = $(inherited) $(SDKROOT)/usr/lib/swift +OTHER_LDFLAGS = $(inherited) -l"swiftCoreGraphics" -framework "CoreGraphics" -framework "Foundation" -framework "IQKeyboardManagerSwift" -framework "MBProgressHUD" -framework "PayFortSDK" -framework "QuartzCore" -framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/SampleApp/SampleApp.xcodeproj/project.pbxproj b/SampleApp/SampleApp.xcodeproj/project.pbxproj index d2eec0b..09c63a0 100644 --- a/SampleApp/SampleApp.xcodeproj/project.pbxproj +++ b/SampleApp/SampleApp.xcodeproj/project.pbxproj @@ -3,13 +3,14 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ 003FA85F25B39597005DC6B2 /* ResponsePageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 003FA85E25B39597005DC6B2 /* ResponsePageViewController.swift */; }; 003FA8C325B4C8C9005DC6B2 /* DirectPayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 003FA8C225B4C8C9005DC6B2 /* DirectPayViewController.swift */; }; 0045A44325AD0A9F00349167 /* CustomPayFortView-ar.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0045A44225AD0A9F00349167 /* CustomPayFortView-ar.xib */; }; + 0057922F27303F460002F87B /* PayFortSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0057922E27303F460002F87B /* PayFortSDK.framework */; }; 005F86FD259D236700AA4BA6 /* MainObjectiveCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 005F86FC259D236700AA4BA6 /* MainObjectiveCViewController.m */; }; 009DAC8825817398008DDB56 /* SdkTokenSettingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009DAC8725817398008DDB56 /* SdkTokenSettingViewController.swift */; }; 009DAC8B258173B8008DDB56 /* ApplePaySettingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009DAC8A258173B8008DDB56 /* ApplePaySettingViewController.swift */; }; @@ -17,12 +18,15 @@ 009DAC9C25817660008DDB56 /* GlobalClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 009DAC9B25817660008DDB56 /* GlobalClass.swift */; }; 00C6F7972582E85700F5A837 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C6F7962582E85700F5A837 /* MainViewController.swift */; }; 00C6F7A425839D1200F5A837 /* ExtraParam.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C6F7A325839D1200F5A837 /* ExtraParam.swift */; }; + 00D26A4B2583AC9C00FD0E97 /* Token.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00D26A4A2583AC9C00FD0E97 /* Token.swift */; }; 00D26A502583B09A00FD0E97 /* ExtraParamCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00D26A4E2583B09A00FD0E97 /* ExtraParamCell.swift */; }; 00D26A512583B09A00FD0E97 /* ExtraParamCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 00D26A4F2583B09A00FD0E97 /* ExtraParamCell.xib */; }; 00D26A542583B6AF00FD0E97 /* TableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00D26A532583B6AF00FD0E97 /* TableViewDataSource.swift */; }; 00D26AA425855B0E00FD0E97 /* ApplePay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00D26AA325855B0E00FD0E97 /* ApplePay.swift */; }; 00D4AFE225BF76B000AF24A2 /* SelectCustomPaymentTypeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00D4AFE125BF76B000AF24A2 /* SelectCustomPaymentTypeVC.swift */; }; 00D4AFE525BF7F4400AF24A2 /* HalfCardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00D4AFE425BF7F4400AF24A2 /* HalfCardViewController.swift */; }; + 00F190172594157A0011E124 /* NetworkLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00F190162594157A0011E124 /* NetworkLogger.swift */; }; + 21FB474D7BB3B429246C85A7 /* Pods_SampleApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 68D050B8F5988CD917DA81FC /* Pods_SampleApp.framework */; }; 22604575250B9C3B007191B2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22604574250B9C3B007191B2 /* AppDelegate.swift */; }; 22604577250B9C3B007191B2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22604576250B9C3B007191B2 /* SceneDelegate.swift */; }; 22604579250B9C3B007191B2 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22604578250B9C3B007191B2 /* ViewController.swift */; }; @@ -32,8 +36,8 @@ 2260458C250B9C3E007191B2 /* SampleAppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2260458B250B9C3E007191B2 /* SampleAppTests.swift */; }; 229C092F259003C200AD4D6C /* CustomCardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 229C092E259003C200AD4D6C /* CustomCardViewController.swift */; }; 22B65C15259E5B1E00CB9461 /* CustomPayFortView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 22B65C14259E5B1E00CB9461 /* CustomPayFortView.xib */; }; - E5659044CAF8CCDACF785F9E /* Pods_SampleApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D95E90D6781C93B8CE28AB2 /* Pods_SampleApp.framework */; }; - F1EA387BDEDF12FBD15EB06F /* Pods_SampleAppTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 41169C7757B46E41E7FC18D0 /* Pods_SampleAppTests.framework */; }; + 3D5DB79E29C078C800A37AF4 /* STCPay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D5DB79D29C078C800A37AF4 /* STCPay.swift */; }; + E9EA08336BFB26AFD4DA5F3D /* Pods_SampleAppTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BA304BC230189E8B98A3BD50 /* Pods_SampleAppTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -50,10 +54,10 @@ 003FA85E25B39597005DC6B2 /* ResponsePageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResponsePageViewController.swift; sourceTree = ""; }; 003FA8C225B4C8C9005DC6B2 /* DirectPayViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectPayViewController.swift; sourceTree = ""; }; 0045A44225AD0A9F00349167 /* CustomPayFortView-ar.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = "CustomPayFortView-ar.xib"; sourceTree = ""; }; + 0057922E27303F460002F87B /* PayFortSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PayFortSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 005F86FA259D236600AA4BA6 /* SampleApp-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SampleApp-Bridging-Header.h"; sourceTree = ""; }; 005F86FB259D236700AA4BA6 /* MainObjectiveCViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MainObjectiveCViewController.h; sourceTree = ""; }; 005F86FC259D236700AA4BA6 /* MainObjectiveCViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MainObjectiveCViewController.m; sourceTree = ""; }; - 009515B7823CB5E74B8630A4 /* Pods-SampleAppTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SampleAppTests.release.xcconfig"; path = "Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.release.xcconfig"; sourceTree = ""; }; 009DAC8725817398008DDB56 /* SdkTokenSettingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SdkTokenSettingViewController.swift; sourceTree = ""; }; 009DAC8A258173B8008DDB56 /* ApplePaySettingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplePaySettingViewController.swift; sourceTree = ""; }; 009DAC8D2581744F008DDB56 /* PaymentSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentSettingsViewController.swift; sourceTree = ""; }; @@ -61,13 +65,16 @@ 00A8D6E72588014D005D32E2 /* SampleApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SampleApp.entitlements; sourceTree = ""; }; 00C6F7962582E85700F5A837 /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; 00C6F7A325839D1200F5A837 /* ExtraParam.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtraParam.swift; sourceTree = ""; }; + 00D26A4A2583AC9C00FD0E97 /* Token.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Token.swift; sourceTree = ""; }; 00D26A4E2583B09A00FD0E97 /* ExtraParamCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtraParamCell.swift; sourceTree = ""; }; 00D26A4F2583B09A00FD0E97 /* ExtraParamCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExtraParamCell.xib; sourceTree = ""; }; 00D26A532583B6AF00FD0E97 /* TableViewDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewDataSource.swift; sourceTree = ""; }; 00D26AA325855B0E00FD0E97 /* ApplePay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplePay.swift; sourceTree = ""; }; 00D4AFE125BF76B000AF24A2 /* SelectCustomPaymentTypeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectCustomPaymentTypeVC.swift; sourceTree = ""; }; 00D4AFE425BF7F4400AF24A2 /* HalfCardViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HalfCardViewController.swift; sourceTree = ""; }; + 00F190162594157A0011E124 /* NetworkLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkLogger.swift; sourceTree = ""; }; 00F5AFAE25EED6C50052F5E1 /* PayFortSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PayFortSDK.framework; path = "../../../../../Library/Developer/Xcode/DerivedData/PayFort-fkplevgculoyxzabulwxjyovvtav/Build/Products/Debug-iphoneos/PayFortSDK.framework"; sourceTree = ""; }; + 04A78A655D8CAC3B2296468A /* Pods-SampleAppTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SampleAppTests.debug.xcconfig"; path = "Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.debug.xcconfig"; sourceTree = ""; }; 22604571250B9C3B007191B2 /* SampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 22604574250B9C3B007191B2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 22604576250B9C3B007191B2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -81,11 +88,13 @@ 2260458D250B9C3E007191B2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 229C092E259003C200AD4D6C /* CustomCardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomCardViewController.swift; sourceTree = ""; }; 22B65C14259E5B1E00CB9461 /* CustomPayFortView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CustomPayFortView.xib; sourceTree = ""; }; - 41169C7757B46E41E7FC18D0 /* Pods_SampleAppTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SampleAppTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5D95E90D6781C93B8CE28AB2 /* Pods_SampleApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SampleApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - CFC44BFD57D28CBC2F085C47 /* Pods-SampleAppTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SampleAppTests.debug.xcconfig"; path = "Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.debug.xcconfig"; sourceTree = ""; }; - D8144A67B1D6BBB1B788C210 /* Pods-SampleApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SampleApp.release.xcconfig"; path = "Target Support Files/Pods-SampleApp/Pods-SampleApp.release.xcconfig"; sourceTree = ""; }; - F045F1B4C677A3DB7B2AC9A8 /* Pods-SampleApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SampleApp.debug.xcconfig"; path = "Target Support Files/Pods-SampleApp/Pods-SampleApp.debug.xcconfig"; sourceTree = ""; }; + 3D4AD49D2B4EBF3100BD434C /* PayFortSDK.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PayFortSDK.xcframework; path = ../PayFortSDK.xcframework; sourceTree = ""; }; + 3D5DB79D29C078C800A37AF4 /* STCPay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = STCPay.swift; sourceTree = ""; }; + 68D050B8F5988CD917DA81FC /* Pods_SampleApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SampleApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BA304BC230189E8B98A3BD50 /* Pods_SampleAppTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SampleAppTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + CA2462AF21F7FA79C71D72C2 /* Pods-SampleApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SampleApp.release.xcconfig"; path = "Target Support Files/Pods-SampleApp/Pods-SampleApp.release.xcconfig"; sourceTree = ""; }; + E55F1D1E43F306C70129664F /* Pods-SampleAppTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SampleAppTests.release.xcconfig"; path = "Target Support Files/Pods-SampleAppTests/Pods-SampleAppTests.release.xcconfig"; sourceTree = ""; }; + F00718E6A7698358B504E799 /* Pods-SampleApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SampleApp.debug.xcconfig"; path = "Target Support Files/Pods-SampleApp/Pods-SampleApp.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -93,7 +102,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E5659044CAF8CCDACF785F9E /* Pods_SampleApp.framework in Frameworks */, + 0057922F27303F460002F87B /* PayFortSDK.framework in Frameworks */, + 21FB474D7BB3B429246C85A7 /* Pods_SampleApp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -101,7 +111,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F1EA387BDEDF12FBD15EB06F /* Pods_SampleAppTests.framework in Frameworks */, + E9EA08336BFB26AFD4DA5F3D /* Pods_SampleAppTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -141,9 +151,11 @@ 009DAC9A2581761E008DDB56 /* Common */ = { isa = PBXGroup; children = ( + 00F190162594157A0011E124 /* NetworkLogger.swift */, 00D26A532583B6AF00FD0E97 /* TableViewDataSource.swift */, 009DAC9B25817660008DDB56 /* GlobalClass.swift */, 00C6F7A325839D1200F5A837 /* ExtraParam.swift */, + 00D26A4A2583AC9C00FD0E97 /* Token.swift */, ); path = Common; sourceTree = ""; @@ -159,6 +171,7 @@ 003FA85E25B39597005DC6B2 /* ResponsePageViewController.swift */, 003FA8C225B4C8C9005DC6B2 /* DirectPayViewController.swift */, 00D4AFE125BF76B000AF24A2 /* SelectCustomPaymentTypeVC.swift */, + 3D5DB79D29C078C800A37AF4 /* STCPay.swift */, ); path = Main; sourceTree = ""; @@ -187,7 +200,7 @@ 22604572250B9C3B007191B2 /* Products */, 9932490B951DB273F2FDAB2D /* Frameworks */, 00F18FFE2592844F0011E124 /* Recovered References */, - EF217F0A7CF2C3312CAD0230 /* Pods */, + 67E7B1F47160DE42D1488394 /* Pods */, ); sourceTree = ""; }; @@ -228,25 +241,27 @@ path = SampleAppTests; sourceTree = ""; }; - 9932490B951DB273F2FDAB2D /* Frameworks */ = { + 67E7B1F47160DE42D1488394 /* Pods */ = { isa = PBXGroup; children = ( - 00F5AFAE25EED6C50052F5E1 /* PayFortSDK.framework */, - 5D95E90D6781C93B8CE28AB2 /* Pods_SampleApp.framework */, - 41169C7757B46E41E7FC18D0 /* Pods_SampleAppTests.framework */, + F00718E6A7698358B504E799 /* Pods-SampleApp.debug.xcconfig */, + CA2462AF21F7FA79C71D72C2 /* Pods-SampleApp.release.xcconfig */, + 04A78A655D8CAC3B2296468A /* Pods-SampleAppTests.debug.xcconfig */, + E55F1D1E43F306C70129664F /* Pods-SampleAppTests.release.xcconfig */, ); - name = Frameworks; + path = Pods; sourceTree = ""; }; - EF217F0A7CF2C3312CAD0230 /* Pods */ = { + 9932490B951DB273F2FDAB2D /* Frameworks */ = { isa = PBXGroup; children = ( - F045F1B4C677A3DB7B2AC9A8 /* Pods-SampleApp.debug.xcconfig */, - D8144A67B1D6BBB1B788C210 /* Pods-SampleApp.release.xcconfig */, - CFC44BFD57D28CBC2F085C47 /* Pods-SampleAppTests.debug.xcconfig */, - 009515B7823CB5E74B8630A4 /* Pods-SampleAppTests.release.xcconfig */, + 00F5AFAE25EED6C50052F5E1 /* PayFortSDK.framework */, + 3D4AD49D2B4EBF3100BD434C /* PayFortSDK.xcframework */, + 0057922E27303F460002F87B /* PayFortSDK.framework */, + 68D050B8F5988CD917DA81FC /* Pods_SampleApp.framework */, + BA304BC230189E8B98A3BD50 /* Pods_SampleAppTests.framework */, ); - path = Pods; + name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ @@ -256,11 +271,11 @@ isa = PBXNativeTarget; buildConfigurationList = 22604590250B9C3E007191B2 /* Build configuration list for PBXNativeTarget "SampleApp" */; buildPhases = ( - 73D78CBA76A65BD44D469490 /* [CP] Check Pods Manifest.lock */, + EDE268F19F25673CC569279F /* [CP] Check Pods Manifest.lock */, 2260456D250B9C3B007191B2 /* Sources */, 2260456E250B9C3B007191B2 /* Frameworks */, 2260456F250B9C3B007191B2 /* Resources */, - F3F96784708CB0481C658CA1 /* [CP] Embed Pods Frameworks */, + 1423BC9323D235EB992B9E4A /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -275,7 +290,7 @@ isa = PBXNativeTarget; buildConfigurationList = 22604593250B9C3E007191B2 /* Build configuration list for PBXNativeTarget "SampleAppTests" */; buildPhases = ( - 7D7B0AD8E1DA565A108D1174 /* [CP] Check Pods Manifest.lock */, + 982A863D51C797E600EBD757 /* [CP] Check Pods Manifest.lock */, 22604583250B9C3E007191B2 /* Sources */, 22604584250B9C3E007191B2 /* Frameworks */, 22604585250B9C3E007191B2 /* Resources */, @@ -296,8 +311,9 @@ 22604569250B9C3B007191B2 /* Project object */ = { isa = PBXProject; attributes = { + BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1130; - LastUpgradeCheck = 1130; + LastUpgradeCheck = 1520; ORGANIZATIONNAME = PayFort; TargetAttributes = { 22604570250B9C3B007191B2 = { @@ -353,29 +369,24 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 73D78CBA76A65BD44D469490 /* [CP] Check Pods Manifest.lock */ = { + 1423BC9323D235EB992B9E4A /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-SampleApp-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 7D7B0AD8E1DA565A108D1174 /* [CP] Check Pods Manifest.lock */ = { + 982A863D51C797E600EBD757 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -397,21 +408,26 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - F3F96784708CB0481C658CA1 /* [CP] Embed Pods Frameworks */ = { + EDE268F19F25673CC569279F /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-SampleApp-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SampleApp/Pods-SampleApp-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -421,8 +437,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 00F190172594157A0011E124 /* NetworkLogger.swift in Sources */, 009DAC9C25817660008DDB56 /* GlobalClass.swift in Sources */, 00D26A502583B09A00FD0E97 /* ExtraParamCell.swift in Sources */, + 00D26A4B2583AC9C00FD0E97 /* Token.swift in Sources */, 003FA85F25B39597005DC6B2 /* ResponsePageViewController.swift in Sources */, 22604579250B9C3B007191B2 /* ViewController.swift in Sources */, 003FA8C325B4C8C9005DC6B2 /* DirectPayViewController.swift in Sources */, @@ -434,6 +452,7 @@ 009DAC8825817398008DDB56 /* SdkTokenSettingViewController.swift in Sources */, 22604575250B9C3B007191B2 /* AppDelegate.swift in Sources */, 005F86FD259D236700AA4BA6 /* MainObjectiveCViewController.m in Sources */, + 3D5DB79E29C078C800A37AF4 /* STCPay.swift in Sources */, 22604577250B9C3B007191B2 /* SceneDelegate.swift in Sources */, 00C6F7972582E85700F5A837 /* MainViewController.swift in Sources */, 00D4AFE225BF76B000AF24A2 /* SelectCustomPaymentTypeVC.swift in Sources */, @@ -506,6 +525,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -516,6 +536,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -566,6 +587,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -576,6 +598,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -596,7 +619,7 @@ }; 22604591250B9C3E007191B2 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F045F1B4C677A3DB7B2AC9A8 /* Pods-SampleApp.debug.xcconfig */; + baseConfigurationReference = F00718E6A7698358B504E799 /* Pods-SampleApp.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_CODE_COVERAGE = NO; @@ -604,7 +627,7 @@ CODE_SIGN_ENTITLEMENTS = SampleApp/SampleApp.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 7KLC3DMM55; + DEVELOPMENT_TEAM = 2YP9LJHD24; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", @@ -614,7 +637,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.payfort.test.applepay; + PRODUCT_BUNDLE_IDENTIFIER = com.payfort.test.stcpay; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "SampleApp/Controllers/Objective C/SampleApp-Bridging-Header.h"; @@ -626,7 +649,7 @@ }; 22604592250B9C3E007191B2 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D8144A67B1D6BBB1B788C210 /* Pods-SampleApp.release.xcconfig */; + baseConfigurationReference = CA2462AF21F7FA79C71D72C2 /* Pods-SampleApp.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_CODE_COVERAGE = NO; @@ -634,7 +657,7 @@ CODE_SIGN_ENTITLEMENTS = SampleApp/SampleApp.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 7KLC3DMM55; + DEVELOPMENT_TEAM = 2YP9LJHD24; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", @@ -644,7 +667,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.payfort.test.applepay; + PRODUCT_BUNDLE_IDENTIFIER = com.payfort.test.stcpay; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "SampleApp/Controllers/Objective C/SampleApp-Bridging-Header.h"; @@ -655,7 +678,7 @@ }; 22604594250B9C3E007191B2 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CFC44BFD57D28CBC2F085C47 /* Pods-SampleAppTests.debug.xcconfig */; + baseConfigurationReference = 04A78A655D8CAC3B2296468A /* Pods-SampleAppTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -678,7 +701,7 @@ }; 22604595250B9C3E007191B2 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 009515B7823CB5E74B8630A4 /* Pods-SampleAppTests.release.xcconfig */; + baseConfigurationReference = E55F1D1E43F306C70129664F /* Pods-SampleAppTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; diff --git a/SampleApp/SampleApp.xcodeproj/xcshareddata/xcschemes/SampleApp.xcscheme b/SampleApp/SampleApp.xcodeproj/xcshareddata/xcschemes/SampleApp.xcscheme index 387953f..30dc27c 100644 --- a/SampleApp/SampleApp.xcodeproj/xcshareddata/xcschemes/SampleApp.xcscheme +++ b/SampleApp/SampleApp.xcodeproj/xcshareddata/xcschemes/SampleApp.xcscheme @@ -1,6 +1,6 @@ + + + + SchemeUserState + + SampleApp.xcscheme_^#shared#^_ + + orderHint + 3 + + + + diff --git a/SampleApp/SampleApp.xcworkspace/xcuserdata/ahmadalkalouti.xcuserdatad/UserInterfaceState.xcuserstate b/SampleApp/SampleApp.xcworkspace/xcuserdata/ahmadalkalouti.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 877d70e2faa63214de35705f671a1c3f931dca32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 63065 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 c0g4#LB5nX Bool { // Override point for customization after application launch. - IQKeyboardManager.shared.enable = true GlobalClass.setDefualtValueToUserDefaults() + IQKeyboardManager.shared.enable = true return true } diff --git a/SampleApp/SampleApp/Assets.xcassets/.DS_Store b/SampleApp/SampleApp/Assets.xcassets/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6a8ebe04c27b2956e618ddc9b46b743a2034a5f5 GIT binary patch literal 6148 zcmeHK-AV#M6#hoNkcyHb=yG2m$p;8lv5Ri=1@fm%aNEU<=pxwX={0(l9;ENg9KvNa zH6kL;ku%@?of*GRW{v~Ebsk48paGyx7p(2DSYk3RUb2ez>=B(`V~7;@Xrhm-G}}5% z0aM_wDIjO}5N)2<43}6uzZoXle!vap({ZaeOp|b~E3Yq`#wBUDJD8>e&X-H%pmP4! z-aK~n?bz&Y;rmw4xFz<Q=sQXxi)v0@&OBQzI6i6PYK6T^jY_D4D|R?Gv2 za5#N@INjOl3&r`}xqjrQ!^HuuGzCn7q5{>>Y)JmUSpEJl23gA#Fa`dV0Tp(3Ncp91G0x^e+0Y?R+s|6s=x>G29aI> literal 0 HcmV?d00001 diff --git a/SampleApp/SampleApp/Base.lproj/Main.storyboard b/SampleApp/SampleApp/Base.lproj/Main.storyboard index e670ab3..69cf77a 100644 --- a/SampleApp/SampleApp/Base.lproj/Main.storyboard +++ b/SampleApp/SampleApp/Base.lproj/Main.storyboard @@ -1,15 +1,68 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -19,23 +72,23 @@ - + - - + @@ -100,7 +153,7 @@ - + @@ -162,6 +215,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -175,7 +501,7 @@ - + @@ -227,10 +553,10 @@ - + + + + + + + + - + @@ -326,9 +686,9 @@ - + - + @@ -351,7 +711,7 @@ - + @@ -376,42 +736,10 @@ - + - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - @@ -461,10 +773,7 @@ - - - @@ -484,7 +793,7 @@ - + @@ -587,7 +896,7 @@ - + @@ -642,7 +951,7 @@ - + - + - + @@ -730,14 +1039,14 @@ - + - + - - + - + - + - + + + + @@ -922,7 +1248,7 @@ - + @@ -947,7 +1273,7 @@ - + @@ -999,7 +1325,7 @@ - + @@ -1028,7 +1354,7 @@ - + @@ -1065,7 +1391,7 @@