diff --git a/AutoCat.xcodeproj/project.pbxproj b/AutoCat.xcodeproj/project.pbxproj index 9f1bc5a..4d459c7 100644 --- a/AutoCat.xcodeproj/project.pbxproj +++ b/AutoCat.xcodeproj/project.pbxproj @@ -46,10 +46,6 @@ 7A3F07AB24360DC800E59687 /* Dated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AA24360DC800E59687 /* Dated.swift */; }; 7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AC2436350B00E59687 /* SearchController.swift */; }; 7A43F9F8246C8A6200BA5B49 /* JWT.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A43F9F7246C8A6200BA5B49 /* JWT.swift */; }; - 7A488C3C24A74B990054D0B2 /* RxTableViewRealmDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A488C3824A74B990054D0B2 /* RxTableViewRealmDataSource.swift */; }; - 7A488C3D24A74B990054D0B2 /* RxCollectionViewRealmDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A488C3924A74B990054D0B2 /* RxCollectionViewRealmDataSource.swift */; }; - 7A488C3E24A74B990054D0B2 /* Reactive+RxRealmDataSources.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A488C3A24A74B990054D0B2 /* Reactive+RxRealmDataSources.swift */; }; - 7A488C3F24A74B990054D0B2 /* RealmBindObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A488C3B24A74B990054D0B2 /* RealmBindObserver.swift */; }; 7A530B7A24001D3300CBFE6E /* CheckController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7924001D3300CBFE6E /* CheckController.swift */; }; 7A530B7E24017FEE00CBFE6E /* VehicleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */; }; 7A530B802401803A00CBFE6E /* Vehicle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7F2401803A00CBFE6E /* Vehicle.swift */; }; @@ -58,12 +54,6 @@ 7A64AE742469DFB600ABE48E /* MediaContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE702469DFB600ABE48E /* MediaContentView.swift */; }; 7A64AE752469DFB600ABE48E /* MediaBrowserViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE712469DFB600ABE48E /* MediaBrowserViewController.swift */; }; 7A64AE762469DFB600ABE48E /* ContentTransformers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE722469DFB600ABE48E /* ContentTransformers.swift */; }; - 7A64AE7E2469E16100ABE48E /* RadialGradientLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE782469E16100ABE48E /* RadialGradientLayer.swift */; }; - 7A64AE7F2469E16100ABE48E /* IndefiniteAnimatedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE792469E16100ABE48E /* IndefiniteAnimatedView.swift */; }; - 7A64AE802469E16100ABE48E /* .gitkeep in Resources */ = {isa = PBXBuildFile; fileRef = 7A64AE7A2469E16100ABE48E /* .gitkeep */; }; - 7A64AE812469E16100ABE48E /* ProgressAnimatedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE7B2469E16100ABE48E /* ProgressAnimatedView.swift */; }; - 7A64AE822469E16100ABE48E /* IHProgressHUD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE7C2469E16100ABE48E /* IHProgressHUD.swift */; }; - 7A64AE832469E16100ABE48E /* IHProgressHUD.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 7A64AE7D2469E16100ABE48E /* IHProgressHUD.bundle */; }; 7A659B5924A2B1BA0043A0F2 /* AudioRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A659B5824A2B1BA0043A0F2 /* AudioRecord.swift */; }; 7A659B5B24A3768A0043A0F2 /* Substrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A659B5A24A3768A0043A0F2 /* Substrings.swift */; }; 7A6DD903242BF4A5009DE740 /* PlateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6DD902242BF4A5009DE740 /* PlateView.swift */; }; @@ -89,6 +79,7 @@ 7A96AE31246B2FE400297C33 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE30246B2FE400297C33 /* Constants.swift */; }; 7A96AE33246C095700297C33 /* Base64FS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE32246C095700297C33 /* Base64FS.swift */; }; 7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FEEC72529AB23001CA50E /* RxRealmDataSource.swift */; }; + 7AABDE1D2532F3EB0041AFC6 /* PKHUD in Frameworks */ = {isa = PBXBuildFile; productRef = 7AABDE1C2532F3EB0041AFC6 /* PKHUD */; }; 7AAE6AD324CDDF950023860B /* VehicleEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AAE6AD224CDDF950023860B /* VehicleEvent.swift */; }; 7AB562BA249C9E9B00473D53 /* Region.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB562B9249C9E9B00473D53 /* Region.swift */; }; 7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB67E8B2435C38700258F61 /* CustomTextField.swift */; }; @@ -145,10 +136,6 @@ 7A3F07AA24360DC800E59687 /* Dated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dated.swift; sourceTree = ""; }; 7A3F07AC2436350B00E59687 /* SearchController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchController.swift; sourceTree = ""; }; 7A43F9F7246C8A6200BA5B49 /* JWT.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JWT.swift; sourceTree = ""; }; - 7A488C3824A74B990054D0B2 /* RxTableViewRealmDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxTableViewRealmDataSource.swift; sourceTree = ""; }; - 7A488C3924A74B990054D0B2 /* RxCollectionViewRealmDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCollectionViewRealmDataSource.swift; sourceTree = ""; }; - 7A488C3A24A74B990054D0B2 /* Reactive+RxRealmDataSources.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Reactive+RxRealmDataSources.swift"; sourceTree = ""; }; - 7A488C3B24A74B990054D0B2 /* RealmBindObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmBindObserver.swift; sourceTree = ""; }; 7A530B7924001D3300CBFE6E /* CheckController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckController.swift; sourceTree = ""; }; 7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleCell.swift; sourceTree = ""; }; 7A530B7F2401803A00CBFE6E /* Vehicle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Vehicle.swift; sourceTree = ""; }; @@ -157,12 +144,6 @@ 7A64AE702469DFB600ABE48E /* MediaContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaContentView.swift; sourceTree = ""; }; 7A64AE712469DFB600ABE48E /* MediaBrowserViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaBrowserViewController.swift; sourceTree = ""; }; 7A64AE722469DFB600ABE48E /* ContentTransformers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentTransformers.swift; sourceTree = ""; }; - 7A64AE782469E16100ABE48E /* RadialGradientLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadialGradientLayer.swift; sourceTree = ""; }; - 7A64AE792469E16100ABE48E /* IndefiniteAnimatedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IndefiniteAnimatedView.swift; sourceTree = ""; }; - 7A64AE7A2469E16100ABE48E /* .gitkeep */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; - 7A64AE7B2469E16100ABE48E /* ProgressAnimatedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressAnimatedView.swift; sourceTree = ""; }; - 7A64AE7C2469E16100ABE48E /* IHProgressHUD.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IHProgressHUD.swift; sourceTree = ""; }; - 7A64AE7D2469E16100ABE48E /* IHProgressHUD.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = IHProgressHUD.bundle; sourceTree = ""; }; 7A659B5824A2B1BA0043A0F2 /* AudioRecord.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRecord.swift; sourceTree = ""; }; 7A659B5A24A3768A0043A0F2 /* Substrings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Substrings.swift; sourceTree = ""; }; 7A6DD902242BF4A5009DE740 /* PlateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlateView.swift; sourceTree = ""; }; @@ -223,6 +204,7 @@ 7A96AE2A246AFD6200297C33 /* Eureka in Frameworks */, 7A051611241412CA00FC55AC /* SwiftDate in Frameworks */, 7A11472323FEA18700B424AF /* RxBlocking in Frameworks */, + 7AABDE1D2532F3EB0041AFC6 /* PKHUD in Frameworks */, 7A530B8B240181F500CBFE6E /* RxRealm in Frameworks */, 7A11471F23FEA18700B424AF /* RxRelay in Frameworks */, 7AF58D2F24029C5200CE01A0 /* MagazineLayout in Frameworks */, @@ -295,8 +277,6 @@ 7A11472C23FECA3E00B424AF /* ThirdParty */ = { isa = PBXGroup; children = ( - 7A488C3724A74B990054D0B2 /* RxRealmDataSources */, - 7A64AE772469E16100ABE48E /* IHProgressHUD */, 7A64AE6E2469DFB600ABE48E /* ATGMediaBrowser */, 7A6DD90724329144009DE740 /* CenterTextLayer.swift */, 7A96AE32246C095700297C33 /* Base64FS.swift */, @@ -366,17 +346,6 @@ path = Extensions; sourceTree = ""; }; - 7A488C3724A74B990054D0B2 /* RxRealmDataSources */ = { - isa = PBXGroup; - children = ( - 7A488C3824A74B990054D0B2 /* RxTableViewRealmDataSource.swift */, - 7A488C3924A74B990054D0B2 /* RxCollectionViewRealmDataSource.swift */, - 7A488C3A24A74B990054D0B2 /* Reactive+RxRealmDataSources.swift */, - 7A488C3B24A74B990054D0B2 /* RealmBindObserver.swift */, - ); - path = RxRealmDataSources; - sourceTree = ""; - }; 7A530B7C24017FBE00CBFE6E /* Cells */ = { isa = PBXGroup; children = ( @@ -404,19 +373,6 @@ path = ATGMediaBrowser; sourceTree = ""; }; - 7A64AE772469E16100ABE48E /* IHProgressHUD */ = { - isa = PBXGroup; - children = ( - 7A64AE782469E16100ABE48E /* RadialGradientLayer.swift */, - 7A64AE792469E16100ABE48E /* IndefiniteAnimatedView.swift */, - 7A64AE7A2469E16100ABE48E /* .gitkeep */, - 7A64AE7B2469E16100ABE48E /* ProgressAnimatedView.swift */, - 7A64AE7C2469E16100ABE48E /* IHProgressHUD.swift */, - 7A64AE7D2469E16100ABE48E /* IHProgressHUD.bundle */, - ); - path = IHProgressHUD; - sourceTree = ""; - }; 7A6DD901242BF48D009DE740 /* Views */ = { isa = PBXGroup; children = ( @@ -484,6 +440,7 @@ 7A0516172414EC1200FC55AC /* RxDataSources */, 7A96AE29246AFD6200297C33 /* Eureka */, 7A813DC02508C4D900CC93B9 /* ExceptionCatcher */, + 7AABDE1C2532F3EB0041AFC6 /* PKHUD */, ); productName = AutoCat; productReference = 7A1146FD23FDE7E500B424AF /* AutoCat.app */; @@ -523,6 +480,7 @@ 7A0516142414EC1200FC55AC /* XCRemoteSwiftPackageReference "RxDataSources" */, 7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */, 7A813DBF2508C4D900CC93B9 /* XCRemoteSwiftPackageReference "ExceptionCatcher" */, + 7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */, ); productRefGroup = 7A1146FE23FDE7E500B424AF /* Products */; projectDirPath = ""; @@ -542,10 +500,8 @@ 7A7547DE2403180A004E8406 /* SectionHeader.xib in Resources */, 7A11470D23FDE7E600B424AF /* LaunchScreen.storyboard in Resources */, 7A6DD90A24329541009DE740 /* RoadNumbers2.0.otf in Resources */, - 7A64AE802469E16100ABE48E /* .gitkeep in Resources */, 7A11470A23FDE7E600B424AF /* Assets.xcassets in Resources */, 7A11470823FDE7E500B424AF /* Main.storyboard in Resources */, - 7A64AE832469E16100ABE48E /* IHProgressHUD.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -560,7 +516,6 @@ 7A96AE33246C095700297C33 /* Base64FS.swift in Sources */, 7A530B802401803A00CBFE6E /* Vehicle.swift in Sources */, 7A96AE31246B2FE400297C33 /* Constants.swift in Sources */, - 7A64AE822469E16100ABE48E /* IHProgressHUD.swift in Sources */, 7A11470123FDE7E500B424AF /* AppDelegate.swift in Sources */, 7ADF6C9D250FA96000F237B2 /* SwiftMaskTextfield.swift in Sources */, 7A27ADF924A09CAD0035F39E /* CocoaError.swift in Sources */, @@ -570,7 +525,6 @@ 7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */, 7AB562BA249C9E9B00473D53 /* Region.swift in Sources */, 7A659B5924A2B1BA0043A0F2 /* AudioRecord.swift in Sources */, - 7A488C3C24A74B990054D0B2 /* RxTableViewRealmDataSource.swift in Sources */, 7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */, 7AE26A3524F31B0700625033 /* EventsController.swift in Sources */, 7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */, @@ -590,8 +544,6 @@ 7A11474923FF2B2D00B424AF /* Response.swift in Sources */, 7A64AE762469DFB600ABE48E /* ContentTransformers.swift in Sources */, 7A11471823FDEBFA00B424AF /* ReportController.swift in Sources */, - 7A64AE7E2469E16100ABE48E /* RadialGradientLayer.swift in Sources */, - 7A64AE7F2469E16100ABE48E /* IndefiniteAnimatedView.swift in Sources */, 7AE24C5F251F1B4E00758E39 /* Buttons.swift in Sources */, 7A11471A23FE839000B424AF /* AuthController.swift in Sources */, 7A530B7A24001D3300CBFE6E /* CheckController.swift in Sources */, @@ -610,18 +562,15 @@ 7A43F9F8246C8A6200BA5B49 /* JWT.swift in Sources */, 7A6DD903242BF4A5009DE740 /* PlateView.swift in Sources */, 7ADF6C9F251201D200F237B2 /* GlobalEventsController.swift in Sources */, - 7A488C3F24A74B990054D0B2 /* RealmBindObserver.swift in Sources */, 7AAE6AD324CDDF950023860B /* VehicleEvent.swift in Sources */, 7A11470323FDE7E500B424AF /* SceneDelegate.swift in Sources */, 7A530B7E24017FEE00CBFE6E /* VehicleCell.swift in Sources */, 7A813DCB250B5DC900CC93B9 /* LocationPickerController.swift in Sources */, 7A11474423FF06CA00B424AF /* Api.swift in Sources */, - 7A488C3D24A74B990054D0B2 /* RxCollectionViewRealmDataSource.swift in Sources */, 7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */, 7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */, 7A21112A24FC3D7E003BBF6F /* AudioEngine.swift in Sources */, 7A8A220B248D67B60073DFD9 /* VehicleReportImage.swift in Sources */, - 7A488C3E24A74B990054D0B2 /* Reactive+RxRealmDataSources.swift in Sources */, 7ADF6C95250D037700F237B2 /* ShowEventController.swift in Sources */, 7A27ADC7249D43210035F39E /* RegionsController.swift in Sources */, 7A05161A2414FF0900FC55AC /* DateSection.swift in Sources */, @@ -630,7 +579,6 @@ 7ADF6C93250B954900F237B2 /* Navigation.swift in Sources */, 7A64AE752469DFB600ABE48E /* MediaBrowserViewController.swift in Sources */, 7A64AE732469DFB600ABE48E /* DismissAnimationController.swift in Sources */, - 7A64AE812469E16100ABE48E /* ProgressAnimatedView.swift in Sources */, 7ADF6C97250F41B000F237B2 /* PNKeyboard.swift in Sources */, 7A000AA224C2EEDE001F5B00 /* Location.swift in Sources */, 7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */, @@ -897,6 +845,14 @@ minimumVersion = 5.2.1; }; }; + 7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/pkluz/PKHUD.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.4.0; + }; + }; 7AF58D2D24029C5200CE01A0 /* XCRemoteSwiftPackageReference "MagazineLayout" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/airbnb/MagazineLayout"; @@ -976,6 +932,11 @@ package = 7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */; productName = Eureka; }; + 7AABDE1C2532F3EB0041AFC6 /* PKHUD */ = { + isa = XCSwiftPackageProductDependency; + package = 7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */; + productName = PKHUD; + }; 7AF58D2E24029C5200CE01A0 /* MagazineLayout */ = { isa = XCSwiftPackageProductDependency; package = 7AF58D2D24029C5200CE01A0 /* XCRemoteSwiftPackageReference "MagazineLayout" */; diff --git a/AutoCat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/AutoCat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 8bb26d0..f1cb54a 100644 --- a/AutoCat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/AutoCat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -37,6 +37,15 @@ "version": "1.6.3" } }, + { + "package": "PKHUD", + "repositoryURL": "https://github.com/pkluz/PKHUD.git", + "state": { + "branch": null, + "revision": "8fd26f23057c6bebd6695524b1c3e05e93aba571", + "version": "5.4.0" + } + }, { "package": "Realm", "repositoryURL": "https://github.com/realm/realm-cocoa", diff --git a/AutoCat/AppDelegate.swift b/AutoCat/AppDelegate.swift index 913574d..6ff3536 100644 --- a/AutoCat/AppDelegate.swift +++ b/AutoCat/AppDelegate.swift @@ -3,6 +3,7 @@ import RealmSwift import RxSwift import RxCocoa import os.log +import PKHUD extension OSLog { static let startup = OSLog(subsystem: "pro.aliencat.autocat.startup", category: "startup") @@ -68,8 +69,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { Realm.Configuration.defaultConfiguration = config - IHProgressHUD.set(defaultStyle: .dark) - IHProgressHUD.set(defaultMaskType: .black) + HUD.dimsBackground = true + HUD.allowsInteraction = false Logging.URLRequests = { _ in false }; diff --git a/AutoCat/Cells/AudioRecordCell.swift b/AutoCat/Cells/AudioRecordCell.swift index b3f71d9..34de807 100644 --- a/AutoCat/Cells/AudioRecordCell.swift +++ b/AutoCat/Cells/AudioRecordCell.swift @@ -1,5 +1,6 @@ import UIKit import RxSwift +import PKHUD class AudioRecordCell: UITableViewCell, ConfigurableCell { @@ -74,7 +75,7 @@ class AudioRecordCell: UITableViewCell, ConfigurableCell { try AudioPlayer.shared.play(url: url) } catch { print("Error playing audio record: \(error.localizedDescription)") - IHProgressHUD.showError(withStatus: error.localizedDescription) + HUD.show(error: error) } } } diff --git a/AutoCat/Controllers/AuthController.swift b/AutoCat/Controllers/AuthController.swift index 281914f..5b5d222 100644 --- a/AutoCat/Controllers/AuthController.swift +++ b/AutoCat/Controllers/AuthController.swift @@ -3,6 +3,7 @@ import RxSwift import RxCocoa import RealmSwift import AuthenticationServices +import PKHUD class AuthController: UIViewController, ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding { @@ -35,20 +36,20 @@ class AuthController: UIViewController, ASAuthorizationControllerDelegate, ASAut @IBAction func loginTapped(_ sender: UIButton) { guard let email = self.username.text, let pass = self.password.text else { return } - IHProgressHUD.show() + HUD.show(.progress) Api.login(email: email, password: pass) .observeOn(MainScheduler.instance) - .subscribe(onSuccess: self.goToMainScreen(user:), onError: self.displayError(error:)) + .subscribe(onSuccess: self.goToMainScreen(user:), onError: HUD.show(error:)) .disposed(by: self.bag) } @IBAction func signupTapped(_ sender: UIButton) { guard let email = self.username.text, let pass = self.password.text else { return } - IHProgressHUD.show() + HUD.show(.progress) Api.signUp(email: email, password: pass) .observeOn(MainScheduler.instance) - .subscribe(onSuccess: self.goToMainScreen(user:), onError: self.displayError(error:)) + .subscribe(onSuccess: self.goToMainScreen(user:), onError: HUD.show(error:)) .disposed(by: self.bag) } @@ -64,29 +65,24 @@ class AuthController: UIViewController, ASAuthorizationControllerDelegate, ASAut } func goToMainScreen(user: User) { -// guard let realm = try? Realm() else { -// IHProgressHUD.showError(withStatus: "Database error") -// return -// } + guard let realm = try? Realm() else { + HUD.flash(.labeledError(title: nil, subtitle: "Database error")) + return + } - IHProgressHUD.dismiss() + HUD.hide() -// if user.email != Settings.shared.user.email { -// try? realm.write { -// realm.deleteAll() -// } -// } + if user.email != Settings.shared.user.email { + try? realm.write { + realm.deleteAll() + } + } Settings.shared.user = user let storyboard = UIStoryboard(name: "Main", bundle: nil) self.view.window?.rootViewController = storyboard.instantiateViewController(identifier: "MainSplitController") } - func displayError(error: Error) { - IHProgressHUD.showError(withStatus: error.localizedDescription) - print(error) - } - // MARK: - Apple SignIn func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor { @@ -97,14 +93,14 @@ class AuthController: UIViewController, ASAuthorizationControllerDelegate, ASAut switch authorization.credential { case let appleIDCredential as ASAuthorizationAppleIDCredential: guard let email = appleIDCredential.email else { - IHProgressHUD.showError(withStatus: "Cannot get email") + HUD.flash(.labeledError(title: nil, subtitle: "Cannot get email")) return } - IHProgressHUD.show() + HUD.show(.progress) Api.signIn(email: email, password: appleIDCredential.user) .observeOn(MainScheduler.instance) - .subscribe(onSuccess: self.goToMainScreen(user:), onError: self.displayError(error:)) + .subscribe(onSuccess: self.goToMainScreen(user:), onError: HUD.show(error:)) .disposed(by: self.bag) if let tokenData = appleIDCredential.identityToken { @@ -116,7 +112,7 @@ class AuthController: UIViewController, ASAuthorizationControllerDelegate, ASAut }) } default: - IHProgressHUD.showError(withStatus: "Unsupported authorization credential") + HUD.flash(.labeledError(title: nil, subtitle: "Unsupported authorization credential")) break } } diff --git a/AutoCat/Controllers/CheckController.swift b/AutoCat/Controllers/CheckController.swift index 65975c6..b46e481 100644 --- a/AutoCat/Controllers/CheckController.swift +++ b/AutoCat/Controllers/CheckController.swift @@ -3,6 +3,7 @@ import RealmSwift import RxSwift import SwiftDate import RxRealm +import PKHUD enum EventAction { case doNotSend @@ -99,12 +100,12 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat self.number.text = nil self.check.isEnabled = false - IHProgressHUD.show() + HUD.show(.progress) self.check(number: numberNormalized, action: .receiveAndSend).subscribe { vehicle in self.updateDetailController(with: vehicle) - IHProgressHUD.dismiss() + HUD.hide() } onError: { error in - IHProgressHUD.show(error: error) + HUD.show(error: error) } .disposed(by: self.bag) @@ -198,7 +199,7 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat // MARK: - Contextual actions func update(vehicle: Vehicle) { - IHProgressHUD.show() + HUD.show(.progress) var eventAction: EventAction = .doNotSend if vehicle.unrecognized, let savedEvent = vehicle.events.first { @@ -207,9 +208,9 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat self.check(number: vehicle.getNumber(), action: eventAction, force: true).subscribe { vehicle in self.updateDetailController(with: vehicle) - IHProgressHUD.dismiss() + HUD.hide() } onError: { error in - IHProgressHUD.show(error: error) + HUD.show(error: error) } .disposed(by: self.bag) } diff --git a/AutoCat/Controllers/GoogleSignInController.swift b/AutoCat/Controllers/GoogleSignInController.swift index feb1468..bd61bad 100644 --- a/AutoCat/Controllers/GoogleSignInController.swift +++ b/AutoCat/Controllers/GoogleSignInController.swift @@ -2,6 +2,7 @@ import UIKit import WebKit import CommonCrypto import RxSwift +import PKHUD struct TokenResponse: Codable { var id_token: String @@ -58,7 +59,7 @@ class GoogleSignInController: UIViewController, WKNavigationDelegate { .subscribe(onSuccess: { _ in self.dismiss(animated: true, completion: self.completion) }, onError: { error in - IHProgressHUD.showError(withStatus: error.localizedDescription) + HUD.flash(.labeledError(title: nil, subtitle: error.localizedDescription)) }) .disposed(by: self.bag) return diff --git a/AutoCat/Controllers/Location/EventsController.swift b/AutoCat/Controllers/Location/EventsController.swift index b44f414..74cd342 100644 --- a/AutoCat/Controllers/Location/EventsController.swift +++ b/AutoCat/Controllers/Location/EventsController.swift @@ -3,6 +3,7 @@ import MapKit import RxSwift import Realm import RealmSwift +import PKHUD class EventPin: NSObject, MKAnnotation { var coordinate: CLLocationCoordinate2D @@ -148,18 +149,18 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele func deleteEvent(index: Int, completion: @escaping (Bool) -> Void) { guard let vehicle = self.vehicle else { - IHProgressHUD.showError(withStatus: "Unknown vehicle") + HUD.flash(.labeledError(title: nil, subtitle: "Unknown vehicle")) return } let event = vehicle.events[index] if let eventId = event.id { - IHProgressHUD.show() + HUD.show(.progress) Api.remove(event: eventId).observeOn(MainScheduler.instance).subscribe(onSuccess: { vehicle in completion(self.update(vehicle: vehicle)) }, onError: { error in completion(false) - IHProgressHUD.show(error: error) + HUD.show(error: error) print(error) }).disposed(by: self.bag) } else { @@ -169,7 +170,7 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele func editEvent(index: Int) { guard let vehicle = self.vehicle else { - IHProgressHUD.showError(withStatus: "Unknown vehicle") + HUD.flash(.labeledError(title: nil, subtitle: "Unknown vehicle")) return } @@ -182,12 +183,12 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele controller.onDone = { newEvent in newEvent.id = event.id self.navigationController?.popViewController(animated: true, completion: { - IHProgressHUD.show() + HUD.show(.progress) Api.edit(event: newEvent) .observeOn(MainScheduler.instance) .subscribe(onSuccess: { self.update(vehicle: $0) }, onError: { error in - IHProgressHUD.show(error: error) + HUD.show(error: error) }) .disposed(by: self.bag) }) @@ -197,7 +198,7 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele @objc func addEvent(_ sender: UIBarButtonItem) { guard let vehicle = self.vehicle else { - IHProgressHUD.showError(withStatus: "Unknown vehicle") + HUD.flash(.labeledError(title: nil, subtitle: "Unknown vehicle")) return } @@ -206,12 +207,12 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele controller.title = "Add new event" controller.onDone = { newEvent in self.navigationController?.popViewController(animated: true, completion: { - IHProgressHUD.show() + HUD.show(.progress) Api.add(event: newEvent, to: vehicle.getNumber()) .observeOn(MainScheduler.instance) .subscribe(onSuccess: { self.update(vehicle: $0) }, onError: { error in - IHProgressHUD.show(error: error) + HUD.show(error: error) }) .disposed(by: self.bag) }) @@ -231,10 +232,10 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele self.vehicle?.events.append(objectsIn: vehicle.events) } self.updateInterface() - IHProgressHUD.dismiss() + HUD.hide() return true } catch { - IHProgressHUD.show(error: error) + HUD.show(error: error) print(error) return false } diff --git a/AutoCat/Controllers/Location/GlobalEventsController.swift b/AutoCat/Controllers/Location/GlobalEventsController.swift index ea7c721..7f97422 100644 --- a/AutoCat/Controllers/Location/GlobalEventsController.swift +++ b/AutoCat/Controllers/Location/GlobalEventsController.swift @@ -1,6 +1,7 @@ import UIKit import MapKit import RxSwift +import PKHUD class GlobalEventsController: UIViewController { @@ -16,7 +17,7 @@ class GlobalEventsController: UIViewController { self.map.showsZoomControls = true #endif - IHProgressHUD.show() + HUD.show(.progress) Api.events(with: self.filter) .observeOn(MainScheduler.init()) .subscribe(onSuccess: { events in @@ -25,9 +26,9 @@ class GlobalEventsController: UIViewController { self.map.removeAnnotations(self.map.annotations) self.map.addAnnotations(pins) self.map.centerOnPins() - IHProgressHUD.dismiss() + HUD.hide() }) { error in - IHProgressHUD.show(error: error) + HUD.show(error: error) } .disposed(by: self.bag) } diff --git a/AutoCat/Controllers/RecordsController.swift b/AutoCat/Controllers/RecordsController.swift index d302e6a..d8c97f3 100644 --- a/AutoCat/Controllers/RecordsController.swift +++ b/AutoCat/Controllers/RecordsController.swift @@ -7,6 +7,7 @@ import Intents import CoreSpotlight import MobileCoreServices import os.log +import PKHUD class RecordsController: UIViewController, UITableViewDelegate { @@ -84,7 +85,7 @@ class RecordsController: UIViewController, UITableViewDelegate { @objc func onAddVoiceRecord(_ sender: UIBarButtonItem) { guard let recorder = self.recorder else { - IHProgressHUD.showError(withStatus: "Audio recorder is not available") + HUD.flash(.labeledError(title: nil, subtitle: "Audio recorder is not available")) return } @@ -142,10 +143,10 @@ class RecordsController: UIViewController, UITableViewDelegate { }) { error in if let alert = alert { alert.dismiss(animated: true) { - IHProgressHUD.show(error: error) + HUD.show(error: error) } } else { - IHProgressHUD.show(error: error) + HUD.show(error: error) } self.addButton.isEnabled = true } @@ -274,7 +275,7 @@ class RecordsController: UIViewController, UITableViewDelegate { self.present(controller, animated: true) } catch { print("Error sharing audio record: \(error.localizedDescription)") - IHProgressHUD.showError(withStatus: error.localizedDescription) + HUD.show(error: error) } } let showText = UIAlertAction(title: "Show recognized text", style: .default) { action in diff --git a/AutoCat/Controllers/SearchController.swift b/AutoCat/Controllers/SearchController.swift index 1dd6f93..2e6b643 100644 --- a/AutoCat/Controllers/SearchController.swift +++ b/AutoCat/Controllers/SearchController.swift @@ -3,6 +3,7 @@ import RxDataSources import RxSwift import RxCocoa import RealmSwift +import PKHUD class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDelegate { @@ -160,9 +161,9 @@ class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDe } func update(vehicle: Vehicle, at indexPath: IndexPath) { - IHProgressHUD.show() + HUD.show(.progress) Api.checkVehicle(by: vehicle.getNumber(), force: true).observeOn(MainScheduler.instance).subscribe { newVehicle in - IHProgressHUD.dismiss() + HUD.hide() if let realm = try? Realm() { if realm.object(ofType: Vehicle.self, forPrimaryKey: vehicle.getNumber()) != nil { try? realm.write { @@ -173,7 +174,7 @@ class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDe self.datasource[indexPath] = newVehicle self.updateDetailController(with: newVehicle) } onError: { err in - IHProgressHUD.show(error: err) + HUD.show(error: err) }.disposed(by: self.bag) } } diff --git a/AutoCat/Extensions/CocoaError.swift b/AutoCat/Extensions/CocoaError.swift index 0a2c60a..391ddae 100644 --- a/AutoCat/Extensions/CocoaError.swift +++ b/AutoCat/Extensions/CocoaError.swift @@ -1,4 +1,5 @@ import UIKit +import PKHUD extension NSError { var displayMessage: (title: String, body: String) { @@ -50,9 +51,9 @@ extension UIViewController { } } -extension IHProgressHUD { +extension HUD { static func show(error: Error) { let msg = (error as NSError).displayMessage - self.showError(withStatus: msg.title + "\n" + msg.body) + self.flash(.labeledError(title: msg.title, subtitle: msg.body), delay: 2.0) } } diff --git a/AutoCat/SceneDelegate.swift b/AutoCat/SceneDelegate.swift index 50a0162..d822548 100644 --- a/AutoCat/SceneDelegate.swift +++ b/AutoCat/SceneDelegate.swift @@ -2,6 +2,7 @@ import UIKit import os.log import AVFoundation import RxSwift +import PKHUD class SceneDelegate: UIResponder, UIWindowSceneDelegate { @@ -145,7 +146,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func openReport(with number: String) { guard let rootController = self.window?.rootViewController else { return } - IHProgressHUD.show() + HUD.show(.progress) _ = Api.getReport(for: number).observeOn(MainScheduler.instance).subscribe { vehicle in let sb = UIStoryboard(name: "Main", bundle: nil) let controller = sb.instantiateViewController(identifier: "ReportController") as ReportController @@ -154,9 +155,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { nav.modalPresentationStyle = .fullScreen controller.navigationItem.leftBarButtonItem = BlockBarButtonItem(barButtonSystemItem: .close) { _ in nav.dismiss(animated: true) } rootController.present(nav, animated: true) - IHProgressHUD.dismiss() + HUD.hide() } onError: { error in - IHProgressHUD.show(error: error) + HUD.show(error: error) } } } diff --git a/AutoCat/ThirdParty/IHProgressHUD/.gitkeep b/AutoCat/ThirdParty/IHProgressHUD/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/angle-mask@1x.png b/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/angle-mask@1x.png deleted file mode 100644 index ffecbd4..0000000 Binary files a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/angle-mask@1x.png and /dev/null differ diff --git a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/angle-mask@2x.png b/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/angle-mask@2x.png deleted file mode 100644 index 452458e..0000000 Binary files a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/angle-mask@2x.png and /dev/null differ diff --git a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/angle-mask@3x.png b/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/angle-mask@3x.png deleted file mode 100644 index bf8e5e4..0000000 Binary files a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/angle-mask@3x.png and /dev/null differ diff --git a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/error@1x.png b/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/error@1x.png deleted file mode 100644 index 99b3694..0000000 Binary files a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/error@1x.png and /dev/null differ diff --git a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/error@2x.png b/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/error@2x.png deleted file mode 100644 index 5c11ed0..0000000 Binary files a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/error@2x.png and /dev/null differ diff --git a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/error@3x.png b/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/error@3x.png deleted file mode 100644 index 91add09..0000000 Binary files a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/error@3x.png and /dev/null differ diff --git a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/info@1x.png b/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/info@1x.png deleted file mode 100644 index ebf14c4..0000000 Binary files a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/info@1x.png and /dev/null differ diff --git a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/info@2x.png b/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/info@2x.png deleted file mode 100644 index d81cfd8..0000000 Binary files a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/info@2x.png and /dev/null differ diff --git a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/info@3x.png b/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/info@3x.png deleted file mode 100644 index 6539bda..0000000 Binary files a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/info@3x.png and /dev/null differ diff --git a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/success@1x.png b/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/success@1x.png deleted file mode 100644 index 03338a3..0000000 Binary files a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/success@1x.png and /dev/null differ diff --git a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/success@2x.png b/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/success@2x.png deleted file mode 100644 index b70ab2b..0000000 Binary files a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/success@2x.png and /dev/null differ diff --git a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/success@3x.png b/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/success@3x.png deleted file mode 100644 index 94d545b..0000000 Binary files a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/success@3x.png and /dev/null differ diff --git a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.swift b/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.swift deleted file mode 100755 index 0e3ff45..0000000 --- a/AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.swift +++ /dev/null @@ -1,1317 +0,0 @@ -// -// Converted to Swift 4 by Swiftify v4.2.29618 - https://objectivec2swift.com/ -// -// IndefiniteAnimatedView.swift -// SVProgressHUD, https://github.com/IHProgressHUD/IHProgressHUD -// -// Original Copyright (c) 2014-2018 Guillaume Campagna. All rights reserved. -// Modified Copyright © 2018 Ibrahim Hassan. All rights reserved. -// - - -import UIKit - -public enum NotificationName : String { - case IHProgressHUDDidReceiveTouchEvent, IHProgressHUDDidTouchDownInside, IHProgressHUDWillDisappear, IHProgressHUDDidDisappear, IHProgressHUDWillAppear, IHProgressHUDDidAppear, IHProgressHUDStatusUserInfoKey - public func getNotificationName() -> Notification.Name { - return Notification.Name.init(self.rawValue) - } -} - -public enum IHProgressHUDStyle : Int { - case light - case dark - case custom -} - -public enum IHProgressHUDMaskType : Int { - case none = 1 - case clear - case black - case gradient - case custom -} - -public enum IHProgressHUDAnimationType : Int { - case flat - case native -} - -private let IHProgressHUDParallaxDepthPoints : CGFloat = 10.0 -private let IHProgressHUDUndefinedProgress : CGFloat = -1 -private let IHProgressHUDDefaultAnimationDuration: CGFloat = 0.15 -private let IHProgressHUDVerticalSpacing: CGFloat = 12.0 -private let IHProgressHUDHorizontalSpacing: CGFloat = 12.0 -private let IHProgressHUDLabelSpacing: CGFloat = 8.0 - -public class IHProgressHUD : UIView { - - static var isNotAppExtension = true - - private var defaultStyle = IHProgressHUDStyle.light - private var defaultMaskType = IHProgressHUDMaskType.none - private var defaultAnimationType = IHProgressHUDAnimationType.flat - private var containerView: UIView? - private var minimumSize = CGSize.init(width: 50, height: 50) - private var ringThickness: CGFloat = 2.0 - private var ringRadius: CGFloat = 18.0 - private var ringNoTextRadius: CGFloat = 24.0 - private var cornerRadius: CGFloat = 14.0 - private var font = UIFont.preferredFont(forTextStyle: .subheadline) - private var foregroundColor : UIColor? - private var backgroundLayerColor = UIColor.init(white: 0, alpha: 0.4) - private var imageViewSize: CGSize = CGSize.init(width: 28, height: 28) - private var shouldTintImages : Bool = true - private var infoImage: UIImage! - private var successImage: UIImage! //= UIImage.init(named: "success")! - private var errorImage: UIImage! //= UIImage.init(named: "error")! - private var viewForExtension: UIView? - private var graceTimeInterval: TimeInterval = 0.0 - private var minimumDismissTimeInterval: TimeInterval = 5.0 - private var maximumDismissTimeInterval: TimeInterval = TimeInterval(CGFloat.infinity) - private var offsetFromCenter: UIOffset = UIOffset.init(horizontal: 0, vertical: 0) - private var fadeInAnimationDuration: TimeInterval = TimeInterval(IHProgressHUDDefaultAnimationDuration) - private var fadeOutAnimationDuration: TimeInterval = TimeInterval(IHProgressHUDDefaultAnimationDuration) - private var maxSupportedWindowLevel: UIWindow.Level = UIWindow.Level.normal - private var hapticsEnabled = false - private var graceTimer: Timer? - private var fadeOutTimer: Timer? - private var controlView: UIControl? - private var backgroundView: UIView? - private var backgroundRadialGradientLayer: RadialGradientLayer? - private var hudView: UIVisualEffectView? - private var statusLabel: UILabel? - private var imageView: UIImageView? - private var indefiniteAnimatedView: IndefiniteAnimatedView? - private var ringView: ProgressAnimatedView? - private var backgroundRingView: ProgressAnimatedView? - private var progress: Float = 0.0 - private var activityCount: Int = 0 - private var visibleKeyboardHeight: CGFloat = 0.0 - private var frontWindow: UIWindow? - private var hudBackgroundColor : UIColor? - #if os(iOS) - @available(iOS 10.0, *) - private var hapticGenerator: UINotificationFeedbackGenerator? { - get { - if hapticsEnabled == true { - return UINotificationFeedbackGenerator() - } else { - return nil - } - } - } - #endif - private override init(frame: CGRect) { - super.init(frame: frame) - infoImage = loadImageBundle(named: "info")! - successImage = loadImageBundle(named: "success")! - errorImage = loadImageBundle(named: "error") - isUserInteractionEnabled = false - activityCount = 0 - getBackGroundView().alpha = 0.0 - getImageView().alpha = 0.0 - getStatusLabel().alpha = 1.0 - getIndefiniteAnimatedView().alpha = 0.0 - getBackgroundRingView().alpha = 0.0 - backgroundColor = UIColor.clear - accessibilityIdentifier = "IHProgressHUD" - isAccessibilityElement = true - } - - required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - } - - private func getIndefiniteAnimatedView() -> IndefiniteAnimatedView { - if defaultAnimationType == .flat { - if (indefiniteAnimatedView == nil) { - indefiniteAnimatedView = IndefiniteAnimatedView.init(frame: .zero) - } - indefiniteAnimatedView?.setIndefinite(strokeColor: foreGroundColorForStyle()) - indefiniteAnimatedView?.setIndefinite(strokeThickness: ringThickness) - var radius :CGFloat = 0.0 - if getStatusLabel().text != nil { - radius = ringRadius - } else { - radius = ringNoTextRadius - } - indefiniteAnimatedView?.setIndefinite(radius: radius) - } else { - indefiniteAnimatedView?.removeAnimationLayer() - indefiniteAnimatedView?.setActivityIndicator(color: foreGroundColorForStyle()) - indefiniteAnimatedView?.startAnimation() - } - indefiniteAnimatedView?.sizeToFit() - return indefiniteAnimatedView! - } - - private static let sharedView : IHProgressHUD = { - var localInstance : IHProgressHUD? - if Thread.current.isMainThread { - if IHProgressHUD.isNotAppExtension { - if let window = UIApplication.shared.delegate?.window { - localInstance = IHProgressHUD.init(frame: window?.bounds ?? CGRect.zero) - } else { - localInstance = IHProgressHUD() - } - } - else { - localInstance = IHProgressHUD.init(frame: UIScreen.main.bounds) - } - } else { - DispatchQueue.main.sync { - if IHProgressHUD.isNotAppExtension { - if let window = UIApplication.shared.delegate?.window { - localInstance = IHProgressHUD.init(frame: window?.bounds ?? CGRect.zero) - } else { - localInstance = IHProgressHUD() - } - } else { - localInstance = IHProgressHUD.init(frame: UIScreen.main.bounds) - } - } - } - return localInstance! - }() - - // MARK :- Setters - - private func showProgress(progress: Float, status: String?) { - OperationQueue.main.addOperation({ [weak self] in - guard let strongSelf = self else { return } - if strongSelf.fadeOutTimer != nil { - strongSelf.activityCount = 0 - } - - // Stop timer - strongSelf.setFadeOut(timer: nil) - strongSelf.setGrace(timer: nil) - - // Update / Check view hierarchy to ensure the HUD is visible - strongSelf.updateViewHierarchy() - - // Reset imageView and fadeout timer if an image is currently displayed - strongSelf.getImageView().isHidden = true - strongSelf.getImageView().image = nil - - // Update text and set progress to the given value - strongSelf.getStatusLabel().isHidden = (status?.count ?? 0) == 0 - strongSelf.getStatusLabel().text = status - strongSelf.progress = progress - - // Choose the "right" indicator depending on the progress - if progress >= 0 { - // Cancel the indefiniteAnimatedView, then show the ringLayer - strongSelf.cancelIndefiniteAnimatedViewAnimation() - - // Add ring to HUD - if strongSelf.getRingView().superview == nil { - strongSelf.getHudView().contentView.addSubview(strongSelf.getRingView()) - } - if strongSelf.getBackgroundRingView().superview == nil { - strongSelf.getHudView().contentView.addSubview(strongSelf.getBackgroundRingView()) - } - - // Set progress animated - CATransaction.begin() - CATransaction.setDisableActions(true) - strongSelf.getRingView().set(strokeEnd: CGFloat(progress)) - // strongSelf.ringView.strokeEnd = progress; - CATransaction.commit() - - // Update the activity count - if progress == 0 { - strongSelf.activityCount += 1 - } - } else { - // Cancel the ringLayer animation, then show the indefiniteAnimatedView - strongSelf.cancelRingLayerAnimation() - - // Add indefiniteAnimatedView to HUD - strongSelf.getHudView().contentView.addSubview(strongSelf.getIndefiniteAnimatedView()) - - if strongSelf.defaultAnimationType == .native { - strongSelf.getIndefiniteAnimatedView().stopActivityIndicator() - } - - // Update the activity count - strongSelf.activityCount += 1 - } - - // Fade in delayed if a grace time is set - if strongSelf.graceTimeInterval > 0.0 && strongSelf.getBackGroundView().alpha == 0.0 { - let timer = Timer(timeInterval: strongSelf.graceTimeInterval, target: strongSelf, selector: #selector(strongSelf.fadeIn(_:)), userInfo: nil, repeats: false) - strongSelf.setGrace(timer: timer) - if let aTimer = strongSelf.graceTimer { - RunLoop.main.add(aTimer, forMode: .common) - } - } else { - strongSelf.fadeIn(nil) - } - - // Tell the Haptics Generator to prepare for feedback, which may come soon - #if os(iOS) - if #available(iOS 10.0, *) { - strongSelf.hapticGenerator?.prepare() - } - #endif - }) - } - - @objc private func controlViewDidReceiveTouchEvent(_ sender: Any?, for event: UIEvent?) { - NotificationCenter.default.post(name: NotificationName.IHProgressHUDDidReceiveTouchEvent.getNotificationName(), object: self, userInfo: notificationUserInfo()) - - if let touchLocation = event?.allTouches?.first?.location(in: self) { - if getHudView().frame.contains(touchLocation) { - NotificationCenter.default.post(name: - NotificationName.IHProgressHUDDidTouchDownInside.getNotificationName(), object: self, userInfo: notificationUserInfo()) - } - } - - } - - func notificationUserInfo() -> [String : Any]? { - if let statusText = getStatusLabel().text { - return [NotificationName.IHProgressHUDStatusUserInfoKey.rawValue: statusText] - } - return nil - } - - - @objc private func fadeIn(_ object: AnyObject?) { - updateHUDFrame() - positionHUD() - if (defaultMaskType != .none) { - getControlView().isUserInteractionEnabled = true - accessibilityLabel = getStatusLabel().text ?? "Loading" - isAccessibilityElement = true - getControlView().accessibilityViewIsModal = true - } else { - getControlView().isUserInteractionEnabled = false - getHudView().accessibilityLabel = getStatusLabel().text ?? "Loading" - getHudView().isAccessibilityElement = true - getControlView().accessibilityViewIsModal = false - } - - if getBackGroundView().alpha != 1.0 { - NotificationCenter.default.post(name: NotificationName.IHProgressHUDWillAppear.getNotificationName(), object: self, userInfo: notificationUserInfo()) - - getHudView().transform = CGAffineTransform.init(scaleX: 1/1.5, y: 1/1.5) - let animationsBlock : () -> Void = { - // Zoom HUD a little to make a nice appear / pop up animation - self.getHudView().transform = CGAffineTransform.identity - - // Fade in all effects (colors, blur, etc.) - self.fadeInEffects() - } - - - let completionBlock : () -> Void = { - if self.getBackGroundView().alpha == 1.0 { - self.registerNotifications() - } - - NotificationCenter.default.post(name: NotificationName.IHProgressHUDDidAppear.getNotificationName(), object: self, userInfo: self.notificationUserInfo()) - - // Update accessibility - - UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: nil) - - UIAccessibility.post(notification: UIAccessibility.Notification.announcement, argument: self.statusLabel?.text) - if let cd : TimeInterval = object as? TimeInterval { - let timer = Timer.init(timeInterval: cd, target: self, selector: #selector(self.dismiss), userInfo: nil, repeats: false) - self.setFadeOut(timer: timer) - RunLoop.main.add(self.fadeOutTimer!, forMode: .common) - } - } - - if fadeInAnimationDuration > 0 { - UIView.animate(withDuration: self.fadeInAnimationDuration, delay: 0, options: [.allowUserInteraction, .curveEaseIn, .beginFromCurrentState], animations: animationsBlock, completion: { - finished in - completionBlock() - }) - } else { - animationsBlock() - completionBlock() - } - self.setNeedsDisplay() - } else { - UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: nil) - - UIAccessibility.post(notification: UIAccessibility.Notification.announcement, argument: self.statusLabel?.text) - - if let convertedDuration : TimeInterval = object as? TimeInterval { - let timer = Timer.init(timeInterval: convertedDuration, target: self, selector: #selector(dismiss), userInfo: nil, repeats: false) - setFadeOut(timer: timer) - RunLoop.main.add(self.fadeOutTimer!, forMode: .common) - } - } - } - - @objc private func positionHUD(_ notification: Notification? = nil) { - var keyboardHeight: CGFloat = 0.0 - var animationDuration: Double = 0.0 - - if IHProgressHUD.isNotAppExtension == false { - if viewForExtension != nil { - frame = viewForExtension!.frame - } else { - frame = UIScreen.main.bounds - } - } - - var statusBarFrame = CGRect.zero - - #if os(iOS) // notAppExtension + iOS - var orientation = UIInterfaceOrientation.portrait - if IHProgressHUD.isNotAppExtension { - if #available(iOS 13.0, *) { - var rootVC:UIViewController? = nil - for scene in UIApplication.shared.connectedScenes { - if scene.activationState == .foregroundActive { - if let vc = ((scene as? UIWindowScene)?.delegate as? UIWindowSceneDelegate)?.window??.rootViewController { - rootVC = vc - break - } - } - } - frame = rootVC?.view.window?.bounds ?? UIScreen.main.bounds - if let or = rootVC?.view.window?.windowScene?.interfaceOrientation { - orientation = or - } - if let statFrame = rootVC?.view.window?.windowScene?.statusBarManager?.statusBarFrame { - statusBarFrame = statFrame - } - } else { - // Fallback on earlier versions - if let appDelegate = UIApplication.shared.delegate { - if let window = appDelegate.window { - if let windowFrame = window?.bounds { - frame = windowFrame - } - } - } - orientation = UIApplication.shared.statusBarOrientation - statusBarFrame = UIApplication.shared.statusBarFrame - } - - - if frame.width > frame.height { - orientation = .landscapeLeft - } else { - orientation = .portrait - } - if let notificationData = notification { - let keyboardInfo = notificationData.userInfo - if let keyboardFrame: NSValue = keyboardInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue { - let keyboardFrame: CGRect = keyboardFrame.cgRectValue - if (notification?.name.rawValue == UIResponder.keyboardWillShowNotification.rawValue || notification?.name.rawValue == UIResponder.keyboardDidShowNotification.rawValue) { - keyboardHeight = keyboardFrame.width - if orientation.isPortrait { - keyboardHeight = keyboardFrame.height - } - } - } - if let aDuration: Double = keyboardInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double { - animationDuration = aDuration - } - } else { - keyboardHeight = getVisibleKeyboardHeight() - } - - updateMotionEffectForOrientation(orientation) - } - #endif - - let orientationFrame = bounds - #if os(tvOS) - if IHProgressHUD.isNotAppExtension { - if let keyWindow : UIWindow = UIApplication.shared.keyWindow { - frame = keyWindow.bounds - } - } - updateMotionEffect(forXMotionEffectType: .tiltAlongHorizontalAxis, yMotionEffectType: .tiltAlongHorizontalAxis) - #endif - - var activeHeight = orientationFrame.height - - if keyboardHeight > 0 { - activeHeight += statusBarFrame.height * 2 - } - activeHeight -= keyboardHeight - - let posX = orientationFrame.midX - let posY = CGFloat(floor(activeHeight * 0.45)) - - let rotateAngle : CGFloat = 0.0 - let newCenter = CGPoint.init(x: posX, y: posY) - - if notification != nil { - // Animate update if notification was present - UIView.animate(withDuration: TimeInterval(animationDuration), delay: 0, options: [.allowUserInteraction, .beginFromCurrentState], animations: { - self.move(to: newCenter, rotateAngle: rotateAngle) - self.getHudView().setNeedsDisplay() - }) - } else { - move(to: newCenter, rotateAngle: rotateAngle) - } - } - - private func updateViewHierarchy() { - // Add the overlay to the application window if necessary - if getControlView().superview == nil { - if containerView != nil { - self.containerView!.addSubview(getControlView()) - // self.frame = containerView!.frame - } else { - if IHProgressHUD.isNotAppExtension { - if self.containerView != nil { - containerView?.addSubview(getControlView()) - } else { - getFrontWindow()?.addSubview(getControlView()) - } - } - else { - // If IHProgressHUD is used inside an app extension add it to the given view - if viewForExtension != nil { - viewForExtension!.addSubview(getControlView()) - } - } - } - } else { - // The HUD is already on screen, but maybe not in front. Therefore - // ensure that overlay will be on top of rootViewController (which may - // be changed during runtime). - getControlView().superview?.bringSubviewToFront(getControlView()) - } - - // Add self to the overlay view - if superview == nil { - getControlView().addSubview(self) - } - } - - private func cancelIndefiniteAnimatedViewAnimation(){ - self.indefiniteAnimatedView?.stopActivityIndicator() - self.indefiniteAnimatedView?.removeFromSuperview() - } - - private func cancelRingLayerAnimation() { - // Animate value update, stop animation - CATransaction.begin() - CATransaction.setDisableActions(true) - - getHudView().layer.removeAllAnimations() - getRingView().set(strokeEnd: 0.0) - - CATransaction.commit() - - // Remove from view - getRingView().removeFromSuperview() - getBackgroundRingView().removeFromSuperview() - } - - // stops the activity indicator, shows a glyph + status, and dismisses the HUD a little bit later - - private func show(image: UIImage, status: String?, duration: TimeInterval) { - OperationQueue.main.addOperation({ [weak self] in - guard let strongSelf = self else { return } - - strongSelf.setFadeOut(timer: nil) - strongSelf.setGrace(timer: nil) - strongSelf.updateViewHierarchy() - - strongSelf.progress = Float(IHProgressHUDUndefinedProgress) - strongSelf.cancelRingLayerAnimation() - strongSelf.cancelIndefiniteAnimatedViewAnimation() - - if strongSelf.shouldTintImages { - if image.renderingMode != UIImage.RenderingMode.alwaysTemplate { - strongSelf.getImageView().image = image.withRenderingMode(.alwaysTemplate) - strongSelf.getImageView().tintColor = strongSelf.foreGroundColorForStyle() - } - } else { - strongSelf.getImageView().image = image - } - strongSelf.getImageView().isHidden = false - - strongSelf.getStatusLabel().isHidden = status == nil || status?.count == 0 - if let stts = status { - strongSelf.getStatusLabel().text = stts - } - if (strongSelf.graceTimeInterval > 0.0 && strongSelf.getBackGroundView().alpha == 0.0) { - let timer = Timer.init(timeInterval: strongSelf.graceTimeInterval, target: strongSelf, selector: #selector(strongSelf.fadeIn(_:)), userInfo: duration, repeats: false) - strongSelf.setGrace(timer: timer) - RunLoop.main.add(strongSelf.graceTimer!, forMode: .common) - } else { - strongSelf.fadeIn(duration as AnyObject) - } - }) - } - // shows a image + status, use white PNGs with the imageViewSize (default is 28x28 pt) - - private func dismissWithDelay(_ delay: TimeInterval, completion: (() -> Void)?) { - OperationQueue.main.addOperation({ [weak self] in - guard let strongSelf = self else { return } - // Stop timer - strongSelf.setGrace(timer: nil) - // Post notification to inform user - NotificationCenter.default.post(name: NotificationName.IHProgressHUDWillDisappear.getNotificationName(), object: nil, userInfo: strongSelf.notificationUserInfo()) - - // Reset activity count - strongSelf.activityCount = 0 - - let animationsBlock: () -> Void = { - // Shrink HUD a little to make a nice disappear animation - strongSelf.getHudView().transform = strongSelf.getHudView().transform.scaledBy(x: 1 / 1.3, y: 1 / 1.3) - - // Fade out all effects (colors, blur, etc.) - strongSelf.fadeOutEffects() - } - - let completionBlock: (() -> Void) = { - // Check if we really achieved to dismiss the HUD (<=> alpha values are applied) - // and the change of these values has not been cancelled in between e.g. due to a new show - if strongSelf.getBackGroundView().alpha == 0.0 { - // Clean up view hierarchy (overlays) - strongSelf.getControlView().removeFromSuperview() - strongSelf.getBackGroundView().removeFromSuperview() - strongSelf.getHudView().removeFromSuperview() - strongSelf.removeFromSuperview() - - // Reset progress and cancel any running animation - strongSelf.progress = Float(IHProgressHUDUndefinedProgress) - strongSelf.cancelRingLayerAnimation() - strongSelf.cancelIndefiniteAnimatedViewAnimation() - - // Remove observer <=> we do not have to handle orientation changes etc. - NotificationCenter.default.removeObserver(strongSelf) - // Post notification to inform user - //IHProgressHUDDidDisappearNotification - NotificationCenter.default.post(name: NotificationName.IHProgressHUDDidDisappear.getNotificationName(), object: strongSelf, userInfo: strongSelf.notificationUserInfo()) - - // Tell the rootViewController to update the StatusBar appearance - #if os(iOS) - if IHProgressHUD.isNotAppExtension { - if #available(iOS 13.0, *) { - var rootVC:UIViewController? = nil - for scene in UIApplication.shared.connectedScenes { - if scene.activationState == .foregroundActive { - rootVC = ((scene as? UIWindowScene)?.delegate as? UIWindowSceneDelegate)?.window??.rootViewController - break - } - } - rootVC?.setNeedsStatusBarAppearanceUpdate() - } else { - // Fallback on earlier versions - let rootController: UIViewController? = UIApplication.shared.keyWindow?.rootViewController - rootController?.setNeedsStatusBarAppearanceUpdate() - } - - } - #endif - if completion != nil { - completion!() - } - // Run an (optional) completionHandler - - } - } - - // UIViewAnimationOptionBeginFromCurrentState AND a delay doesn't always work as expected - // When UIViewAnimationOptionBeginFromCurrentState is set, animateWithDuration: evaluates the current - // values to check if an animation is necessary. The evaluation happens at function call time and not - // after the delay => the animation is sometimes skipped. Therefore we delay using dispatch_after. - - let dipatchTime = DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) - DispatchQueue.main.asyncAfter(deadline: dipatchTime, execute: { - if strongSelf.fadeOutAnimationDuration > 0 { - UIView.animate(withDuration: strongSelf.fadeOutAnimationDuration, delay: 0, options: [.allowUserInteraction, .curveEaseOut, .beginFromCurrentState], animations: { - animationsBlock() - }) { finished in - completionBlock() - } - }else { - animationsBlock() - completionBlock() - } - }) - - // Inform iOS to redraw the view hierarchy - strongSelf.setNeedsDisplay() - } - ) - } - - @objc private func dismiss() { - dismissWithDelay(0.0, completion: nil) - } - - private func setStatus(_ status: String?) { - getStatusLabel().text = status - updateHUDFrame() - } - - private func updateHUDFrame() { - // Check if an image or progress ring is displayed - let imageUsed: Bool = (getImageView().image) != nil && !((getImageView().isHidden) ) - let progressUsed: Bool = getImageView().isHidden - - // Calculate size of string - var labelRect : CGRect = CGRect.zero - var labelHeight: CGFloat = 0.0 - var labelWidth: CGFloat = 0.0 - - if getStatusLabel().text != nil { - let constraintSize = CGSize(width: 200.0, height: 300.0) - labelRect = getStatusLabel().text?.boundingRect(with: constraintSize, options: [.usesFontLeading, .truncatesLastVisibleLine, .usesLineFragmentOrigin], attributes: [NSAttributedString.Key.font: getStatusLabel().font ?? UIFont.systemFont(ofSize: 15)], context: nil) ?? CGRect.zero - labelHeight = CGFloat(ceilf(Float(labelRect.height ))) - labelWidth = CGFloat(ceilf(Float(labelRect.width ))) - } - - // Calculate hud size based on content - // For the beginning use default values, these - // might get update if string is too large etc. - var hudWidth: CGFloat - var hudHeight: CGFloat - - var contentWidth: CGFloat = 0.0 - var contentHeight: CGFloat = 0.0 - - if (imageUsed || progressUsed) { - if imageUsed { - contentWidth = getImageView().frame.width - contentHeight = getImageView().frame.height - } else { - contentWidth = getIndefiniteAnimatedView().frame.width - contentHeight = getIndefiniteAnimatedView().frame.height - } - } - // |-spacing-content-spacing-| - hudWidth = CGFloat(IHProgressHUDHorizontalSpacing + max(labelWidth, contentWidth) + IHProgressHUDHorizontalSpacing) - - // |-spacing-content-(labelSpacing-label-)spacing-| - hudHeight = CGFloat(IHProgressHUDVerticalSpacing) + labelHeight + contentHeight + CGFloat(IHProgressHUDVerticalSpacing) - if ((getStatusLabel().text != nil) && (imageUsed || progressUsed )) { - // Add spacing if both content and label are used - hudHeight += CGFloat(IHProgressHUDLabelSpacing)//8 [80] - } - - // Update values on subviews - getHudView().bounds = CGRect(x: 0.0, y: 0.0, width: max(minimumSize.width, hudWidth), height: max(minimumSize.height, hudHeight)) - - // Animate value update - CATransaction.begin() - CATransaction.setDisableActions(true) - - // Spinner and image view - var centerY: CGFloat - if getStatusLabel().text != nil { - let yOffset = max(IHProgressHUDVerticalSpacing, (minimumSize.height - contentHeight - CGFloat(IHProgressHUDLabelSpacing) - labelHeight) / 2.0)//12 - centerY = yOffset + contentHeight / 2.0 //26 - } else { - centerY = getHudView().bounds.midY - } - getIndefiniteAnimatedView().center = CGPoint(x: getHudView().bounds.midX, y: centerY) - if CGFloat(progress) != IHProgressHUDUndefinedProgress { - getRingView().center = CGPoint(x: getHudView().bounds.midX , y: centerY) - getBackgroundRingView().center = getRingView().center - } - getImageView().center = CGPoint(x: getHudView().bounds.midX , y: centerY) - // Label - if imageUsed || progressUsed { - if imageUsed { - centerY = getImageView().frame.maxY + IHProgressHUDLabelSpacing + labelHeight / 2.0 - } else { - centerY = getIndefiniteAnimatedView().frame.maxY + IHProgressHUDLabelSpacing + labelHeight / 2.0 - } - } else { - centerY = getHudView().bounds.midY - } - getStatusLabel().frame = labelRect - getStatusLabel().center = CGPoint(x: getHudView().bounds.midX , y: centerY) - CATransaction.commit() - } - - private func registerNotifications() { - #if os(iOS) - if #available(iOS 13.0, *) { - NotificationCenter.default.addObserver(self, selector: #selector(positionHUD(_:)), name: UIDevice.orientationDidChangeNotification, object: nil) - } else { - NotificationCenter.default.addObserver(self, selector: #selector(positionHUD(_:)), name: UIApplication.didChangeStatusBarOrientationNotification, object: nil) - } - NotificationCenter.default.addObserver(self, selector: #selector(self.positionHUD(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) - - NotificationCenter.default.addObserver(self, selector: #selector(self.positionHUD(_:)), name: UIResponder.keyboardDidHideNotification, object: nil) - - NotificationCenter.default.addObserver(self, selector: #selector(self.positionHUD(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) - - NotificationCenter.default.addObserver(self, selector: #selector(self.positionHUD(_:)), name: UIResponder.keyboardDidShowNotification, object: nil) - #endif - NotificationCenter.default.addObserver(self, selector: #selector(self.positionHUD(_:)), name: UIApplication.didBecomeActiveNotification, object: nil) - } - - private func fadeOutEffects() { - if defaultStyle == .custom { - getHudView().effect = nil - } - getHudView().backgroundColor = .clear - getBackGroundView().alpha = 0.0 - - getImageView().alpha = 0.0 - getStatusLabel().alpha = 0.0 - getIndefiniteAnimatedView().alpha = 0.0 - getRingView().alpha = 0 - getBackgroundRingView().alpha = 0 - }// - - private func getBackgroundRingView() -> ProgressAnimatedView { - if backgroundRingView == nil { - backgroundRingView = ProgressAnimatedView.init(frame: .zero) - backgroundRingView?.set(strokeEnd: 1.0) - } - - backgroundRingView?.set(strokeColor: foreGroundColorForStyle().withAlphaComponent(0.1)) - backgroundRingView?.set(strokeThickness: ringThickness) - - var radius : CGFloat = 0.0 - if getStatusLabel().text != nil { - radius = ringRadius - } else { - radius = ringNoTextRadius - } - backgroundRingView?.set(radius: radius) - return backgroundRingView! - } - - private func getRingView() -> ProgressAnimatedView { - if ringView == nil { - ringView = ProgressAnimatedView.init(frame: .zero) - } - - ringView?.set(strokeThickness: ringThickness) - ringView?.set(strokeColor: foreGroundColorForStyle()) - var radius : CGFloat = 0.0 - if getStatusLabel().text != nil { - radius = ringRadius - } else { - radius = ringNoTextRadius - } - ringView?.set(radius: radius) - - return ringView! - } - - private func getImageView() -> UIImageView { - if imageView != nil && imageView?.bounds.size != imageViewSize { - imageView?.removeFromSuperview() - imageView = nil - } - - if imageView == nil { - imageView = UIImageView.init(frame: CGRect.init(x: 0, y: 0, width: imageViewSize.width, height: imageViewSize.height)) - } - if imageView?.superview == nil { - getHudView().contentView.addSubview(imageView!) - } - - return imageView! - } - - private func getStatusLabel() -> UILabel { - if statusLabel == nil { - statusLabel = UILabel.init(frame: .zero) - statusLabel?.backgroundColor = .clear - statusLabel?.adjustsFontSizeToFitWidth = true - statusLabel?.textAlignment = .center - statusLabel?.baselineAdjustment = .alignCenters - statusLabel?.numberOfLines = 0 - } - if statusLabel?.superview == nil && statusLabel != nil { - getHudView().contentView.addSubview(statusLabel!) - } - statusLabel?.textColor = foreGroundColorForStyle() - statusLabel?.font = font - statusLabel?.alpha = 1.0 - statusLabel?.isHidden = false - return statusLabel! - } - - private func fadeInEffects() { - if defaultStyle != .custom { - var blurStyle = UIBlurEffect.Style.light - if defaultStyle == .dark { - blurStyle = UIBlurEffect.Style.light - } - let blurEffect = UIBlurEffect.init(style: blurStyle) - getHudView().effect = blurEffect - - getHudView().backgroundColor = backgroundColorForStyle().withAlphaComponent(0.6) - } else { - getHudView().backgroundColor = backgroundColorForStyle() - } - - getBackGroundView().alpha = 1.0 - getImageView().alpha = 1.0 - getIndefiniteAnimatedView().alpha = 1.0 - getRingView().alpha = 1.0 - getBackgroundRingView().alpha = 1.0 - } - - private func backgroundColorForStyle() -> UIColor { - if defaultStyle == .light { - return .white - } else if defaultStyle == .dark { - return .black - } else { - let color = hudBackgroundColor ?? backgroundColor! - return color - } - } - - private func getFrontWindow() -> UIWindow? { - if IHProgressHUD.isNotAppExtension { - let frontToBackWindows: NSEnumerator = (UIApplication.shared.windows as NSArray).reverseObjectEnumerator() - for window in frontToBackWindows { - guard let win : UIWindow = window as? UIWindow else {return nil} - let windowOnMainScreen: Bool = win.screen == UIScreen.main - let windowIsVisible: Bool = !win.isHidden && (win.alpha > 0) - var windowLevelSupported = false - windowLevelSupported = win.windowLevel >= UIWindow.Level.normal && win.windowLevel <= maxSupportedWindowLevel - - let windowKeyWindow = win.isKeyWindow - print("=====================================") - print("windowOnMainScreen: \(windowOnMainScreen)") - print("windowIsVisible: \(windowIsVisible)") - print("windowLevelSupported: \(windowLevelSupported)") - print("windowKeyWindow: \(windowKeyWindow)") - - if windowOnMainScreen && windowIsVisible && windowLevelSupported && windowKeyWindow { - return win - } - } - } - return nil - } - - private func getVisibleKeyboardHeight() -> CGFloat { - if IHProgressHUD.isNotAppExtension { - var keyboardWindow : UIWindow? = nil - for testWindow in UIApplication.shared.windows { - if !testWindow.self.isEqual(UIWindow.self) { - keyboardWindow = testWindow - break - } - } - for possibleKeyboard in keyboardWindow?.subviews ?? [] { - var viewName = String.init(describing: possibleKeyboard.self) - if viewName.hasPrefix("UI") { - if viewName.hasSuffix("PeripheralHostView") || viewName.hasSuffix("Keyboard") { - return possibleKeyboard.bounds.height - } else if viewName.hasSuffix("InputSetContainerView") { - for possibleKeyboardSubview: UIView? in possibleKeyboard.subviews { - viewName = String.init(describing: possibleKeyboardSubview.self) - if viewName.hasPrefix("UI") && viewName.hasSuffix("InputSetHostView") { - let convertedRect = possibleKeyboard.convert(possibleKeyboardSubview?.frame ?? CGRect.zero, to: self) - let intersectedRect: CGRect = convertedRect.intersection(bounds) - if !intersectedRect.isNull { - return intersectedRect.height - } - } - } - } - } - } - } - return 0 - } - - #if os(iOS) - private func updateMotionEffectForOrientation(_ orientation: UIInterfaceOrientation) { - let xMotionEffectType: UIInterpolatingMotionEffect.EffectType = orientation.isPortrait ? .tiltAlongHorizontalAxis : .tiltAlongVerticalAxis - let yMotionEffectType: UIInterpolatingMotionEffect.EffectType = orientation.isPortrait ? .tiltAlongVerticalAxis : .tiltAlongHorizontalAxis - updateMotionEffect(forXMotionEffectType: xMotionEffectType, yMotionEffectType: yMotionEffectType) - } - #endif - - private func updateMotionEffect(forXMotionEffectType xMotionEffectType: UIInterpolatingMotionEffect.EffectType, yMotionEffectType: UIInterpolatingMotionEffect.EffectType) { - let effectX = UIInterpolatingMotionEffect(keyPath: "center.x", type: xMotionEffectType) - effectX.minimumRelativeValue = -IHProgressHUDParallaxDepthPoints - effectX.maximumRelativeValue = IHProgressHUDParallaxDepthPoints - - let effectY = UIInterpolatingMotionEffect(keyPath: "center.y", type: yMotionEffectType) - effectY.minimumRelativeValue = -IHProgressHUDParallaxDepthPoints - effectY.maximumRelativeValue = IHProgressHUDParallaxDepthPoints - - let effectGroup = UIMotionEffectGroup() - effectGroup.motionEffects = [effectX, effectY] - - // Clear old motion effect, then add new motion effects - getHudView().motionEffects = [] - getHudView().addMotionEffect(effectGroup) - } - - private func move(to newCenter: CGPoint, rotateAngle angle: CGFloat) { - getHudView().transform = CGAffineTransform(rotationAngle: angle) - guard let container = containerView else { - getHudView().center = CGPoint(x: newCenter.x + offsetFromCenter.horizontal, y: newCenter.y + offsetFromCenter.vertical) - return - } - getHudView().center = CGPoint(x: container.center.x + offsetFromCenter.horizontal, y: container.center.y + offsetFromCenter.vertical) - } -} - -extension IHProgressHUD { - - public class func set(defaultStyle style: IHProgressHUDStyle) { - sharedView.defaultStyle = style - } - - public class func setHUD(backgroundColor color: UIColor) { - sharedView.defaultStyle = .custom - sharedView.hudBackgroundColor = color - } - - public class func set(defaultMaskType maskType: IHProgressHUDMaskType) { - sharedView.defaultMaskType = maskType - } - - public class func set(defaultAnimationType type: IHProgressHUDAnimationType) { - sharedView.defaultAnimationType = type - } - - public class func set(status: String?) { - sharedView.setStatus(status) - } - - public class func set(containerView: UIView?) { - sharedView.containerView = containerView - } // default is window level - - public class func set(minimumSize: CGSize) { - sharedView.minimumSize = minimumSize - } - - // default is CGSizeZero, can be used to avoid resizing for a larger message - - public class func set(ringThickness: CGFloat) { - sharedView.ringThickness = ringThickness - } // default is 2 pt - - public class func set(ringRadius : CGFloat) { - sharedView.ringRadius = ringRadius - }// default is 18 pt - - public class func setRing(noTextRingRadius radius: CGFloat) { - sharedView.ringNoTextRadius = radius - } // default is 24 pt - - public class func set(cornerRadius: CGFloat) { - sharedView.cornerRadius = cornerRadius - }// default is 14 pt - - public class func set(borderColor color : UIColor) { - sharedView.getHudView().layer.borderColor = color.cgColor - - }// default is nil - - public class func set(borderWidth width: CGFloat) { - sharedView.getHudView().layer.borderWidth = width - }// default is 0 - - public class func set(font: UIFont) { - sharedView.font = font - } // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] - - public class func set(foregroundColor color: UIColor) { - sharedView.foregroundColor = color - // sharedView.defaultStyle = .custom - } - // default is [UIColor blackColor], only used for ProgressHUDStyleCustom - - public class func set(backgroundColor color: UIColor) { - sharedView.backgroundColor = color - sharedView.defaultStyle = .custom - } // default is [UIColor whiteColor], only used for ProgressHUDStyleCustom - - public class func set(backgroundLayerColor color: UIColor) { - sharedView.backgroundLayerColor = color - } // default is [UIColor colorWithWhite:0 alpha:0.5], only used for ProgressHUDMaskTypeCustom - - public class func set(imageViewSize size: CGSize) { - sharedView.imageViewSize = size - } // default is 28x28 pt - - public class func set(shouldTintImages: Bool) { - sharedView.shouldTintImages = shouldTintImages - } // default is YES - - public class func set(infoImage image: UIImage) { - sharedView.infoImage = image - } // default is the bundled info image provided by Freepik - - public class func setSuccessImage(successImage image: UIImage) { - sharedView.successImage = image - } // default is the bundled success image provided by Freepik - - public class func setErrorImage(errorImage image: UIImage) { - sharedView.errorImage = image - } // default is the bundled error image provided by Freepik - - public class func set(viewForExtension view: UIView) { - IHProgressHUD.isNotAppExtension = false - sharedView.viewForExtension = view - }// default is nil, only used if #define SV_APP_EXTENSIONS is set - - public class func set(graceTimeInterval interval: TimeInterval) { - sharedView.graceTimeInterval = interval - } // default is 0 seconds - - public class func set(minimumDismiss interval: TimeInterval) { - sharedView.minimumDismissTimeInterval = interval - } // default is 5.0 seconds - - public class func set(maximumDismissTimeInterval interval: TimeInterval) { - sharedView.maximumDismissTimeInterval = interval - } // default is infinite - - public class func setFadeInAnimationDuration(fadeInAnimationDuration duration: TimeInterval) { - sharedView.fadeInAnimationDuration = duration - } // default is 0.15 seconds - - public class func setFadeOutAnimationDuration(fadeOutAnimationDuration duration: TimeInterval) { - sharedView.fadeOutAnimationDuration = duration - } // default is 0.15 seconds - - public class func setMaxSupportedWindowLevel(maxSupportedWindowLevel windowLevel: UIWindow.Level) { - sharedView.maxSupportedWindowLevel = windowLevel - } // default is UIWindowLevelNormal - - public class func setHapticsEnabled(hapticsEnabled: Bool) { - sharedView.hapticsEnabled = hapticsEnabled - } // default is NO - - - // MARK: - Show Methods - public class func show() { - show(withStatus: nil) - } - - public class func show(withStatus status: String?) { - show(progress: IHProgressHUDUndefinedProgress, status: status) - } - - public class func show(progress: CGFloat) { - show(progress: progress, status: nil) - } - - public class func show(progress: CGFloat, status: String?) { - sharedView.showProgress(progress: Float(progress), status: status) - } - - public class func setOffsetFromCenter(_ offset: UIOffset) { - sharedView.offsetFromCenter = offset - } - - public class func resetOffsetFromCenter() { - setOffsetFromCenter(.zero) - } - - public class func popActivity() { - if sharedView.activityCount > 0 { - sharedView.activityCount -= 1 - } - if sharedView.activityCount == 0 { - sharedView.dismiss() - } - } // decrease activity count, if activity count == 0 the HUD is dismissed - - public class func dismiss() { - dismissWithDelay(0.0) - } - - public class func dismissWithCompletion(_ completion: (() -> Void)?) { - dismissWithDelay(0.0, completion: completion) - } - - public class func dismissWithDelay(_ delay: TimeInterval) { - dismissWithDelay(delay, completion: nil) - } - - public class func dismissWithDelay(_ delay: TimeInterval, completion: (() -> Void)?) { - sharedView.dismissWithDelay(delay, completion: completion) - } - - public class func isVisible() -> Bool { - return sharedView.getBackGroundView().alpha > 0.0 - } - - public class func displayDurationForString(_ string:String?) -> TimeInterval { - let minimum = max(CGFloat(string?.count ?? 0) * 0.06 + 0.5, CGFloat(sharedView.minimumDismissTimeInterval)) - return TimeInterval(min(minimum, CGFloat(sharedView.maximumDismissTimeInterval))) - } - - public class func showInfowithStatus(_ status: String?) { - showImage(sharedView.infoImage, status: status) - #if os(iOS) - if #available(iOS 10.0, *) { - sharedView.hapticGenerator?.notificationOccurred(.warning) - } - #endif - } - - public class func showImage(_ image: UIImage, status: String?) { - let displayInterval = displayDurationForString(status) - sharedView.show(image: image, status: status, duration: displayInterval) - } - - public class func showSuccesswithStatus(_ status: String?) { - showImage(sharedView.successImage, status: status) - #if os(iOS) - if #available(iOS 10.0, *) { - sharedView.hapticGenerator?.notificationOccurred(.success) - } - #endif - } - - public class func showError(withStatus status: String?) { - showImage(sharedView.errorImage, status: status) - #if os(iOS) - if #available(iOS 10.0, *) { - sharedView.hapticGenerator?.notificationOccurred(.error) - } - #endif - } -} -//MARK: - -extension IHProgressHUD { - private func setGrace(timer: Timer?) { - if (graceTimer != nil) { - graceTimer?.invalidate() - graceTimer = nil - } else { - if timer != nil { - graceTimer = timer - } - } - } - - private func setFadeOut(timer: Timer?) { - if (fadeOutTimer != nil) { - fadeOutTimer?.invalidate() - fadeOutTimer = nil - } - if timer != nil { - fadeOutTimer = timer - } - } -} - -//MARK: - Instance Getter Methods -extension IHProgressHUD { - private func foreGroundColorForStyle() -> UIColor { - guard let color = foregroundColor else { - if defaultStyle == .light { - return .black - } else if defaultStyle == .dark { - return .white - } else { - return .black - } - } - return color - } - - private func getHudView() -> UIVisualEffectView { - if hudView == nil { - let tmphudView = UIVisualEffectView() - tmphudView.layer.masksToBounds = true - tmphudView.autoresizingMask = [.flexibleBottomMargin, .flexibleTopMargin, .flexibleRightMargin, .flexibleLeftMargin] - hudView = tmphudView - hudView?.accessibilityLabel = "HUD View" - } - - if hudView?.superview == nil { - self.addSubview(hudView!) - } - - hudView?.layer.cornerRadius = cornerRadius - return hudView! - } - - private func getBackGroundView() -> UIView { - if backgroundView == nil { - backgroundView = UIView() - backgroundView?.autoresizingMask = [.flexibleWidth, .flexibleHeight] - } - if backgroundView?.superview == nil { - insertSubview(self.backgroundView!, belowSubview: getHudView()) - } - // Update styling - if defaultMaskType == .gradient { - if (backgroundRadialGradientLayer == nil) { - backgroundRadialGradientLayer = RadialGradientLayer() - } - if (backgroundRadialGradientLayer?.superlayer == nil) { - backgroundView!.layer.insertSublayer(backgroundRadialGradientLayer!, at: 0) - } - } else { - if ((backgroundRadialGradientLayer != nil) && (backgroundRadialGradientLayer?.superlayer != nil)) { - backgroundRadialGradientLayer?.removeFromSuperlayer() - } - if defaultMaskType == .black { - backgroundView?.backgroundColor = UIColor(white: 0, alpha: 0.4) - } else if defaultMaskType == .custom { - backgroundView?.backgroundColor = backgroundLayerColor - } else { - backgroundView?.backgroundColor = UIColor.clear - } - } - - // Update frame - if backgroundView != nil { - backgroundView?.frame = bounds - } - if backgroundRadialGradientLayer != nil { - backgroundRadialGradientLayer?.frame = bounds - - // Calculate the new center of the gradient, it may change if keyboard is visible - var gradientCenter: CGPoint = center - gradientCenter.y = (bounds.size.height - visibleKeyboardHeight) / 2 - backgroundRadialGradientLayer?.gradientCenter = gradientCenter - backgroundRadialGradientLayer?.setNeedsDisplay() - } - return backgroundView! - } - - private func getControlView() -> UIControl { - if controlView == nil { - controlView = UIControl.init() - controlView?.autoresizingMask = [.flexibleWidth, .flexibleHeight] - controlView?.backgroundColor = .clear - controlView?.isUserInteractionEnabled = true - controlView?.addTarget(self, action: #selector(controlViewDidReceiveTouchEvent(_:for:)), for: .touchDown) - } - if IHProgressHUD.isNotAppExtension { - if let windowBounds : CGRect = UIApplication.shared.delegate?.window??.bounds { - controlView?.frame = windowBounds - } - } - else { - controlView?.frame = UIScreen.main.bounds - } - return controlView! - } - - private func loadImageBundle(named imageName:String) -> UIImage? { - var imageBundle = Bundle.init(for: IHProgressHUD.self) - if let resourcePath = imageBundle.path(forResource: "IHProgressHUD", ofType: "bundle") { - if let resourcesBundle = Bundle(path: resourcePath) { - imageBundle = resourcesBundle - } - } - - return (UIImage(named: imageName, in: imageBundle, compatibleWith: nil)) - } -} diff --git a/AutoCat/ThirdParty/IHProgressHUD/IndefiniteAnimatedView.swift b/AutoCat/ThirdParty/IHProgressHUD/IndefiniteAnimatedView.swift deleted file mode 100755 index 0911028..0000000 --- a/AutoCat/ThirdParty/IHProgressHUD/IndefiniteAnimatedView.swift +++ /dev/null @@ -1,197 +0,0 @@ -// -// Converted to Swift 4 by Swiftify v4.2.29618 - https://objectivec2swift.com/ -// -// IndefiniteAnimatedView.swift -// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD -// -// Original Copyright (c) 2014-2018 Guillaume Campagna. All rights reserved. -// Modified Copyright © 2018 Ibrahim Hassan. All rights reserved. -// - -import UIKit - -class IndefiniteAnimatedView : UIView { - - private var activityIndicator : UIActivityIndicatorView? - private var strokeThickness : CGFloat? - private var strokeColor : UIColor? - private var indefinteAnimatedLayer : CAShapeLayer? - private var radius : CGFloat? - - override init(frame: CGRect) { - super.init(frame: frame) - if self.superview != nil { - layoutAnimatedLayer() - } - } - - required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} - -//MARK: - Setter Functions -extension IndefiniteAnimatedView { - - func setIndefinite(radius: CGFloat) { - if (self.radius != radius) { - self.radius = radius - - self.getIndefinteAnimatedLayer().removeFromSuperlayer() - self.indefinteAnimatedLayer = nil - - if superview != nil { - layoutAnimatedLayer() - } - } - } - - func setIndefinite(strokeThickness : CGFloat) { - self.strokeThickness = strokeThickness - if let strkthickness = self.strokeThickness { - getIndefinteAnimatedLayer().lineWidth = strkthickness - } - } - - func setIndefinite(strokeColor: UIColor) { - self.strokeColor = strokeColor - getIndefinteAnimatedLayer().strokeColor = strokeColor.cgColor - } - -} - -//MARK: - Getter Functions -extension IndefiniteAnimatedView { - private func getIndefinteAnimatedLayer() -> CAShapeLayer { - if self.indefinteAnimatedLayer != nil { - return self.indefinteAnimatedLayer! - } else { - let localRingRadius : CGFloat = radius ?? 18 - let localStrokeThickness : CGFloat = strokeThickness ?? 2 - let localStrokeColor : UIColor = strokeColor ?? UIColor.black - - let arcCenter = CGPoint(x: localRingRadius + localStrokeThickness / 2 + 5, y: localRingRadius + localStrokeThickness / 2 + 5) - let smoothedPath = UIBezierPath(arcCenter: arcCenter, radius: localRingRadius, startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi + CGFloat.pi / 2, clockwise: true) - - indefinteAnimatedLayer = CAShapeLayer() - indefinteAnimatedLayer?.contentsScale = UIScreen.main.scale - indefinteAnimatedLayer?.frame = CGRect.init(x: 0, y: 0, width: arcCenter.x * 2, height: arcCenter.y * 2) - indefinteAnimatedLayer?.fillColor = UIColor.clear.cgColor - indefinteAnimatedLayer?.strokeColor = localStrokeColor.cgColor - indefinteAnimatedLayer?.lineWidth = localStrokeThickness - indefinteAnimatedLayer?.lineCap = CAShapeLayerLineCap.round - indefinteAnimatedLayer?.lineJoin = CAShapeLayerLineJoin.bevel - indefinteAnimatedLayer?.path = smoothedPath.cgPath - - let maskLayer = CALayer() - let image = loadImageBundle(named: "angle-mask")! - maskLayer.contents = image.cgImage - maskLayer.frame = indefinteAnimatedLayer!.bounds - indefinteAnimatedLayer?.mask = maskLayer - - let animationDuration = TimeInterval.init(1) - let linearCurve = CAMediaTimingFunction.init(name: .linear) - let animation = CABasicAnimation.init(keyPath: "transform.rotation") - animation.fromValue = 0 - animation.toValue = CGFloat.pi * 2 - animation.duration = animationDuration - animation.timingFunction = linearCurve - animation.isRemovedOnCompletion = false - animation.repeatCount = .infinity - animation.fillMode = .forwards - animation.autoreverses = false - indefinteAnimatedLayer?.mask?.add(animation, forKey: "rotate") - - - let animationGroup = CAAnimationGroup.init() - animationGroup.duration = animationDuration - animationGroup.repeatCount = .infinity - animationGroup.isRemovedOnCompletion = false - animationGroup.timingFunction = linearCurve - - let strokeStartAnimation = CABasicAnimation.init(keyPath: "strokeStart") - strokeStartAnimation.duration = animationDuration - strokeStartAnimation.fromValue = 0.015 - strokeStartAnimation.toValue = 0.0001 - - animationGroup.animations = [strokeStartAnimation] - indefinteAnimatedLayer?.add(animationGroup, forKey: "progress") - } - return self.indefinteAnimatedLayer! - } -} - -//MARK: - ActivityIndicatorView Functions -extension IndefiniteAnimatedView { - - func removeAnimationLayer() { - for view in self.subviews { - if let activityView = view as? UIActivityIndicatorView { - activityView.removeFromSuperview() - } - } - getIndefinteAnimatedLayer().removeFromSuperlayer() - } - - func startAnimation() { - if let activityIndicator = activityIndicator { - self.addSubview(activityIndicator) - activityIndicator.frame = CGRect.init(x: 8, y: 8, width: self.frame.size.width - 16, height: self.frame.size.height - 16) - } - } - - func stopActivityIndicator() { - activityIndicator?.stopAnimating() - } - - func setActivityIndicator(color: UIColor) { - activityIndicator = UIActivityIndicatorView.init(style: UIActivityIndicatorView.Style.large) - activityIndicator?.hidesWhenStopped = true - activityIndicator?.startAnimating() - activityIndicator?.color = color - } -} -//MARK: - -extension IndefiniteAnimatedView { - override func willMove(toSuperview newSuperview: UIView?) { - if let _ = newSuperview { - layoutAnimatedLayer() - } else { - getIndefinteAnimatedLayer().removeFromSuperlayer() - indefinteAnimatedLayer = nil - } - } - - private func layoutAnimatedLayer() { - let calayer = getIndefinteAnimatedLayer() - self.layer.addSublayer(calayer) - let widthDiff: CGFloat = bounds.width - layer.bounds.width - let heightDiff: CGFloat = bounds.height - layer.bounds.height - let xPos = bounds.width - layer.bounds.width / 2 - widthDiff / 2 - let yPos = bounds.height - layer.bounds.height / 2 - heightDiff / 2 - calayer.position = CGPoint.init(x: xPos, y: yPos) - } - - override func sizeThatFits(_ size: CGSize) -> CGSize { - let localRadius : CGFloat = radius ?? 18 - let localStrokeThickness : CGFloat = strokeThickness ?? 2 - for view in self.subviews { - if let _ = view as? UIActivityIndicatorView { - return CGSize.init(width: 50, height: 50) - } - } - return CGSize.init(width: (localRadius + localStrokeThickness / 2 + 5) * 2, height: (localRadius + localStrokeThickness / 2 + 5) * 2) - } - - private func loadImageBundle(named imageName:String) -> UIImage? { - var imageBundle = Bundle.init(for: IndefiniteAnimatedView.self) - if let resourcePath = imageBundle.path(forResource: "IHProgressHUD", ofType: "bundle") { - if let resourcesBundle = Bundle(path: resourcePath) { - imageBundle = resourcesBundle - } - } - - return (UIImage(named: imageName, in: imageBundle, compatibleWith: nil)) - } -} - diff --git a/AutoCat/ThirdParty/IHProgressHUD/ProgressAnimatedView.swift b/AutoCat/ThirdParty/IHProgressHUD/ProgressAnimatedView.swift deleted file mode 100755 index 5437310..0000000 --- a/AutoCat/ThirdParty/IHProgressHUD/ProgressAnimatedView.swift +++ /dev/null @@ -1,128 +0,0 @@ -// -// Converted to Swift 4 by Swiftify v4.2.29618 - https://objectivec2swift.com/ -// -// IndefiniteAnimatedView.swift -// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD -// -// Original Copyright (c) 2014-2018 Guillaume Campagna. All rights reserved. -// Modified Copyright © 2018 Ibrahim Hassan. All rights reserved. -// - -import UIKit - -class ProgressAnimatedView: UIView { - - private var radius : CGFloat? - private var strokeThickness : CGFloat? - private var strokeColor : UIColor? - private var strokeEnd : CGFloat? - private var ringAnimatedLayer : CAShapeLayer? - - override init(frame: CGRect) { - super.init(frame: frame) - } - - required init?(coder aDecoder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func willMove(toSuperview newSuperview: UIView?) { - if let _ = newSuperview { - layoutAnimatedLayer() - } else { - getRingAnimatedLayer().removeFromSuperlayer() - ringAnimatedLayer = nil - } - } - - func layoutAnimatedLayer() { - let rlayer = getRingAnimatedLayer() - layer.addSublayer(rlayer) - let widthDiff = bounds.width - layer.bounds.width - let heightDiff = bounds.height - layer.bounds.height - let layerPositionX = bounds.width - layer.bounds.width / 2 - widthDiff / 2 - let layerPositionY = bounds.height - layer.bounds.height / 2 - heightDiff / 2 - rlayer.position = CGPoint.init(x: layerPositionX, y: layerPositionY) - } - - override func sizeThatFits(_ size: CGSize) -> CGSize { - let localRadius : CGFloat = radius ?? 18 - let localStrokeThickness : CGFloat = strokeThickness ?? 2 - return CGSize(width: (localRadius + localStrokeThickness / 2 + 5) * 2, height: (localRadius + localStrokeThickness / 2 + 5) * 2) - } - -} - -//MARK: - Setter -extension ProgressAnimatedView { - @objc public func set(radius: CGFloat) { - if radius != self.radius { - self.radius = radius - - getRingAnimatedLayer().removeFromSuperlayer() - ringAnimatedLayer = nil - - if superview != nil { - layoutAnimatedLayer() - } - } - } - - func set(strokeThickness : CGFloat) { - self.strokeThickness = strokeThickness - getRingAnimatedLayer().lineWidth = strokeThickness - - if superview != nil { - layoutAnimatedLayer() - } - - } - - func set(strokeEnd: CGFloat) { - self.strokeEnd = strokeEnd - getRingAnimatedLayer().strokeEnd = strokeEnd - - if superview != nil { - layoutAnimatedLayer() - } - - } - - func set(strokeColor: UIColor) { - - self.strokeColor = strokeColor - self.getRingAnimatedLayer().strokeColor = strokeColor.cgColor - - if superview != nil { - layoutAnimatedLayer() - } - } -} - -//MARK: - Getter -extension ProgressAnimatedView { - private func getRingAnimatedLayer() -> CAShapeLayer { - if self.ringAnimatedLayer != nil { - return self.ringAnimatedLayer! - } else { - let localStrokeThickness: CGFloat = strokeThickness ?? 2 - let localRingRadius: CGFloat = radius ?? 18 - - let arcCenter = CGPoint(x: localRingRadius + localStrokeThickness / 2 + 5, y: localRingRadius + localStrokeThickness / 2 + 5) - let smoothedPath = UIBezierPath(arcCenter: arcCenter, radius: localRingRadius, startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi + CGFloat.pi / 2, clockwise: true) - - let _ringAnimatedLayer = CAShapeLayer() - _ringAnimatedLayer.contentsScale = UIScreen.main.scale - _ringAnimatedLayer.frame = CGRect(x: 0.0, y: 0.0, width: arcCenter.x * 2, height: arcCenter.y * 2) - _ringAnimatedLayer.fillColor = UIColor.clear.cgColor - _ringAnimatedLayer.strokeColor = strokeColor?.cgColor - _ringAnimatedLayer.lineWidth = localStrokeThickness - _ringAnimatedLayer.lineCap = .round - _ringAnimatedLayer.lineJoin = .bevel - _ringAnimatedLayer.path = smoothedPath.cgPath - self.ringAnimatedLayer = _ringAnimatedLayer - } - return self.ringAnimatedLayer! - } - -} diff --git a/AutoCat/ThirdParty/IHProgressHUD/RadialGradientLayer.swift b/AutoCat/ThirdParty/IHProgressHUD/RadialGradientLayer.swift deleted file mode 100755 index 1be0c08..0000000 --- a/AutoCat/ThirdParty/IHProgressHUD/RadialGradientLayer.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// Converted to Swift 4 by Swiftify v4.2.29618 - https://objectivec2swift.com/ -// -// IndefiniteAnimatedView.swift -// SVProgressHUD, https://github.com/SVProgressHUD/SVProgressHUD -// -// Original Copyright (c) 2014-2018 Guillaume Campagna. All rights reserved. -// Modified Copyright © 2018 Ibrahim Hassan. All rights reserved. -// - -import QuartzCore - -class RadialGradientLayer: CALayer { - var gradientCenter = CGPoint.zero - override func draw(in context: CGContext) { - super.draw(in: context) - let locationsCount = 2 - let locations : [CGFloat] = [0.0, 1.0] - let colors : [CGFloat] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75] - let colorSpace = CGColorSpaceCreateDeviceRGB() - if let gradient = CGGradient.init(colorSpace: colorSpace, colorComponents: colors, locations: locations, count: locationsCount) { - let radius = min(bounds.size.width, bounds.size.height) - - context.drawRadialGradient(gradient, startCenter: gradientCenter, startRadius: 0, endCenter: gradientCenter, endRadius: radius, options: CGGradientDrawingOptions.drawsAfterEndLocation) - } - } -} diff --git a/AutoCat/ThirdParty/RxRealmDataSources/Reactive+RxRealmDataSources.swift b/AutoCat/ThirdParty/RxRealmDataSources/Reactive+RxRealmDataSources.swift deleted file mode 100644 index c51ca48..0000000 --- a/AutoCat/ThirdParty/RxRealmDataSources/Reactive+RxRealmDataSources.swift +++ /dev/null @@ -1,113 +0,0 @@ -// -// RxRealm extensions -// -// Copyright (c) 2016 RxSwiftCommunity. All rights reserved. -// Check the LICENSE file for details -// - -import Foundation - -import RealmSwift -import RxSwift -import RxCocoa -import RxRealm - -#if os(iOS) -// MARK: - iOS / UIKit - -import UIKit -extension Reactive where Base: UITableView { - - public func realmChanges(_ dataSource: RxTableViewRealmDataSource) - -> RealmBindObserver, RxTableViewRealmDataSource> { - - return RealmBindObserver(dataSource: dataSource) {ds, results, changes in - if ds.tableView == nil { - ds.tableView = self.base - } - ds.tableView?.dataSource = ds - ds.applyChanges(items: AnyRealmCollection(results), changes: changes) - } - } - - public func realmModelSelected(_ modelType: E.Type) -> ControlEvent where E: RealmSwift.Object { - - let source: Observable = self.itemSelected.flatMap { [weak view = self.base as UITableView] indexPath -> Observable in - guard let view = view, let ds = view.dataSource as? RxTableViewRealmDataSource else { - return Observable.empty() - } - - return Observable.just(ds.model(at: indexPath)) - } - - return ControlEvent(events: source) - } - -} - -extension Reactive where Base: UICollectionView { - - public func realmChanges(_ dataSource: RxCollectionViewRealmDataSource) - -> RealmBindObserver, RxCollectionViewRealmDataSource> { - - return RealmBindObserver(dataSource: dataSource) {ds, results, changes in - if ds.collectionView == nil { - ds.collectionView = self.base - } - ds.collectionView?.dataSource = ds - ds.applyChanges(items: AnyRealmCollection(results), changes: changes) - } - } - - public func realmModelSelected(_ modelType: E.Type) -> ControlEvent where E: RealmSwift.Object { - - let source: Observable = self.itemSelected.flatMap { [weak view = self.base as UICollectionView] indexPath -> Observable in - guard let view = view, let ds = view.dataSource as? RxCollectionViewRealmDataSource else { - return Observable.empty() - } - - return Observable.just(ds.model(at: indexPath)) - } - - return ControlEvent(events: source) - } -} - - -#elseif os(OSX) -// MARK: - macOS / Cocoa - -import Cocoa -extension Reactive where Base: NSTableView { - - public func realmChanges(_ dataSource: RxTableViewRealmDataSource) - -> RealmBindObserver, RxTableViewRealmDataSource> { - - base.delegate = dataSource - base.dataSource = dataSource - - return RealmBindObserver(dataSource: dataSource) {ds, results, changes in - if dataSource.tableView == nil { - dataSource.tableView = self.base - } - ds.applyChanges(items: AnyRealmCollection(results), changes: changes) - } - } -} - -extension Reactive where Base: NSCollectionView { - - public func realmChanges(_ dataSource: RxCollectionViewRealmDataSource) - -> RealmBindObserver, RxCollectionViewRealmDataSource> { - - return RealmBindObserver(dataSource: dataSource) {ds, results, changes in - if ds.collectionView == nil { - ds.collectionView = self.base - } - ds.collectionView?.dataSource = ds - ds.applyChanges(items: AnyRealmCollection(results), changes: changes) - } - } -} - -#endif diff --git a/AutoCat/ThirdParty/RxRealmDataSources/RealmBindObserver.swift b/AutoCat/ThirdParty/RxRealmDataSources/RealmBindObserver.swift deleted file mode 100644 index a60b378..0000000 --- a/AutoCat/ThirdParty/RxRealmDataSources/RealmBindObserver.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// RxRealm extensions -// -// Copyright (c) 2016 RxSwiftCommunity. All rights reserved. -// Check the LICENSE file for details -// - -import Foundation - -import RealmSwift -import RxSwift -import RxCocoa -import RxRealm - -public class RealmBindObserver: ObserverType { - typealias BindingType = (DS, C, RealmChangeset?) -> Void - public typealias E = (C, RealmChangeset?) - - let dataSource: DS - let binding: BindingType - - init(dataSource: DS, binding: @escaping BindingType) { - self.dataSource = dataSource - self.binding = binding - } - - public func on(_ event: Event) { - switch event { - case .next(let element): - binding(dataSource, element.0, element.1) - case .error: - return - case .completed: - return - } - } - - func asObserver() -> AnyObserver { - return AnyObserver(eventHandler: on) - } -} diff --git a/AutoCat/ThirdParty/RxRealmDataSources/RxCollectionViewRealmDataSource.swift b/AutoCat/ThirdParty/RxRealmDataSources/RxCollectionViewRealmDataSource.swift deleted file mode 100644 index 8883732..0000000 --- a/AutoCat/ThirdParty/RxRealmDataSources/RxCollectionViewRealmDataSource.swift +++ /dev/null @@ -1,210 +0,0 @@ -// -// RxRealm extensions -// -// Copyright (c) 2016 RxSwiftCommunity. All rights reserved. -// Check the LICENSE file for details -// - -import Foundation - -import RealmSwift -import RxSwift -import RxCocoa -import RxRealm - -#if os(iOS) - // MARK: - iOS / UIKit - - import UIKit - - public typealias CollectionCellFactory = (RxCollectionViewRealmDataSource, UICollectionView, IndexPath, E) -> UICollectionViewCell - public typealias CollectionCellConfig = (CellType, IndexPath, E) -> Void - - open class RxCollectionViewRealmDataSource : NSObject, UICollectionViewDataSource { - private var items: AnyRealmCollection? - - // MARK: - Configuration - - public var collectionView: UICollectionView? - public var animated = true - - // MARK: - Init - public let cellIdentifier: String - public let cellFactory: CollectionCellFactory - - public init(cellIdentifier: String, cellFactory: @escaping CollectionCellFactory) { - self.cellIdentifier = cellIdentifier - self.cellFactory = cellFactory - } - - public init(cellIdentifier: String, cellType: CellType.Type, cellConfig: @escaping CollectionCellConfig) where CellType: UICollectionViewCell { - self.cellIdentifier = cellIdentifier - self.cellFactory = {ds, cv, ip, model in - let cell = cv.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: ip) as! CellType - cellConfig(cell, ip, model) - return cell - } - } - - // MARK: - Data access - public func model(at indexPath: IndexPath) -> E { - return items![indexPath.row] - } - - // MARK: - UICollectionViewDataSource protocol - public func numberOfSections(in collectionView: UICollectionView) -> Int { - return 1 - } - - public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - return items?.count ?? 0 - } - - public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - return cellFactory(self, collectionView, indexPath, items![indexPath.row]) - } - - // MARK: - Applying changeset to the collection view - private let fromRow = {(row: Int) in return IndexPath(row: row, section: 0)} - - func applyChanges(items: AnyRealmCollection, changes: RealmChangeset?) { - if self.items == nil { - self.items = items - } - - guard let collectionView = collectionView else { - fatalError("You have to bind a collection view to the data source.") - } - - guard animated else { - collectionView.reloadData() - return - } - - guard let changes = changes else { - collectionView.reloadData() - return - } - - let lastItemCount = collectionView.numberOfItems(inSection: 0) - guard items.count == lastItemCount + changes.inserted.count - changes.deleted.count else { - collectionView.reloadData() - return - } - - collectionView.performBatchUpdates({[unowned self] in - collectionView.deleteItems(at: changes.deleted.map(self.fromRow)) - collectionView.reloadItems(at: changes.updated.map(self.fromRow)) - collectionView.insertItems(at: changes.inserted.map(self.fromRow)) - }, completion: nil) - } -} - -#elseif os(OSX) -// MARK: - macOS / Cocoa - -import Cocoa - - public typealias CollectionItemFactory = (RxCollectionViewRealmDataSource, NSCollectionView, IndexPath, E) -> NSCollectionViewItem - public typealias CollectionItemConfig = (ItemType, IndexPath, E) -> Void - - open class RxCollectionViewRealmDataSource : NSObject, NSCollectionViewDataSource { - - private var items: AnyRealmCollection? - - // MARK: - Configuration - - public var collectionView: NSCollectionView? - public var animated = true - - // MARK: - Init - public let itemIdentifier: String - public let itemFactory: CollectionItemFactory - - public weak var delegate: NSCollectionViewDelegate? - public weak var dataSource: NSCollectionViewDataSource? - - public init(itemIdentifier: String, itemFactory: @escaping CollectionItemFactory) { - self.itemIdentifier = itemIdentifier - self.itemFactory = itemFactory - } - - public init(itemIdentifier: String, itemType: ItemType.Type, itemConfig: @escaping CollectionItemConfig) where ItemType: NSCollectionViewItem { - self.itemIdentifier = itemIdentifier - self.itemFactory = { ds, cv, ip, model in - let item = cv.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: itemIdentifier), for: ip) as! ItemType - itemConfig(item, ip, model) - return item - } - } - - // MARK: - NSCollectionViewDataSource protocol - public func numberOfSections(in collectionView: NSCollectionView) -> Int { - return 1 - } - - public func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int { - return items?.count ?? 0 - } - - @available(OSX 10.11, *) - public func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem { - return itemFactory(self, collectionView, indexPath, items![indexPath.item]) - } - - // MARK: - Proxy unimplemented data source and delegate methods - open override func responds(to aSelector: Selector!) -> Bool { - if RxCollectionViewRealmDataSource.instancesRespond(to: aSelector) { - return true - } else if let delegate = delegate { - return delegate.responds(to: aSelector) - } else if let dataSource = dataSource { - return dataSource.responds(to: aSelector) - } else { - return false - } - } - - open override func forwardingTarget(for aSelector: Selector!) -> Any? { - return delegate ?? dataSource - } - - // MARK: - Applying changeset to the collection view - private let fromRow = {(row: Int) in return IndexPath(item: row, section: 0)} - - func applyChanges(items: AnyRealmCollection, changes: RealmChangeset?) { - if self.items == nil { - self.items = items - } - - guard let collectionView = collectionView else { - fatalError("You have to bind a collection view to the data source.") - } - - guard animated else { - collectionView.reloadData() - return - } - - guard let changes = changes else { - collectionView.reloadData() - return - } - - let lastItemCount = collectionView.numberOfItems(inSection: 0) - guard items.count == lastItemCount + changes.inserted.count - changes.deleted.count else { - collectionView.reloadData() - return - } - - collectionView.performBatchUpdates({[unowned self] in - //TODO: this should be animated, but doesn't seem to be? - collectionView.animator().deleteItems(at: Set(changes.deleted.map(self.fromRow))) - collectionView.animator().reloadItems(at: Set(changes.updated.map(self.fromRow))) - collectionView.animator().insertItems(at: Set(changes.inserted.map(self.fromRow))) - }, completionHandler: nil) - } - } - - -#endif diff --git a/AutoCat/ThirdParty/RxRealmDataSources/RxTableViewRealmDataSource.swift b/AutoCat/ThirdParty/RxRealmDataSources/RxTableViewRealmDataSource.swift deleted file mode 100644 index c80bb80..0000000 --- a/AutoCat/ThirdParty/RxRealmDataSources/RxTableViewRealmDataSource.swift +++ /dev/null @@ -1,223 +0,0 @@ -// -// RxRealm extensions -// -// Copyright (c) 2016 RxSwiftCommunity. All rights reserved. -// Check the LICENSE file for details -// - -import Foundation - -import RealmSwift -import RxSwift -import RxCocoa -import RxRealm - -#if os(iOS) - // MARK: - iOS / UIKit - - import UIKit - - public typealias TableCellFactory = (RxTableViewRealmDataSource, UITableView, IndexPath, E) -> UITableViewCell - public typealias TableCellConfig = (CellType, IndexPath, E) -> Void - - open class RxTableViewRealmDataSource: NSObject, UITableViewDataSource { - - private var items: AnyRealmCollection? - - // MARK: - Configuration - - public var tableView: UITableView? - public var animated = true - public var rowAnimations = ( - insert: UITableView.RowAnimation.automatic, - update: UITableView.RowAnimation.automatic, - delete: UITableView.RowAnimation.automatic) - - public var headerTitle: String? - public var footerTitle: String? - - // MARK: - Init - public let cellIdentifier: String - public let cellFactory: TableCellFactory - - public init(cellIdentifier: String, cellFactory: @escaping TableCellFactory) { - self.cellIdentifier = cellIdentifier - self.cellFactory = cellFactory - } - - public init(cellIdentifier: String, cellType: CellType.Type, cellConfig: @escaping TableCellConfig) where CellType: UITableViewCell { - self.cellIdentifier = cellIdentifier - self.cellFactory = {ds, tv, ip, model in - let cell = tv.dequeueReusableCell(withIdentifier: cellIdentifier, for: ip) as! CellType - cellConfig(cell, ip, model) - return cell - } - } - - // MARK: - Data access - public func model(at indexPath: IndexPath) -> E { - return items![indexPath.row] - } - - // MARK: - UITableViewDataSource protocol - public func numberOfSections(in tableView: UITableView) -> Int { - return 1 - } - - public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return items?.count ?? 0 - } - - public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - return cellFactory(self, tableView, indexPath, items![indexPath.row]) - } - - public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { - return headerTitle - } - - public func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { - return footerTitle - } - - // MARK: - Applying changeset to the table view - private let fromRow = {(row: Int) in return IndexPath(row: row, section: 0)} - - func applyChanges(items: AnyRealmCollection, changes: RealmChangeset?) { - if self.items == nil { - self.items = items - } - - guard let tableView = tableView else { - fatalError("You have to bind a table view to the data source.") - } - - guard animated else { - tableView.reloadData() - return - } - - guard let changes = changes else { - tableView.reloadData() - return - } - - let lastItemCount = tableView.numberOfRows(inSection: 0) - guard items.count == lastItemCount + changes.inserted.count - changes.deleted.count else { - tableView.reloadData() - return - } - - tableView.beginUpdates() - tableView.deleteRows(at: changes.deleted.map(fromRow), with: rowAnimations.delete) - tableView.insertRows(at: changes.inserted.map(fromRow), with: rowAnimations.insert) - tableView.reloadRows(at: changes.updated.map(fromRow), with: rowAnimations.update) - tableView.endUpdates() - } - } - -#elseif os(OSX) - // MARK: - macOS / Cocoa - - import Cocoa - - public typealias TableCellFactory = (RxTableViewRealmDataSource, NSTableView, Int, E) -> NSTableCellView - public typealias TableCellConfig = (CellType, Int, E) -> Void - - open class RxTableViewRealmDataSource: NSObject, NSTableViewDataSource, NSTableViewDelegate { - - private var items: AnyRealmCollection? - - // MARK: - Configuration - - public var tableView: NSTableView? - public var animated = true - public var rowAnimations = ( - insert: NSTableView.AnimationOptions.effectFade, - update: NSTableView.AnimationOptions.effectFade, - delete: NSTableView.AnimationOptions.effectFade) - - public weak var delegate: NSTableViewDelegate? - public weak var dataSource: NSTableViewDataSource? - - // MARK: - Init - public let cellIdentifier: String - public let cellFactory: TableCellFactory - - public init(cellIdentifier: String, cellFactory: @escaping TableCellFactory) { - self.cellIdentifier = cellIdentifier - self.cellFactory = cellFactory - } - - public init(cellIdentifier: String, cellType: CellType.Type, cellConfig: @escaping TableCellConfig) where CellType: NSTableCellView { - self.cellIdentifier = cellIdentifier - self.cellFactory = { ds, tv, row, model in - let cell = tv.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: cellIdentifier), owner: tv) as! CellType - cellConfig(cell, row, model) - return cell - } - } - - // MARK: - UITableViewDataSource protocol - public func numberOfRows(in tableView: NSTableView) -> Int { - return items?.count ?? 0 - } - - public func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { - return cellFactory(self, tableView, row, items![row]) - } - - // MARK: - Proxy unimplemented data source and delegate methods - open override func responds(to aSelector: Selector!) -> Bool { - if RxTableViewRealmDataSource.instancesRespond(to: aSelector) { - return true - } else if let delegate = delegate { - return delegate.responds(to: aSelector) - } else if let dataSource = dataSource { - return dataSource.responds(to: aSelector) - } else { - return false - } - } - - open override func forwardingTarget(for aSelector: Selector!) -> Any? { - return delegate ?? dataSource - } - - // MARK: - Applying changeset to the table view - private let fromRow = {(row: Int) in return IndexPath(item: row, section: 0)} - - func applyChanges(items: AnyRealmCollection, changes: RealmChangeset?) { - if self.items == nil { - self.items = items - } - - guard let tableView = tableView else { - fatalError("You have to bind a table view to the data source.") - } - - guard animated else { - tableView.reloadData() - return - } - - guard let changes = changes else { - tableView.reloadData() - return - } - - let lastItemCount = tableView.numberOfRows - guard items.count == lastItemCount + changes.inserted.count - changes.deleted.count else { - tableView.reloadData() - return - } - - tableView.beginUpdates() - tableView.removeRows(at: IndexSet(changes.deleted), withAnimation: rowAnimations.delete) - tableView.insertRows(at: IndexSet(changes.inserted), withAnimation: rowAnimations.insert) - tableView.reloadData(forRowIndexes: IndexSet(changes.updated), columnIndexes: IndexSet([0])) - tableView.endUpdates() - } - } - -#endif