Enabled mac catalyst
@ -30,7 +30,6 @@
|
|||||||
7A11474723FF2AA500B424AF /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A11474623FF2AA500B424AF /* User.swift */; };
|
7A11474723FF2AA500B424AF /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A11474623FF2AA500B424AF /* User.swift */; };
|
||||||
7A11474923FF2B2D00B424AF /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A11474823FF2B2D00B424AF /* Response.swift */; };
|
7A11474923FF2B2D00B424AF /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A11474823FF2B2D00B424AF /* Response.swift */; };
|
||||||
7A11474B23FF368B00B424AF /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A11474A23FF368B00B424AF /* Settings.swift */; };
|
7A11474B23FF368B00B424AF /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A11474A23FF368B00B424AF /* Settings.swift */; };
|
||||||
7A11474E23FFEE8800B424AF /* SVProgressHUD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A11474D23FFEE8800B424AF /* SVProgressHUD.framework */; };
|
|
||||||
7A3F07AB24360DC800E59687 /* Dated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AA24360DC800E59687 /* Dated.swift */; };
|
7A3F07AB24360DC800E59687 /* Dated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AA24360DC800E59687 /* Dated.swift */; };
|
||||||
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AC2436350B00E59687 /* SearchController.swift */; };
|
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AC2436350B00E59687 /* SearchController.swift */; };
|
||||||
7A3F07AF24366DF900E59687 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AE24366DF900E59687 /* Filter.swift */; };
|
7A3F07AF24366DF900E59687 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AE24366DF900E59687 /* Filter.swift */; };
|
||||||
@ -39,6 +38,16 @@
|
|||||||
7A530B7E24017FEE00CBFE6E /* VehicleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */; };
|
7A530B7E24017FEE00CBFE6E /* VehicleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */; };
|
||||||
7A530B802401803A00CBFE6E /* Vehicle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7F2401803A00CBFE6E /* Vehicle.swift */; };
|
7A530B802401803A00CBFE6E /* Vehicle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7F2401803A00CBFE6E /* Vehicle.swift */; };
|
||||||
7A530B8B240181F500CBFE6E /* RxRealm in Frameworks */ = {isa = PBXBuildFile; productRef = 7A530B8A240181F500CBFE6E /* RxRealm */; };
|
7A530B8B240181F500CBFE6E /* RxRealm in Frameworks */ = {isa = PBXBuildFile; productRef = 7A530B8A240181F500CBFE6E /* RxRealm */; };
|
||||||
|
7A64AE732469DFB600ABE48E /* DismissAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A64AE6F2469DFB600ABE48E /* DismissAnimationController.swift */; };
|
||||||
|
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 */; };
|
||||||
7A6DD903242BF4A5009DE740 /* PlateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6DD902242BF4A5009DE740 /* PlateView.swift */; };
|
7A6DD903242BF4A5009DE740 /* PlateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6DD902242BF4A5009DE740 /* PlateView.swift */; };
|
||||||
7A6DD90824329144009DE740 /* CenterTextLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6DD90724329144009DE740 /* CenterTextLayer.swift */; };
|
7A6DD90824329144009DE740 /* CenterTextLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6DD90724329144009DE740 /* CenterTextLayer.swift */; };
|
||||||
7A6DD90A24329541009DE740 /* RoadNumbers2.0.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7A6DD90924329541009DE740 /* RoadNumbers2.0.otf */; };
|
7A6DD90A24329541009DE740 /* RoadNumbers2.0.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7A6DD90924329541009DE740 /* RoadNumbers2.0.otf */; };
|
||||||
@ -47,7 +56,6 @@
|
|||||||
7A7547DD2403180A004E8406 /* SectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7547DB2403180A004E8406 /* SectionHeader.swift */; };
|
7A7547DD2403180A004E8406 /* SectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7547DB2403180A004E8406 /* SectionHeader.swift */; };
|
||||||
7A7547DE2403180A004E8406 /* SectionHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7A7547DC2403180A004E8406 /* SectionHeader.xib */; };
|
7A7547DE2403180A004E8406 /* SectionHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7A7547DC2403180A004E8406 /* SectionHeader.xib */; };
|
||||||
7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7547DF24032CB6004E8406 /* VehiclePhotoCell.swift */; };
|
7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7547DF24032CB6004E8406 /* VehiclePhotoCell.swift */; };
|
||||||
7A92D0AC240425B200EF3B77 /* ATGMediaBrowser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A92D0AB240425B100EF3B77 /* ATGMediaBrowser.framework */; };
|
|
||||||
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB67E8B2435C38700258F61 /* CustomTextField.swift */; };
|
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB67E8B2435C38700258F61 /* CustomTextField.swift */; };
|
||||||
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB67E8D2435D1A000258F61 /* CustomButton.swift */; };
|
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB67E8D2435D1A000258F61 /* CustomButton.swift */; };
|
||||||
7AEFE728240455E200910EB7 /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AEFE727240455E200910EB7 /* SettingsController.swift */; };
|
7AEFE728240455E200910EB7 /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AEFE727240455E200910EB7 /* SettingsController.swift */; };
|
||||||
@ -80,6 +88,17 @@
|
|||||||
7A530B7924001D3300CBFE6E /* CheckController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckController.swift; sourceTree = "<group>"; };
|
7A530B7924001D3300CBFE6E /* CheckController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckController.swift; sourceTree = "<group>"; };
|
||||||
7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleCell.swift; sourceTree = "<group>"; };
|
7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleCell.swift; sourceTree = "<group>"; };
|
||||||
7A530B7F2401803A00CBFE6E /* Vehicle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Vehicle.swift; sourceTree = "<group>"; };
|
7A530B7F2401803A00CBFE6E /* Vehicle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Vehicle.swift; sourceTree = "<group>"; };
|
||||||
|
7A64AE6B2469DC6900ABE48E /* AutoCat.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AutoCat.entitlements; sourceTree = "<group>"; };
|
||||||
|
7A64AE6F2469DFB600ABE48E /* DismissAnimationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DismissAnimationController.swift; sourceTree = "<group>"; };
|
||||||
|
7A64AE702469DFB600ABE48E /* MediaContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaContentView.swift; sourceTree = "<group>"; };
|
||||||
|
7A64AE712469DFB600ABE48E /* MediaBrowserViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaBrowserViewController.swift; sourceTree = "<group>"; };
|
||||||
|
7A64AE722469DFB600ABE48E /* ContentTransformers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentTransformers.swift; sourceTree = "<group>"; };
|
||||||
|
7A64AE782469E16100ABE48E /* RadialGradientLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadialGradientLayer.swift; sourceTree = "<group>"; };
|
||||||
|
7A64AE792469E16100ABE48E /* IndefiniteAnimatedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IndefiniteAnimatedView.swift; sourceTree = "<group>"; };
|
||||||
|
7A64AE7A2469E16100ABE48E /* .gitkeep */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitkeep; sourceTree = "<group>"; };
|
||||||
|
7A64AE7B2469E16100ABE48E /* ProgressAnimatedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProgressAnimatedView.swift; sourceTree = "<group>"; };
|
||||||
|
7A64AE7C2469E16100ABE48E /* IHProgressHUD.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IHProgressHUD.swift; sourceTree = "<group>"; };
|
||||||
|
7A64AE7D2469E16100ABE48E /* IHProgressHUD.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = IHProgressHUD.bundle; sourceTree = "<group>"; };
|
||||||
7A6DD902242BF4A5009DE740 /* PlateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlateView.swift; sourceTree = "<group>"; };
|
7A6DD902242BF4A5009DE740 /* PlateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlateView.swift; sourceTree = "<group>"; };
|
||||||
7A6DD90724329144009DE740 /* CenterTextLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CenterTextLayer.swift; sourceTree = "<group>"; };
|
7A6DD90724329144009DE740 /* CenterTextLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CenterTextLayer.swift; sourceTree = "<group>"; };
|
||||||
7A6DD90924329541009DE740 /* RoadNumbers2.0.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = RoadNumbers2.0.otf; sourceTree = "<group>"; };
|
7A6DD90924329541009DE740 /* RoadNumbers2.0.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = RoadNumbers2.0.otf; sourceTree = "<group>"; };
|
||||||
@ -105,7 +124,6 @@
|
|||||||
7A0516162414EC1200FC55AC /* Differentiator in Frameworks */,
|
7A0516162414EC1200FC55AC /* Differentiator in Frameworks */,
|
||||||
7A11472823FEA1F400B424AF /* RealmSwift in Frameworks */,
|
7A11472823FEA1F400B424AF /* RealmSwift in Frameworks */,
|
||||||
7A11472123FEA18700B424AF /* RxCocoa in Frameworks */,
|
7A11472123FEA18700B424AF /* RxCocoa in Frameworks */,
|
||||||
7A11474E23FFEE8800B424AF /* SVProgressHUD.framework in Frameworks */,
|
|
||||||
7A0516182414EC1200FC55AC /* RxDataSources in Frameworks */,
|
7A0516182414EC1200FC55AC /* RxDataSources in Frameworks */,
|
||||||
7A051611241412CA00FC55AC /* SwiftDate in Frameworks */,
|
7A051611241412CA00FC55AC /* SwiftDate in Frameworks */,
|
||||||
7A11472323FEA18700B424AF /* RxBlocking in Frameworks */,
|
7A11472323FEA18700B424AF /* RxBlocking in Frameworks */,
|
||||||
@ -113,7 +131,6 @@
|
|||||||
7A11472B23FEA24D00B424AF /* Action in Frameworks */,
|
7A11472B23FEA24D00B424AF /* Action in Frameworks */,
|
||||||
7A11471F23FEA18700B424AF /* RxRelay in Frameworks */,
|
7A11471F23FEA18700B424AF /* RxRelay in Frameworks */,
|
||||||
7AF58D2F24029C5200CE01A0 /* MagazineLayout in Frameworks */,
|
7AF58D2F24029C5200CE01A0 /* MagazineLayout in Frameworks */,
|
||||||
7A92D0AC240425B200EF3B77 /* ATGMediaBrowser.framework in Frameworks */,
|
|
||||||
7A530B78240010D900CBFE6E /* InputMask in Frameworks */,
|
7A530B78240010D900CBFE6E /* InputMask in Frameworks */,
|
||||||
7A11471D23FEA18700B424AF /* RxSwift in Frameworks */,
|
7A11471D23FEA18700B424AF /* RxSwift in Frameworks */,
|
||||||
7A11472623FEA1F400B424AF /* Realm in Frameworks */,
|
7A11472623FEA1F400B424AF /* Realm in Frameworks */,
|
||||||
@ -143,6 +160,7 @@
|
|||||||
7A1146FF23FDE7E500B424AF /* AutoCat */ = {
|
7A1146FF23FDE7E500B424AF /* AutoCat */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
7A64AE6B2469DC6900ABE48E /* AutoCat.entitlements */,
|
||||||
7A3F07A924360D9100E59687 /* Extensions */,
|
7A3F07A924360D9100E59687 /* Extensions */,
|
||||||
7A6DD90424326788009DE740 /* Fonts */,
|
7A6DD90424326788009DE740 /* Fonts */,
|
||||||
7A6DD901242BF48D009DE740 /* Views */,
|
7A6DD901242BF48D009DE740 /* Views */,
|
||||||
@ -177,6 +195,8 @@
|
|||||||
7A11472C23FECA3E00B424AF /* ThirdParty */ = {
|
7A11472C23FECA3E00B424AF /* ThirdParty */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
7A64AE772469E16100ABE48E /* IHProgressHUD */,
|
||||||
|
7A64AE6E2469DFB600ABE48E /* ATGMediaBrowser */,
|
||||||
7A6DD90724329144009DE740 /* CenterTextLayer.swift */,
|
7A6DD90724329144009DE740 /* CenterTextLayer.swift */,
|
||||||
);
|
);
|
||||||
path = ThirdParty;
|
path = ThirdParty;
|
||||||
@ -234,6 +254,30 @@
|
|||||||
path = Cells;
|
path = Cells;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
7A64AE6E2469DFB600ABE48E /* ATGMediaBrowser */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7A64AE6F2469DFB600ABE48E /* DismissAnimationController.swift */,
|
||||||
|
7A64AE702469DFB600ABE48E /* MediaContentView.swift */,
|
||||||
|
7A64AE712469DFB600ABE48E /* MediaBrowserViewController.swift */,
|
||||||
|
7A64AE722469DFB600ABE48E /* ContentTransformers.swift */,
|
||||||
|
);
|
||||||
|
path = ATGMediaBrowser;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
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 = "<group>";
|
||||||
|
};
|
||||||
7A6DD901242BF48D009DE740 /* Views */ = {
|
7A6DD901242BF48D009DE740 /* Views */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -263,7 +307,6 @@
|
|||||||
7A1146F923FDE7E500B424AF /* Sources */,
|
7A1146F923FDE7E500B424AF /* Sources */,
|
||||||
7A1146FA23FDE7E500B424AF /* Frameworks */,
|
7A1146FA23FDE7E500B424AF /* Frameworks */,
|
||||||
7A1146FB23FDE7E500B424AF /* Resources */,
|
7A1146FB23FDE7E500B424AF /* Resources */,
|
||||||
7A11475123FFF02E00B424AF /* ShellScript */,
|
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@ -342,41 +385,22 @@
|
|||||||
7A7547DE2403180A004E8406 /* SectionHeader.xib in Resources */,
|
7A7547DE2403180A004E8406 /* SectionHeader.xib in Resources */,
|
||||||
7A11470D23FDE7E600B424AF /* LaunchScreen.storyboard in Resources */,
|
7A11470D23FDE7E600B424AF /* LaunchScreen.storyboard in Resources */,
|
||||||
7A6DD90A24329541009DE740 /* RoadNumbers2.0.otf in Resources */,
|
7A6DD90A24329541009DE740 /* RoadNumbers2.0.otf in Resources */,
|
||||||
|
7A64AE802469E16100ABE48E /* .gitkeep in Resources */,
|
||||||
7A11470A23FDE7E600B424AF /* Assets.xcassets in Resources */,
|
7A11470A23FDE7E600B424AF /* Assets.xcassets in Resources */,
|
||||||
7A11470823FDE7E500B424AF /* Main.storyboard in Resources */,
|
7A11470823FDE7E500B424AF /* Main.storyboard in Resources */,
|
||||||
|
7A64AE832469E16100ABE48E /* IHProgressHUD.bundle in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
|
||||||
7A11475123FFF02E00B424AF /* ShellScript */ = {
|
|
||||||
isa = PBXShellScriptBuildPhase;
|
|
||||||
buildActionMask = 2147483647;
|
|
||||||
files = (
|
|
||||||
);
|
|
||||||
inputFileListPaths = (
|
|
||||||
"$(SRCROOT)/input.xcfilelist",
|
|
||||||
);
|
|
||||||
inputPaths = (
|
|
||||||
);
|
|
||||||
outputFileListPaths = (
|
|
||||||
"$(SRCROOT)/output.xcfilelist",
|
|
||||||
);
|
|
||||||
outputPaths = (
|
|
||||||
);
|
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
|
||||||
shellPath = /bin/sh;
|
|
||||||
shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n/usr/local/bin/carthage copy-frameworks\n";
|
|
||||||
};
|
|
||||||
/* End PBXShellScriptBuildPhase section */
|
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
7A1146F923FDE7E500B424AF /* Sources */ = {
|
7A1146F923FDE7E500B424AF /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
7A530B802401803A00CBFE6E /* Vehicle.swift in Sources */,
|
7A530B802401803A00CBFE6E /* Vehicle.swift in Sources */,
|
||||||
|
7A64AE822469E16100ABE48E /* IHProgressHUD.swift in Sources */,
|
||||||
7A11470123FDE7E500B424AF /* AppDelegate.swift in Sources */,
|
7A11470123FDE7E500B424AF /* AppDelegate.swift in Sources */,
|
||||||
7A6DD90824329144009DE740 /* CenterTextLayer.swift in Sources */,
|
7A6DD90824329144009DE740 /* CenterTextLayer.swift in Sources */,
|
||||||
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */,
|
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */,
|
||||||
@ -386,9 +410,13 @@
|
|||||||
7AEFE728240455E200910EB7 /* SettingsController.swift in Sources */,
|
7AEFE728240455E200910EB7 /* SettingsController.swift in Sources */,
|
||||||
7A3F07AB24360DC800E59687 /* Dated.swift in Sources */,
|
7A3F07AB24360DC800E59687 /* Dated.swift in Sources */,
|
||||||
7A11474923FF2B2D00B424AF /* Response.swift in Sources */,
|
7A11474923FF2B2D00B424AF /* Response.swift in Sources */,
|
||||||
|
7A64AE762469DFB600ABE48E /* ContentTransformers.swift in Sources */,
|
||||||
7A11471823FDEBFA00B424AF /* ReportController.swift in Sources */,
|
7A11471823FDEBFA00B424AF /* ReportController.swift in Sources */,
|
||||||
|
7A64AE7E2469E16100ABE48E /* RadialGradientLayer.swift in Sources */,
|
||||||
|
7A64AE7F2469E16100ABE48E /* IndefiniteAnimatedView.swift in Sources */,
|
||||||
7A11471A23FE839000B424AF /* AuthController.swift in Sources */,
|
7A11471A23FE839000B424AF /* AuthController.swift in Sources */,
|
||||||
7A530B7A24001D3300CBFE6E /* CheckController.swift in Sources */,
|
7A530B7A24001D3300CBFE6E /* CheckController.swift in Sources */,
|
||||||
|
7A64AE742469DFB600ABE48E /* MediaContentView.swift in Sources */,
|
||||||
7A7547DD2403180A004E8406 /* SectionHeader.swift in Sources */,
|
7A7547DD2403180A004E8406 /* SectionHeader.swift in Sources */,
|
||||||
7AF58D58240309CA00CE01A0 /* VehicleTextParamCell.swift in Sources */,
|
7AF58D58240309CA00CE01A0 /* VehicleTextParamCell.swift in Sources */,
|
||||||
7A11474723FF2AA500B424AF /* User.swift in Sources */,
|
7A11474723FF2AA500B424AF /* User.swift in Sources */,
|
||||||
@ -401,7 +429,10 @@
|
|||||||
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */,
|
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */,
|
||||||
7A05161A2414FF0900FC55AC /* DateSection.swift in Sources */,
|
7A05161A2414FF0900FC55AC /* DateSection.swift in Sources */,
|
||||||
7A11474B23FF368B00B424AF /* Settings.swift in Sources */,
|
7A11474B23FF368B00B424AF /* Settings.swift in Sources */,
|
||||||
|
7A64AE752469DFB600ABE48E /* MediaBrowserViewController.swift in Sources */,
|
||||||
7A3F07AF24366DF900E59687 /* Filter.swift in Sources */,
|
7A3F07AF24366DF900E59687 /* Filter.swift in Sources */,
|
||||||
|
7A64AE732469DFB600ABE48E /* DismissAnimationController.swift in Sources */,
|
||||||
|
7A64AE812469E16100ABE48E /* ProgressAnimatedView.swift in Sources */,
|
||||||
7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */,
|
7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@ -546,13 +577,10 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 5;
|
CURRENT_PROJECT_VERSION = 6;
|
||||||
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"$(PROJECT_DIR)/Carthage/Build/iOS",
|
|
||||||
);
|
|
||||||
INFOPLIST_FILE = AutoCat/Info.plist;
|
INFOPLIST_FILE = AutoCat/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@ -561,6 +589,7 @@
|
|||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = pro.aliencat.AutoCat;
|
PRODUCT_BUNDLE_IDENTIFIER = pro.aliencat.AutoCat;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SUPPORTS_MACCATALYST = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
@ -570,13 +599,10 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 5;
|
CURRENT_PROJECT_VERSION = 6;
|
||||||
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"$(PROJECT_DIR)/Carthage/Build/iOS",
|
|
||||||
);
|
|
||||||
INFOPLIST_FILE = AutoCat/Info.plist;
|
INFOPLIST_FILE = AutoCat/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
@ -585,6 +611,7 @@
|
|||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = pro.aliencat.AutoCat;
|
PRODUCT_BUNDLE_IDENTIFIER = pro.aliencat.AutoCat;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SUPPORTS_MACCATALYST = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
"repositoryURL": "https://github.com/RxSwiftCommunity/Action",
|
"repositoryURL": "https://github.com/RxSwiftCommunity/Action",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": null,
|
"branch": null,
|
||||||
"revision": "cdade63f7bbe1f5e1eff7779e5858a796dc2c001",
|
"revision": "1079e557787a3ffe88f833eb5f637dcf1396421b",
|
||||||
"version": "4.0.1"
|
"version": "4.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -24,8 +24,8 @@
|
|||||||
"repositoryURL": "https://github.com/onevcat/Kingfisher",
|
"repositoryURL": "https://github.com/onevcat/Kingfisher",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": null,
|
"branch": null,
|
||||||
"revision": "46bf251fee8ed426921c647790f08ca8ad0105a9",
|
"revision": "349ed06467a6f8a4939bcb83db301542bc84eac9",
|
||||||
"version": "5.13.1"
|
"version": "5.13.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -33,8 +33,8 @@
|
|||||||
"repositoryURL": "https://github.com/airbnb/MagazineLayout",
|
"repositoryURL": "https://github.com/airbnb/MagazineLayout",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": null,
|
"branch": null,
|
||||||
"revision": "bbbe1456c34c1abb527d05ff9da3ff2a54584d78",
|
"revision": "4a91fb2fa75a3c498748466227fa115fd27bb100",
|
||||||
"version": "1.5.5"
|
"version": "1.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -42,8 +42,8 @@
|
|||||||
"repositoryURL": "https://github.com/realm/realm-cocoa",
|
"repositoryURL": "https://github.com/realm/realm-cocoa",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": null,
|
"branch": null,
|
||||||
"revision": "913d59c6522e3007c7cbac3a8e9775abf72c054c",
|
"revision": "fa43b8e2909334c79f233ce472332c136ca108da",
|
||||||
"version": "4.3.2"
|
"version": "4.4.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -78,8 +78,8 @@
|
|||||||
"repositoryURL": "https://github.com/ReactiveX/RxSwift.git",
|
"repositoryURL": "https://github.com/ReactiveX/RxSwift.git",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": null,
|
"branch": null,
|
||||||
"revision": "b3e888b4972d9bc76495dd74d30a8c7fad4b9395",
|
"revision": "002d325b0bdee94e7882e1114af5ff4fe1e96afa",
|
||||||
"version": "5.0.1"
|
"version": "5.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import SVProgressHUD
|
|
||||||
import RealmSwift
|
import RealmSwift
|
||||||
import os.log
|
import os.log
|
||||||
|
|
||||||
@ -26,8 +25,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
|
|
||||||
Realm.Configuration.defaultConfiguration = config
|
Realm.Configuration.defaultConfiguration = config
|
||||||
|
|
||||||
SVProgressHUD.setDefaultStyle(.dark)
|
IHProgressHUD.set(defaultStyle: .dark)
|
||||||
SVProgressHUD.setDefaultMaskType(.black)
|
IHProgressHUD.set(defaultMaskType: .black)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -38,12 +37,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
// Called when a new scene session is being created.
|
// Called when a new scene session is being created.
|
||||||
// Use this method to select a configuration to create the new scene with.
|
// Use this method to select a configuration to create the new scene with.
|
||||||
|
|
||||||
|
#if !targetEnvironment(macCatalyst)
|
||||||
|
|
||||||
if let shortcutItem = options.shortcutItem {
|
if let shortcutItem = options.shortcutItem {
|
||||||
if shortcutItem.type == "CheckNumberAction" {
|
if shortcutItem.type == "CheckNumberAction" {
|
||||||
self.quickAction = .check
|
self.quickAction = .check
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
|
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
AutoCat/AutoCat.entitlements
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.app-sandbox</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.network.client</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@ -2,7 +2,7 @@
|
|||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="pme-aR-UNJ">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="pme-aR-UNJ">
|
||||||
<device id="retina4_7" orientation="portrait" appearance="dark"/>
|
<device id="retina4_7" orientation="portrait" appearance="dark"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16086"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
<capability name="collection view cell content view" minToolsVersion="11.0"/>
|
<capability name="collection view cell content view" minToolsVersion="11.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
@ -64,7 +64,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</collectionViewCell>
|
</collectionViewCell>
|
||||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" reuseIdentifier="VehicleTextParamCell" id="3Qa-Fn-qe7" customClass="VehicleTextParamCell" customModule="AutoCat" customModuleProvider="target">
|
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" reuseIdentifier="VehicleTextParamCell" id="3Qa-Fn-qe7" customClass="VehicleTextParamCell" customModule="AutoCat" customModuleProvider="target">
|
||||||
<rect key="frame" x="115" y="95" width="145" height="42.5"/>
|
<rect key="frame" x="0.0" y="118" width="145" height="42.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<collectionViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="fmb-JM-Fcr">
|
<collectionViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="fmb-JM-Fcr">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="145" height="42.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="145" height="42.5"/>
|
||||||
@ -110,26 +110,26 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</collectionViewCell>
|
</collectionViewCell>
|
||||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" reuseIdentifier="VehiclePhotoCell" id="X77-i3-DVY" customClass="VehiclePhotoCell" customModule="AutoCat" customModuleProvider="target">
|
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" reuseIdentifier="VehiclePhotoCell" id="X77-i3-DVY" customClass="VehiclePhotoCell" customModule="AutoCat" customModuleProvider="target">
|
||||||
<rect key="frame" x="36" y="147.5" width="303" height="264"/>
|
<rect key="frame" x="155" y="95" width="58" height="88.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<collectionViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="AMu-PZ-gGR">
|
<collectionViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="AMu-PZ-gGR">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="303" height="264"/>
|
<rect key="frame" x="0.0" y="0.0" width="58" height="88.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="wgf-C8-UOE">
|
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="wgf-C8-UOE">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="303" height="198"/>
|
<rect key="frame" x="0.0" y="0.0" width="58" height="38"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" secondItem="wgf-C8-UOE" secondAttribute="height" multiplier="101:66" id="OzD-Ts-mnv"/>
|
<constraint firstAttribute="width" secondItem="wgf-C8-UOE" secondAttribute="height" multiplier="101:66" id="Eou-Ta-7sN"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</imageView>
|
</imageView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1HU-6D-JSt">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1HU-6D-JSt">
|
||||||
<rect key="frame" x="8" y="206" width="287" height="21"/>
|
<rect key="frame" x="8" y="217.5" width="42" height="20.5"/>
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="l3q-fD-P3R">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="l3q-fD-P3R">
|
||||||
<rect key="frame" x="8" y="235" width="287" height="21"/>
|
<rect key="frame" x="8" y="242" width="42" height="18"/>
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
||||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
@ -149,7 +149,6 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
</collectionViewCellContentView>
|
</collectionViewCellContentView>
|
||||||
<color key="backgroundColor" cocoaTouchSystemColor="tableCellGroupedBackgroundColor"/>
|
<color key="backgroundColor" cocoaTouchSystemColor="tableCellGroupedBackgroundColor"/>
|
||||||
<size key="customSize" width="303" height="264"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="date" destination="l3q-fD-P3R" id="rEm-YK-xrw"/>
|
<outlet property="date" destination="l3q-fD-P3R" id="rEm-YK-xrw"/>
|
||||||
<outlet property="model" destination="1HU-6D-JSt" id="SfI-p5-s2o"/>
|
<outlet property="model" destination="1HU-6D-JSt" id="SfI-p5-s2o"/>
|
||||||
@ -194,14 +193,14 @@
|
|||||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="VehicleCell" id="VEP-QD-i6y" customClass="VehicleCell" customModule="AutoCat" customModuleProvider="target">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="VehicleCell" id="VEP-QD-i6y" customClass="VehicleCell" customModule="AutoCat" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="28" width="375" height="85.5"/>
|
<rect key="frame" x="0.0" y="28" width="375" height="85"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="VEP-QD-i6y" id="8hH-8I-XLB">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="VEP-QD-i6y" id="8hH-8I-XLB">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="85.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="85"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Kia (JF) Optima" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AQY-7N-q8D">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Kia (JF) Optima" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AQY-7N-q8D">
|
||||||
<rect key="frame" x="8" y="8" width="124" height="21.5"/>
|
<rect key="frame" x="8" y="8" width="124" height="21"/>
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
@ -213,7 +212,7 @@
|
|||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cvf-vM-QnT" customClass="PlateView" customModule="AutoCat" customModuleProvider="target">
|
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cvf-vM-QnT" customClass="PlateView" customModule="AutoCat" customModuleProvider="target">
|
||||||
<rect key="frame" x="8" y="37.5" width="317" height="40"/>
|
<rect key="frame" x="8" y="37" width="317" height="40"/>
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="height" constant="40" id="Xoz-Iw-PCU"/>
|
<constraint firstAttribute="height" constant="40" id="Xoz-Iw-PCU"/>
|
||||||
@ -533,21 +532,6 @@
|
|||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="3261.5999999999999" y="-585.1574212893554"/>
|
<point key="canvasLocation" x="3261.5999999999999" y="-585.1574212893554"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--View Controller-->
|
|
||||||
<scene sceneID="ZJx-Sq-6bu">
|
|
||||||
<objects>
|
|
||||||
<viewController id="1Nj-Yj-3Sj" sceneMemberID="viewController">
|
|
||||||
<view key="view" contentMode="scaleToFill" id="mvB-cD-Ow0">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
|
||||||
<viewLayoutGuide key="safeArea" id="AB1-mO-dFT"/>
|
|
||||||
</view>
|
|
||||||
</viewController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="xYU-vW-bpS" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="844" y="1648"/>
|
|
||||||
</scene>
|
|
||||||
<!--Search-->
|
<!--Search-->
|
||||||
<scene sceneID="kiS-EQ-VFl">
|
<scene sceneID="kiS-EQ-VFl">
|
||||||
<objects>
|
<objects>
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import RxSwift
|
import RxSwift
|
||||||
import RxCocoa
|
import RxCocoa
|
||||||
import SVProgressHUD
|
|
||||||
import RealmSwift
|
import RealmSwift
|
||||||
|
|
||||||
class AuthController: UIViewController {
|
class AuthController: UIViewController {
|
||||||
@ -32,7 +31,7 @@ class AuthController: UIViewController {
|
|||||||
@IBAction func loginTapped(_ sender: UIButton) {
|
@IBAction func loginTapped(_ sender: UIButton) {
|
||||||
guard let name = self.username.text, let pass = self.password.text else { return }
|
guard let name = self.username.text, let pass = self.password.text else { return }
|
||||||
|
|
||||||
SVProgressHUD.show()
|
IHProgressHUD.show()
|
||||||
Api.login(username: name, password: pass)
|
Api.login(username: name, password: pass)
|
||||||
.observeOn(MainScheduler.instance)
|
.observeOn(MainScheduler.instance)
|
||||||
.subscribe(onNext: self.goToMainScreen(user:), onError: self.displayError(error:))
|
.subscribe(onNext: self.goToMainScreen(user:), onError: self.displayError(error:))
|
||||||
@ -42,7 +41,7 @@ class AuthController: UIViewController {
|
|||||||
@IBAction func signupTapped(_ sender: UIButton) {
|
@IBAction func signupTapped(_ sender: UIButton) {
|
||||||
guard let name = self.username.text, let pass = self.password.text else { return }
|
guard let name = self.username.text, let pass = self.password.text else { return }
|
||||||
|
|
||||||
SVProgressHUD.show()
|
IHProgressHUD.show()
|
||||||
Api.signup(username: name, password: pass)
|
Api.signup(username: name, password: pass)
|
||||||
.observeOn(MainScheduler.instance)
|
.observeOn(MainScheduler.instance)
|
||||||
.subscribe(onNext: self.goToMainScreen(user:), onError: self.displayError(error:))
|
.subscribe(onNext: self.goToMainScreen(user:), onError: self.displayError(error:))
|
||||||
@ -51,11 +50,11 @@ class AuthController: UIViewController {
|
|||||||
|
|
||||||
func goToMainScreen(user: User) {
|
func goToMainScreen(user: User) {
|
||||||
guard let realm = try? Realm() else {
|
guard let realm = try? Realm() else {
|
||||||
SVProgressHUD.showError(withStatus: "Database error")
|
IHProgressHUD.showError(withStatus: "Database error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
SVProgressHUD.dismiss()
|
IHProgressHUD.dismiss()
|
||||||
|
|
||||||
if user.login != Settings.shared.user.login {
|
if user.login != Settings.shared.user.login {
|
||||||
try? realm.write {
|
try? realm.write {
|
||||||
@ -69,7 +68,7 @@ class AuthController: UIViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func displayError(error: Error) {
|
func displayError(error: Error) {
|
||||||
SVProgressHUD.showError(withStatus: error.localizedDescription)
|
IHProgressHUD.showError(withStatus: error.localizedDescription)
|
||||||
print(error)
|
print(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import UIKit
|
|||||||
import InputMask
|
import InputMask
|
||||||
import RealmSwift
|
import RealmSwift
|
||||||
import RxSwift
|
import RxSwift
|
||||||
import SVProgressHUD
|
|
||||||
import SwiftDate
|
import SwiftDate
|
||||||
import RxRealm
|
import RxRealm
|
||||||
import RxDataSources
|
import RxDataSources
|
||||||
@ -84,7 +83,7 @@ class CheckController: UIViewController, MaskedTextFieldDelegateListener {
|
|||||||
self.number.resignFirstResponder()
|
self.number.resignFirstResponder()
|
||||||
self.number.text = nil
|
self.number.text = nil
|
||||||
self.check.isEnabled = false
|
self.check.isEnabled = false
|
||||||
SVProgressHUD.show()
|
IHProgressHUD.show()
|
||||||
Api.checkVehicle(by: numberNormalized)
|
Api.checkVehicle(by: numberNormalized)
|
||||||
.observeOn(MainScheduler.instance)
|
.observeOn(MainScheduler.instance)
|
||||||
.subscribe(onNext: onReceivedVehicle(_:), onError: { err in
|
.subscribe(onNext: onReceivedVehicle(_:), onError: { err in
|
||||||
@ -93,7 +92,7 @@ class CheckController: UIViewController, MaskedTextFieldDelegateListener {
|
|||||||
realm.add(Vehicle(numberNormalized))
|
realm.add(Vehicle(numberNormalized))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SVProgressHUD.showError(withStatus: err.localizedDescription)
|
IHProgressHUD.showError(withStatus: err.localizedDescription)
|
||||||
print(err.localizedDescription)
|
print(err.localizedDescription)
|
||||||
}).disposed(by: self.bag)
|
}).disposed(by: self.bag)
|
||||||
}
|
}
|
||||||
@ -117,7 +116,7 @@ class CheckController: UIViewController, MaskedTextFieldDelegateListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.updateDetailController(with: vehicle)
|
self.updateDetailController(with: vehicle)
|
||||||
SVProgressHUD.dismiss()
|
IHProgressHUD.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateDetailController(with vehicle: Vehicle) {
|
func updateDetailController(with vehicle: Vehicle) {
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import MagazineLayout
|
import MagazineLayout
|
||||||
import ATGMediaBrowser
|
|
||||||
import Kingfisher
|
import Kingfisher
|
||||||
|
|
||||||
enum ReportSection: Int, CaseIterable, CustomStringConvertible {
|
enum ReportSection: Int, CaseIterable, CustomStringConvertible {
|
||||||
@ -309,7 +308,7 @@ class ReportController: UIViewController, UICollectionViewDataSource, UICollecti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func mediaBrowser(_ mediaBrowser: ATGMediaBrowser.MediaBrowserViewController, didChangeFocusTo index: Int) {
|
func mediaBrowser(_ mediaBrowser: MediaBrowserViewController, didChangeFocusTo index: Int) {
|
||||||
guard let photo = self.vehicle?.photos[index] else { return }
|
guard let photo = self.vehicle?.photos[index] else { return }
|
||||||
mediaBrowser.title = photo.description
|
mediaBrowser.title = photo.description
|
||||||
}
|
}
|
||||||
|
|||||||
236
AutoCat/ThirdParty/ATGMediaBrowser/ContentTransformers.swift
vendored
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
//
|
||||||
|
// ContentTransformers.swift
|
||||||
|
// ATGMediaBrowser
|
||||||
|
//
|
||||||
|
// Created by Suraj Thomas K on 7/17/18.
|
||||||
|
// Copyright © 2018 Al Tayer Group LLC.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||||
|
// and associated documentation files (the "Software"), to deal in the Software without
|
||||||
|
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||||
|
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
/**
|
||||||
|
Content transformer used for transition between media item views.
|
||||||
|
|
||||||
|
- parameter contentView: The content view on which transform corresponding to the position has to be applied.
|
||||||
|
- parameter position: Current position for the passed content view.
|
||||||
|
|
||||||
|
- note:
|
||||||
|
The trasnform to be applied on the contentView has to be dependent on the position passed.
|
||||||
|
The position value can be -ve, 0.0 or positive.
|
||||||
|
|
||||||
|
Try to visualize content views at -1.0[previous]=>0.0[current]=>1.0[next].
|
||||||
|
|
||||||
|
1. When position is -1.0, the content view should be at the place meant for previous view.
|
||||||
|
|
||||||
|
2. When the position is 0.0, the transform applied on the content view should make it visible full screen at origin.
|
||||||
|
|
||||||
|
3. When position is 1.0, the content view should be at the place meant for next view.
|
||||||
|
|
||||||
|
Be mindful of the drawing order, when designing new transitions.
|
||||||
|
*/
|
||||||
|
public typealias ContentTransformer = (_ contentView: UIView, _ position: CGFloat) -> Void
|
||||||
|
|
||||||
|
// MARK: - Default Transitions
|
||||||
|
|
||||||
|
/// An enumeration to hold default content transformers
|
||||||
|
public enum DefaultContentTransformers {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Horizontal move-in-out content transformer.
|
||||||
|
|
||||||
|
- Requires:
|
||||||
|
* GestureDirection: Horizontal
|
||||||
|
*/
|
||||||
|
public static let horizontalMoveInOut: ContentTransformer = { contentView, position in
|
||||||
|
|
||||||
|
let widthIncludingGap = contentView.bounds.size.width + MediaContentView.interItemSpacing
|
||||||
|
contentView.transform = CGAffineTransform(translationX: widthIncludingGap * position, y: 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Vertical move-in-out content transformer.
|
||||||
|
|
||||||
|
- Requires:
|
||||||
|
* GestureDirection: Vertical
|
||||||
|
*/
|
||||||
|
public static let verticalMoveInOut: ContentTransformer = { contentView, position in
|
||||||
|
|
||||||
|
let heightIncludingGap = contentView.bounds.size.height + MediaContentView.interItemSpacing
|
||||||
|
contentView.transform = CGAffineTransform(translationX: 0.0, y: heightIncludingGap * position)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Horizontal slide-out content transformer.
|
||||||
|
|
||||||
|
- Requires:
|
||||||
|
* GestureDirection: Horizontal
|
||||||
|
* DrawOrder: PreviousToNext
|
||||||
|
*/
|
||||||
|
public static let horizontalSlideOut: ContentTransformer = { contentView, position in
|
||||||
|
|
||||||
|
var scale: CGFloat = 1.0
|
||||||
|
if position < -0.5 {
|
||||||
|
scale = 0.9
|
||||||
|
} else if -0.5...0.0 ~= Double(position) {
|
||||||
|
scale = 1.0 + (position * 0.2)
|
||||||
|
}
|
||||||
|
var transform = CGAffineTransform(scaleX: scale, y: scale)
|
||||||
|
|
||||||
|
let widthIncludingGap = contentView.bounds.size.width + MediaContentView.interItemSpacing
|
||||||
|
let x = position >= 0.0 ? widthIncludingGap * position : 0.0
|
||||||
|
transform = transform.translatedBy(x: x, y: 0.0)
|
||||||
|
|
||||||
|
contentView.transform = transform
|
||||||
|
|
||||||
|
let margin: CGFloat = 0.0000001
|
||||||
|
contentView.isHidden = ((1.0-margin)...(1.0+margin) ~= abs(position))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Vertical slide-out content transformer.
|
||||||
|
|
||||||
|
- Requires:
|
||||||
|
* GestureDirection: Vertical
|
||||||
|
* DrawOrder: PreviousToNext
|
||||||
|
*/
|
||||||
|
public static let verticalSlideOut: ContentTransformer = { contentView, position in
|
||||||
|
|
||||||
|
var scale: CGFloat = 1.0
|
||||||
|
if position < -0.5 {
|
||||||
|
scale = 0.9
|
||||||
|
} else if -0.5...0.0 ~= Double(position) {
|
||||||
|
scale = 1.0 + (position * 0.2)
|
||||||
|
}
|
||||||
|
var transform = CGAffineTransform(scaleX: scale, y: scale)
|
||||||
|
|
||||||
|
let heightIncludingGap = contentView.bounds.size.height + MediaContentView.interItemSpacing
|
||||||
|
let y = position >= 0.0 ? heightIncludingGap * position : 0.0
|
||||||
|
transform = transform.translatedBy(x: 0.0, y: y)
|
||||||
|
|
||||||
|
contentView.transform = transform
|
||||||
|
|
||||||
|
let margin: CGFloat = 0.0000001
|
||||||
|
contentView.isHidden = ((1.0-margin)...(1.0+margin) ~= abs(position))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Horizontal slide-in content transformer.
|
||||||
|
|
||||||
|
- Requires:
|
||||||
|
* GestureDirection: Horizontal
|
||||||
|
* DrawOrder: NextToPrevious
|
||||||
|
*/
|
||||||
|
public static let horizontalSlideIn: ContentTransformer = { contentView, position in
|
||||||
|
|
||||||
|
var scale: CGFloat = 1.0
|
||||||
|
if position > 0.5 {
|
||||||
|
scale = 0.9
|
||||||
|
} else if 0.0...0.5 ~= Double(position) {
|
||||||
|
scale = 1.0 - (position * 0.2)
|
||||||
|
}
|
||||||
|
var transform = CGAffineTransform(scaleX: scale, y: scale)
|
||||||
|
|
||||||
|
let widthIncludingGap = contentView.bounds.size.width + MediaContentView.interItemSpacing
|
||||||
|
let x = position > 0.0 ? 0.0 : widthIncludingGap * position
|
||||||
|
transform = transform.translatedBy(x: x, y: 0.0)
|
||||||
|
|
||||||
|
contentView.transform = transform
|
||||||
|
|
||||||
|
let margin: CGFloat = 0.0000001
|
||||||
|
contentView.isHidden = ((1.0-margin)...(1.0+margin) ~= abs(position))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Vertical slide-in content transformer.
|
||||||
|
|
||||||
|
- Requires:
|
||||||
|
* GestureDirection: Vertical
|
||||||
|
* DrawOrder: NextToPrevious
|
||||||
|
*/
|
||||||
|
public static let verticalSlideIn: ContentTransformer = { contentView, position in
|
||||||
|
|
||||||
|
var scale: CGFloat = 1.0
|
||||||
|
if position > 0.5 {
|
||||||
|
scale = 0.9
|
||||||
|
} else if 0.0...0.5 ~= Double(position) {
|
||||||
|
scale = 1.0 - (position * 0.2)
|
||||||
|
}
|
||||||
|
var transform = CGAffineTransform(scaleX: scale, y: scale)
|
||||||
|
|
||||||
|
let heightIncludingGap = contentView.bounds.size.height + MediaContentView.interItemSpacing
|
||||||
|
let y = position > 0.0 ? 0.0 : heightIncludingGap * position
|
||||||
|
transform = transform.translatedBy(x: 0.0, y: y)
|
||||||
|
|
||||||
|
contentView.transform = transform
|
||||||
|
|
||||||
|
let margin: CGFloat = 0.0000001
|
||||||
|
contentView.isHidden = ((1.0-margin)...(1.0+margin) ~= abs(position))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Horizontal zoom-in-out content transformer.
|
||||||
|
|
||||||
|
- Requires:
|
||||||
|
* GestureDirection: Horizontal
|
||||||
|
*/
|
||||||
|
public static let horizontalZoomInOut: ContentTransformer = { contentView, position in
|
||||||
|
|
||||||
|
let minScale: CGFloat = 0.5
|
||||||
|
// Scale factor is used to reduce the scale animation speed.
|
||||||
|
let scaleFactor: CGFloat = 0.5
|
||||||
|
var scale: CGFloat = CGFloat.maximum(minScale, 1.0 - abs(position * scaleFactor))
|
||||||
|
|
||||||
|
// Actual gap will be scaleFactor * 0.5 times of contentView.bounds.size.width.
|
||||||
|
let actualGap = contentView.bounds.size.width * scaleFactor * 0.5
|
||||||
|
let gapCorrector = MediaContentView.interItemSpacing - actualGap
|
||||||
|
|
||||||
|
let widthIncludingGap = contentView.bounds.size.width + gapCorrector
|
||||||
|
let translation = (widthIncludingGap * position)/scale
|
||||||
|
|
||||||
|
var transform = CGAffineTransform(scaleX: scale, y: scale)
|
||||||
|
transform = transform.translatedBy(x: translation, y: 0.0)
|
||||||
|
|
||||||
|
contentView.transform = transform
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Vertical zoom-in-out content transformer.
|
||||||
|
|
||||||
|
- Requires:
|
||||||
|
* GestureDirection: Vertical
|
||||||
|
*/
|
||||||
|
public static let verticalZoomInOut: ContentTransformer = { contentView, position in
|
||||||
|
|
||||||
|
let minScale: CGFloat = 0.5
|
||||||
|
// Scale factor is used to reduce the scale animation speed.
|
||||||
|
let scaleFactor: CGFloat = 0.5
|
||||||
|
let scale: CGFloat = CGFloat.maximum(minScale, 1.0 - abs(position * scaleFactor))
|
||||||
|
|
||||||
|
// Actual gap will be scaleFactor * 0.5 times of contentView.bounds.size.height.
|
||||||
|
let actualGap = contentView.bounds.size.height * scaleFactor * 0.5
|
||||||
|
let gapCorrector = MediaContentView.interItemSpacing - actualGap
|
||||||
|
|
||||||
|
let heightIncludingGap = contentView.bounds.size.height + gapCorrector
|
||||||
|
let translation = (heightIncludingGap * position)/scale
|
||||||
|
|
||||||
|
var transform = CGAffineTransform(scaleX: scale, y: scale)
|
||||||
|
transform = transform.translatedBy(x: 0.0, y: translation)
|
||||||
|
|
||||||
|
contentView.transform = transform
|
||||||
|
}
|
||||||
|
}
|
||||||
288
AutoCat/ThirdParty/ATGMediaBrowser/DismissAnimationController.swift
vendored
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
//
|
||||||
|
// DismissAnimationController.swift
|
||||||
|
// ATGMediaBrowser
|
||||||
|
//
|
||||||
|
// Created by Suraj Thomas K on 7/19/18.
|
||||||
|
// Copyright © 2018 Al Tayer Group LLC.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||||
|
// and associated documentation files (the "Software"), to deal in the Software without
|
||||||
|
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||||
|
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
internal class DismissAnimationController: NSObject {
|
||||||
|
|
||||||
|
private enum Constants {
|
||||||
|
|
||||||
|
static let minimumVelocity: CGFloat = 15.0
|
||||||
|
static let minimumTranslation: CGFloat = 0.25
|
||||||
|
static let transitionDuration = 0.3
|
||||||
|
static let updateFrameRate: CGFloat = 60.0
|
||||||
|
static let transitionSpeedFactor: CGFloat = 0.15
|
||||||
|
static let minimumZoomDuringInteraction: CGFloat = 0.9
|
||||||
|
}
|
||||||
|
|
||||||
|
internal var image: UIImage?
|
||||||
|
internal let gestureDirection: MediaBrowserViewController.GestureDirection
|
||||||
|
internal weak var viewController: MediaBrowserViewController?
|
||||||
|
internal var interactionInProgress = false
|
||||||
|
|
||||||
|
private lazy var imageView = UIImageView()
|
||||||
|
private var backgroundView: UIView?
|
||||||
|
|
||||||
|
private var timer: Timer?
|
||||||
|
private var distanceToMove: CGPoint = .zero
|
||||||
|
private var relativePosition: CGPoint = .zero
|
||||||
|
private var progressValue: CGFloat {
|
||||||
|
return (gestureDirection == .horizontal) ? relativePosition.y : relativePosition.x
|
||||||
|
}
|
||||||
|
private var shouldZoomOutOnInteraction = false
|
||||||
|
|
||||||
|
init(
|
||||||
|
image: UIImage? = nil,
|
||||||
|
gestureDirection: MediaBrowserViewController.GestureDirection,
|
||||||
|
viewController: MediaBrowserViewController
|
||||||
|
) {
|
||||||
|
|
||||||
|
self.image = image
|
||||||
|
self.gestureDirection = gestureDirection
|
||||||
|
self.viewController = viewController
|
||||||
|
}
|
||||||
|
|
||||||
|
internal func handleInteractiveTransition(_ recognizer: UIPanGestureRecognizer) {
|
||||||
|
|
||||||
|
let translation = recognizer.translation(in: recognizer.view)
|
||||||
|
|
||||||
|
let progress = CGPoint(
|
||||||
|
x: translation.x / UIScreen.main.bounds.size.width,
|
||||||
|
y: translation.y / UIScreen.main.bounds.size.height
|
||||||
|
)
|
||||||
|
|
||||||
|
switch recognizer.state {
|
||||||
|
case .began:
|
||||||
|
beginTransition()
|
||||||
|
fallthrough
|
||||||
|
case .changed:
|
||||||
|
relativePosition = progress
|
||||||
|
updateTransition()
|
||||||
|
case .ended, .cancelled, .failed:
|
||||||
|
var toMove: CGFloat = 0.0
|
||||||
|
|
||||||
|
if abs(progressValue) > Constants.minimumTranslation {
|
||||||
|
if let viewController = viewController,
|
||||||
|
let targetFrame = viewController.dataSource?.targetFrameForDismissal(viewController) {
|
||||||
|
|
||||||
|
animateToTargetFrame(targetFrame)
|
||||||
|
return
|
||||||
|
|
||||||
|
} else {
|
||||||
|
toMove = (progressValue / abs(progressValue))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toMove = -progressValue
|
||||||
|
}
|
||||||
|
|
||||||
|
if gestureDirection == .horizontal {
|
||||||
|
distanceToMove.x = -relativePosition.x
|
||||||
|
distanceToMove.y = toMove
|
||||||
|
} else {
|
||||||
|
distanceToMove.x = toMove
|
||||||
|
distanceToMove.y = -relativePosition.y
|
||||||
|
}
|
||||||
|
|
||||||
|
if timer == nil {
|
||||||
|
timer = Timer.scheduledTimer(
|
||||||
|
timeInterval: 1.0/Double(Constants.updateFrameRate),
|
||||||
|
target: self,
|
||||||
|
selector: #selector(update(_:)),
|
||||||
|
userInfo: nil,
|
||||||
|
repeats: true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal func animateToTargetFrame(_ target: CGRect) {
|
||||||
|
|
||||||
|
let frame = imageViewFrame(for: imageView.bounds.size, in: target, mode: .scaleAspectFill)
|
||||||
|
UIView.animate(withDuration: Constants.transitionDuration, animations: {
|
||||||
|
|
||||||
|
self.imageView.frame = frame
|
||||||
|
self.backgroundView?.alpha = 0.0
|
||||||
|
}) { finished in
|
||||||
|
|
||||||
|
if finished {
|
||||||
|
self.interactionInProgress = false
|
||||||
|
if self.gestureDirection == .horizontal {
|
||||||
|
self.relativePosition.y = -1.0
|
||||||
|
} else {
|
||||||
|
self.relativePosition.x = -1.0
|
||||||
|
}
|
||||||
|
self.finishTransition()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func update(_ timeInterval: TimeInterval) {
|
||||||
|
|
||||||
|
let speed = (Constants.updateFrameRate * Constants.transitionSpeedFactor)
|
||||||
|
let xDistance = distanceToMove.x / speed
|
||||||
|
let yDistance = distanceToMove.y / speed
|
||||||
|
distanceToMove.x -= xDistance
|
||||||
|
distanceToMove.y -= yDistance
|
||||||
|
relativePosition.x += xDistance
|
||||||
|
relativePosition.y += yDistance
|
||||||
|
updateTransition()
|
||||||
|
|
||||||
|
let translation = CGPoint(
|
||||||
|
x: xDistance * (UIScreen.main.bounds.size.width),
|
||||||
|
y: yDistance * (UIScreen.main.bounds.size.height)
|
||||||
|
)
|
||||||
|
let directionalTranslation = (gestureDirection == .horizontal) ? translation.y : translation.x
|
||||||
|
if abs(directionalTranslation) < 1.0 {
|
||||||
|
|
||||||
|
relativePosition.x += distanceToMove.x
|
||||||
|
relativePosition.y += distanceToMove.y
|
||||||
|
updateTransition()
|
||||||
|
interactionInProgress = false
|
||||||
|
|
||||||
|
finishTransition()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal func beginTransition() {
|
||||||
|
|
||||||
|
shouldZoomOutOnInteraction = false
|
||||||
|
if let viewController = viewController {
|
||||||
|
shouldZoomOutOnInteraction = viewController.dataSource?.targetFrameForDismissal(viewController) != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
createTransitionViews()
|
||||||
|
|
||||||
|
viewController?.mediaContainerView.isHidden = true
|
||||||
|
viewController?.hideControls = true
|
||||||
|
viewController?.visualEffectContainer.isHidden = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private func finishTransition() {
|
||||||
|
|
||||||
|
distanceToMove = .zero
|
||||||
|
timer?.invalidate()
|
||||||
|
timer = nil
|
||||||
|
|
||||||
|
imageView.removeFromSuperview()
|
||||||
|
|
||||||
|
backgroundView?.removeFromSuperview()
|
||||||
|
backgroundView = nil
|
||||||
|
|
||||||
|
let directionalPosition = (gestureDirection == .horizontal) ? relativePosition.y : relativePosition.x
|
||||||
|
if directionalPosition != 0.0 {
|
||||||
|
viewController?.dismiss(animated: false, completion: nil)
|
||||||
|
} else {
|
||||||
|
viewController?.mediaContainerView.isHidden = false
|
||||||
|
viewController?.hideControls = false
|
||||||
|
viewController?.visualEffectContainer.isHidden = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func createTransitionViews() {
|
||||||
|
|
||||||
|
backgroundView?.removeFromSuperview()
|
||||||
|
backgroundView = nil
|
||||||
|
|
||||||
|
if let viewController = viewController,
|
||||||
|
let bg = viewController.visualEffectContainer.snapshotView(afterScreenUpdates: true) {
|
||||||
|
backgroundView = bg
|
||||||
|
viewController.view.addSubview(bg)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
bg.leadingAnchor.constraint(equalTo: viewController.view.leadingAnchor),
|
||||||
|
bg.trailingAnchor.constraint(equalTo: viewController.view.trailingAnchor),
|
||||||
|
bg.topAnchor.constraint(equalTo: viewController.view.topAnchor),
|
||||||
|
bg.bottomAnchor.constraint(equalTo: viewController.view.bottomAnchor)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
imageView.image = image
|
||||||
|
imageView.frame = imageViewFrame(
|
||||||
|
for: image?.size ?? .zero,
|
||||||
|
in: viewController?.view.bounds ?? .zero
|
||||||
|
)
|
||||||
|
viewController?.view.addSubview(imageView)
|
||||||
|
imageView.transform = CGAffineTransform.identity
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateTransition() {
|
||||||
|
|
||||||
|
var transform = CGAffineTransform.identity
|
||||||
|
let directionalPosition = (gestureDirection == .horizontal) ? relativePosition.y : relativePosition.x
|
||||||
|
|
||||||
|
if shouldZoomOutOnInteraction {
|
||||||
|
let scale = CGFloat.maximum(Constants.minimumZoomDuringInteraction, 1.0 - abs(directionalPosition))
|
||||||
|
transform = transform.scaledBy(x: scale, y: scale)
|
||||||
|
}
|
||||||
|
|
||||||
|
if gestureDirection == .horizontal {
|
||||||
|
transform = transform.translatedBy(
|
||||||
|
x: shouldZoomOutOnInteraction ? relativePosition.x * UIScreen.main.bounds.size.width : 0.0,
|
||||||
|
y: relativePosition.y * UIScreen.main.bounds.size.height
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
transform = transform.translatedBy(
|
||||||
|
x: relativePosition.x * UIScreen.main.bounds.size.width,
|
||||||
|
y: shouldZoomOutOnInteraction ? relativePosition.y * UIScreen.main.bounds.size.height : 0.0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
imageView.transform = transform
|
||||||
|
|
||||||
|
let alpha = (directionalPosition < 0.0) ? directionalPosition + 1.0 : 1.0 - directionalPosition
|
||||||
|
backgroundView?.alpha = alpha
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private func imageViewFrame(for imageSize: CGSize, in frame: CGRect, mode: UIView.ContentMode = .scaleAspectFit) -> CGRect {
|
||||||
|
|
||||||
|
guard imageSize != .zero,
|
||||||
|
mode == .scaleAspectFit || mode == .scaleAspectFill else {
|
||||||
|
return frame
|
||||||
|
}
|
||||||
|
|
||||||
|
var targetImageSize = frame.size
|
||||||
|
|
||||||
|
let aspectHeight = frame.size.width / imageSize.width * imageSize.height
|
||||||
|
let aspectWidth = frame.size.height / imageSize.height * imageSize.width
|
||||||
|
|
||||||
|
if imageSize.width / imageSize.height > frame.size.width / frame.size.height {
|
||||||
|
if mode == .scaleAspectFit {
|
||||||
|
targetImageSize.height = aspectHeight
|
||||||
|
} else {
|
||||||
|
targetImageSize.width = aspectWidth
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if mode == .scaleAspectFit {
|
||||||
|
targetImageSize.width = aspectWidth
|
||||||
|
} else {
|
||||||
|
targetImageSize.height = aspectHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = frame.minX + (frame.size.width - targetImageSize.width) / 2.0
|
||||||
|
let y = frame.minY + (frame.size.height - targetImageSize.height) / 2.0
|
||||||
|
|
||||||
|
return CGRect(origin: CGPoint(x: x, y: y), size: targetImageSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
1019
AutoCat/ThirdParty/ATGMediaBrowser/MediaBrowserViewController.swift
vendored
Normal file
315
AutoCat/ThirdParty/ATGMediaBrowser/MediaContentView.swift
vendored
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
//
|
||||||
|
// MediaContentView.swift
|
||||||
|
// ATGMediaBrowser
|
||||||
|
//
|
||||||
|
// Created by Suraj Thomas K on 7/10/18.
|
||||||
|
// Copyright © 2018 Al Tayer Group LLC.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||||
|
// and associated documentation files (the "Software"), to deal in the Software without
|
||||||
|
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
|
// substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
||||||
|
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
/// Holds the value of minimumZoomScale and maximumZoomScale of the image.
|
||||||
|
public struct ZoomScale {
|
||||||
|
|
||||||
|
/// Minimum zoom level, the image can be zoomed out to.
|
||||||
|
public var minimumZoomScale: CGFloat
|
||||||
|
|
||||||
|
/// Maximum zoom level, the image can be zoomed into.
|
||||||
|
public var maximumZoomScale: CGFloat
|
||||||
|
|
||||||
|
/// Default zoom scale. minimum is 1.0 and maximum is 3.0
|
||||||
|
public static let `default` = ZoomScale(
|
||||||
|
minimum: 1.0,
|
||||||
|
maximum: 3.0
|
||||||
|
)
|
||||||
|
|
||||||
|
/// Identity zoom scale. Pass this to disable zoom.
|
||||||
|
public static let identity = ZoomScale(
|
||||||
|
minimum: 1.0,
|
||||||
|
maximum: 1.0
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initializer.
|
||||||
|
- parameter minimum: The minimum zoom level.
|
||||||
|
- parameter maximum: The maximum zoom level.
|
||||||
|
*/
|
||||||
|
public init(minimum: CGFloat, maximum: CGFloat) {
|
||||||
|
|
||||||
|
minimumZoomScale = minimum
|
||||||
|
maximumZoomScale = maximum
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class MediaContentView: UIScrollView {
|
||||||
|
|
||||||
|
// MARK: - Exposed variables
|
||||||
|
internal static var interItemSpacing: CGFloat = 0.0
|
||||||
|
internal var index: Int {
|
||||||
|
didSet {
|
||||||
|
resetZoom()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal static var contentTransformer: ContentTransformer = DefaultContentTransformers.horizontalMoveInOut
|
||||||
|
|
||||||
|
internal var position: CGFloat {
|
||||||
|
didSet {
|
||||||
|
updateTransform()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal var image: UIImage? {
|
||||||
|
didSet {
|
||||||
|
updateImageView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal var isLoading: Bool = false {
|
||||||
|
didSet {
|
||||||
|
indicatorContainer.isHidden = !isLoading
|
||||||
|
if isLoading {
|
||||||
|
indicator.startAnimating()
|
||||||
|
} else {
|
||||||
|
indicator.stopAnimating()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal var zoomLevels: ZoomScale? {
|
||||||
|
didSet {
|
||||||
|
zoomScale = ZoomScale.default.minimumZoomScale
|
||||||
|
minimumZoomScale = zoomLevels?.minimumZoomScale ?? ZoomScale.default.minimumZoomScale
|
||||||
|
maximumZoomScale = zoomLevels?.maximumZoomScale ?? ZoomScale.default.maximumZoomScale
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private enumerations
|
||||||
|
|
||||||
|
private enum Constants {
|
||||||
|
|
||||||
|
static let indicatorViewSize: CGFloat = 60.0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private variables
|
||||||
|
|
||||||
|
private lazy var imageView: UIImageView = {
|
||||||
|
let imageView = UIImageView()
|
||||||
|
imageView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||||
|
imageView.contentMode = .scaleAspectFit
|
||||||
|
imageView.clipsToBounds = true
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var indicator: UIActivityIndicatorView = {
|
||||||
|
let indicatorView = UIActivityIndicatorView()
|
||||||
|
indicatorView.style = UIActivityIndicatorView.Style.large
|
||||||
|
indicatorView.hidesWhenStopped = true
|
||||||
|
return indicatorView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var indicatorContainer: UIView = {
|
||||||
|
let container = UIView()
|
||||||
|
container.backgroundColor = .darkGray
|
||||||
|
container.layer.cornerRadius = Constants.indicatorViewSize * 0.5
|
||||||
|
container.layer.masksToBounds = true
|
||||||
|
return container
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var doubleTapGestureRecognizer: UITapGestureRecognizer = { [unowned self] in
|
||||||
|
let gesture = UITapGestureRecognizer(target: self, action: #selector(didDoubleTap(_:)))
|
||||||
|
gesture.numberOfTapsRequired = 2
|
||||||
|
gesture.numberOfTouchesRequired = 1
|
||||||
|
return gesture
|
||||||
|
}()
|
||||||
|
|
||||||
|
init(index itemIndex: Int, position: CGFloat, frame: CGRect) {
|
||||||
|
|
||||||
|
self.index = itemIndex
|
||||||
|
self.position = position
|
||||||
|
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
initializeViewComponents()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder aDecoder: NSCoder) {
|
||||||
|
|
||||||
|
fatalError("Do nto use `init?(coder:)`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - View Composition and Events
|
||||||
|
|
||||||
|
extension MediaContentView {
|
||||||
|
|
||||||
|
private func initializeViewComponents() {
|
||||||
|
|
||||||
|
addSubview(imageView)
|
||||||
|
imageView.frame = frame
|
||||||
|
|
||||||
|
setupIndicatorView()
|
||||||
|
|
||||||
|
configureScrollView()
|
||||||
|
|
||||||
|
addGestureRecognizer(doubleTapGestureRecognizer)
|
||||||
|
|
||||||
|
updateTransform()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func configureScrollView() {
|
||||||
|
|
||||||
|
isMultipleTouchEnabled = true
|
||||||
|
showsHorizontalScrollIndicator = false
|
||||||
|
showsVerticalScrollIndicator = false
|
||||||
|
contentSize = imageView.bounds.size
|
||||||
|
canCancelContentTouches = false
|
||||||
|
zoomLevels = ZoomScale.default
|
||||||
|
delegate = self
|
||||||
|
bouncesZoom = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private func resetZoom() {
|
||||||
|
|
||||||
|
setZoomScale(1.0, animated: false)
|
||||||
|
imageView.transform = CGAffineTransform.identity
|
||||||
|
contentSize = imageView.frame.size
|
||||||
|
contentOffset = .zero
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setupIndicatorView() {
|
||||||
|
|
||||||
|
addSubview(indicatorContainer)
|
||||||
|
indicatorContainer.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
indicatorContainer.widthAnchor.constraint(equalToConstant: Constants.indicatorViewSize),
|
||||||
|
indicatorContainer.heightAnchor.constraint(equalToConstant: Constants.indicatorViewSize),
|
||||||
|
indicatorContainer.centerXAnchor.constraint(equalTo: centerXAnchor),
|
||||||
|
indicatorContainer.centerYAnchor.constraint(equalTo: centerYAnchor)
|
||||||
|
])
|
||||||
|
|
||||||
|
indicatorContainer.addSubview(indicator)
|
||||||
|
indicator.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
indicator.leadingAnchor.constraint(equalTo: indicatorContainer.leadingAnchor),
|
||||||
|
indicator.trailingAnchor.constraint(equalTo: indicatorContainer.trailingAnchor),
|
||||||
|
indicator.topAnchor.constraint(equalTo: indicatorContainer.topAnchor),
|
||||||
|
indicator.bottomAnchor.constraint(equalTo: indicatorContainer.bottomAnchor)
|
||||||
|
])
|
||||||
|
|
||||||
|
indicatorContainer.setNeedsLayout()
|
||||||
|
indicatorContainer.layoutIfNeeded()
|
||||||
|
|
||||||
|
indicatorContainer.isHidden = true
|
||||||
|
}
|
||||||
|
|
||||||
|
internal func updateTransform() {
|
||||||
|
|
||||||
|
MediaContentView.contentTransformer(self, position)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal func handleChangeInViewSize(to size: CGSize) {
|
||||||
|
|
||||||
|
let oldScale = zoomScale
|
||||||
|
zoomScale = 1.0
|
||||||
|
imageView.frame = CGRect(origin: .zero, size: size)
|
||||||
|
|
||||||
|
updateImageView()
|
||||||
|
updateTransform()
|
||||||
|
setZoomScale(oldScale, animated: false)
|
||||||
|
|
||||||
|
contentSize = imageView.frame.size
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func didDoubleTap(_ recognizer: UITapGestureRecognizer) {
|
||||||
|
|
||||||
|
let locationInImage = recognizer.location(in: imageView)
|
||||||
|
|
||||||
|
let isImageCoveringScreen = imageView.frame.size.width > bounds.size.width &&
|
||||||
|
imageView.frame.size.height > bounds.size.height
|
||||||
|
let zoomTo = (isImageCoveringScreen || zoomScale == maximumZoomScale) ? minimumZoomScale : maximumZoomScale
|
||||||
|
|
||||||
|
guard zoomTo != zoomScale else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let width = bounds.size.width / zoomTo
|
||||||
|
let height = bounds.size.height / zoomTo
|
||||||
|
|
||||||
|
let zoomRect = CGRect(
|
||||||
|
x: locationInImage.x - width * 0.5,
|
||||||
|
y: locationInImage.y - height * 0.5,
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
)
|
||||||
|
|
||||||
|
zoom(to: zoomRect, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - UIScrollViewDelegate
|
||||||
|
|
||||||
|
extension MediaContentView: UIScrollViewDelegate {
|
||||||
|
|
||||||
|
internal func viewForZooming(in scrollView: UIScrollView) -> UIView? {
|
||||||
|
|
||||||
|
let shouldAllowZoom = (image != nil && position == 0.0)
|
||||||
|
return shouldAllowZoom ? imageView : nil
|
||||||
|
}
|
||||||
|
|
||||||
|
internal func scrollViewDidZoom(_ scrollView: UIScrollView) {
|
||||||
|
|
||||||
|
centerImageView()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func centerImageView() {
|
||||||
|
|
||||||
|
var imageViewFrame = imageView.frame
|
||||||
|
|
||||||
|
if imageViewFrame.size.width < bounds.size.width {
|
||||||
|
imageViewFrame.origin.x = (bounds.size.width - imageViewFrame.size.width) / 2.0
|
||||||
|
} else {
|
||||||
|
imageViewFrame.origin.x = 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
if imageViewFrame.size.height < bounds.size.height {
|
||||||
|
imageViewFrame.origin.y = (bounds.size.height - imageViewFrame.size.height) / 2.0
|
||||||
|
} else {
|
||||||
|
imageViewFrame.origin.y = 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
imageView.frame = imageViewFrame
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateImageView() {
|
||||||
|
|
||||||
|
imageView.image = image
|
||||||
|
|
||||||
|
if let contentImage = image {
|
||||||
|
|
||||||
|
let imageViewSize = bounds.size
|
||||||
|
let imageSize = contentImage.size
|
||||||
|
var targetImageSize = imageViewSize
|
||||||
|
|
||||||
|
if imageSize.width / imageSize.height > imageViewSize.width / imageViewSize.height {
|
||||||
|
targetImageSize.height = imageViewSize.width / imageSize.width * imageSize.height
|
||||||
|
} else {
|
||||||
|
targetImageSize.width = imageViewSize.height / imageSize.height * imageSize.width
|
||||||
|
}
|
||||||
|
|
||||||
|
imageView.frame = CGRect(origin: .zero, size: targetImageSize)
|
||||||
|
}
|
||||||
|
centerImageView()
|
||||||
|
}
|
||||||
|
}
|
||||||
0
AutoCat/ThirdParty/IHProgressHUD/.gitkeep
vendored
Normal file
BIN
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/angle-mask@1x.png
vendored
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/angle-mask@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/angle-mask@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/error@1x.png
vendored
Normal file
|
After Width: | Height: | Size: 409 B |
BIN
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/error@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 873 B |
BIN
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/error@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 752 B |
BIN
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/info@1x.png
vendored
Normal file
|
After Width: | Height: | Size: 662 B |
BIN
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/info@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/info@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/success@1x.png
vendored
Normal file
|
After Width: | Height: | Size: 490 B |
BIN
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/success@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 912 B |
BIN
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.bundle/success@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
1312
AutoCat/ThirdParty/IHProgressHUD/IHProgressHUD.swift
vendored
Executable file
197
AutoCat/ThirdParty/IHProgressHUD/IndefiniteAnimatedView.swift
vendored
Executable file
@ -0,0 +1,197 @@
|
|||||||
|
//
|
||||||
|
// 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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
128
AutoCat/ThirdParty/IHProgressHUD/ProgressAnimatedView.swift
vendored
Executable file
@ -0,0 +1,128 @@
|
|||||||
|
//
|
||||||
|
// 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!
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
27
AutoCat/ThirdParty/IHProgressHUD/RadialGradientLayer.swift
vendored
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||