Sharing report
This commit is contained in:
parent
f5983b37bb
commit
81c7ef119b
@ -58,6 +58,8 @@
|
|||||||
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 */; };
|
||||||
|
7A8A2209248D10EC0073DFD9 /* ResizeImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A2208248D10EC0073DFD9 /* ResizeImage.swift */; };
|
||||||
|
7A8A220B248D67B60073DFD9 /* VehicleReportImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A220A248D67B60073DFD9 /* VehicleReportImage.swift */; };
|
||||||
7A96AE2A246AFD6200297C33 /* Eureka in Frameworks */ = {isa = PBXBuildFile; productRef = 7A96AE29246AFD6200297C33 /* Eureka */; };
|
7A96AE2A246AFD6200297C33 /* Eureka in Frameworks */ = {isa = PBXBuildFile; productRef = 7A96AE29246AFD6200297C33 /* Eureka */; };
|
||||||
7A96AE2D246B2B7400297C33 /* GoogleSignInController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */; };
|
7A96AE2D246B2B7400297C33 /* GoogleSignInController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */; };
|
||||||
7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A96AE2E246B2BCD00297C33 /* WebKit.framework */; };
|
7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A96AE2E246B2BCD00297C33 /* WebKit.framework */; };
|
||||||
@ -116,6 +118,8 @@
|
|||||||
7A7547DB2403180A004E8406 /* SectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeader.swift; sourceTree = "<group>"; };
|
7A7547DB2403180A004E8406 /* SectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeader.swift; sourceTree = "<group>"; };
|
||||||
7A7547DC2403180A004E8406 /* SectionHeader.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SectionHeader.xib; sourceTree = "<group>"; };
|
7A7547DC2403180A004E8406 /* SectionHeader.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SectionHeader.xib; sourceTree = "<group>"; };
|
||||||
7A7547DF24032CB6004E8406 /* VehiclePhotoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehiclePhotoCell.swift; sourceTree = "<group>"; };
|
7A7547DF24032CB6004E8406 /* VehiclePhotoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehiclePhotoCell.swift; sourceTree = "<group>"; };
|
||||||
|
7A8A2208248D10EC0073DFD9 /* ResizeImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResizeImage.swift; sourceTree = "<group>"; };
|
||||||
|
7A8A220A248D67B60073DFD9 /* VehicleReportImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleReportImage.swift; sourceTree = "<group>"; };
|
||||||
7A92D0AB240425B100EF3B77 /* ATGMediaBrowser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ATGMediaBrowser.framework; path = Carthage/Build/iOS/ATGMediaBrowser.framework; sourceTree = "<group>"; };
|
7A92D0AB240425B100EF3B77 /* ATGMediaBrowser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ATGMediaBrowser.framework; path = Carthage/Build/iOS/ATGMediaBrowser.framework; sourceTree = "<group>"; };
|
||||||
7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleSignInController.swift; sourceTree = "<group>"; };
|
7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleSignInController.swift; sourceTree = "<group>"; };
|
||||||
7A96AE2E246B2BCD00297C33 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; };
|
7A96AE2E246B2BCD00297C33 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
@ -258,6 +262,8 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
7A3F07AA24360DC800E59687 /* Dated.swift */,
|
7A3F07AA24360DC800E59687 /* Dated.swift */,
|
||||||
|
7A8A2208248D10EC0073DFD9 /* ResizeImage.swift */,
|
||||||
|
7A8A220A248D67B60073DFD9 /* VehicleReportImage.swift */,
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -431,6 +437,7 @@
|
|||||||
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */,
|
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */,
|
||||||
7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */,
|
7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */,
|
||||||
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */,
|
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */,
|
||||||
|
7A8A2209248D10EC0073DFD9 /* ResizeImage.swift in Sources */,
|
||||||
7A6DD90E24337930009DE740 /* PlateNumber.swift in Sources */,
|
7A6DD90E24337930009DE740 /* PlateNumber.swift in Sources */,
|
||||||
7AEFE728240455E200910EB7 /* SettingsController.swift in Sources */,
|
7AEFE728240455E200910EB7 /* SettingsController.swift in Sources */,
|
||||||
7A3F07AB24360DC800E59687 /* Dated.swift in Sources */,
|
7A3F07AB24360DC800E59687 /* Dated.swift in Sources */,
|
||||||
@ -455,6 +462,7 @@
|
|||||||
7A530B7E24017FEE00CBFE6E /* VehicleCell.swift in Sources */,
|
7A530B7E24017FEE00CBFE6E /* VehicleCell.swift in Sources */,
|
||||||
7A11474423FF06CA00B424AF /* Api.swift in Sources */,
|
7A11474423FF06CA00B424AF /* Api.swift in Sources */,
|
||||||
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */,
|
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */,
|
||||||
|
7A8A220B248D67B60073DFD9 /* VehicleReportImage.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 */,
|
7A64AE752469DFB600ABE48E /* MediaBrowserViewController.swift in Sources */,
|
||||||
@ -607,7 +615,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 10;
|
CURRENT_PROJECT_VERSION = 11;
|
||||||
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
||||||
INFOPLIST_FILE = AutoCat/Info.plist;
|
INFOPLIST_FILE = AutoCat/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
@ -629,7 +637,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 10;
|
CURRENT_PROJECT_VERSION = 11;
|
||||||
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
||||||
INFOPLIST_FILE = AutoCat/Info.plist;
|
INFOPLIST_FILE = AutoCat/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
|
|||||||
@ -40,53 +40,5 @@
|
|||||||
landmarkType = "7">
|
landmarkType = "7">
|
||||||
</BreakpointContent>
|
</BreakpointContent>
|
||||||
</BreakpointProxy>
|
</BreakpointProxy>
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
uuid = "AA4B069F-D10E-43F0-ABC6-943827D977DB"
|
|
||||||
shouldBeEnabled = "No"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
filePath = "AutoCat/Controllers/MainSplitController.swift"
|
|
||||||
startingColumnNumber = "9223372036854775807"
|
|
||||||
endingColumnNumber = "9223372036854775807"
|
|
||||||
startingLineNumber = "47"
|
|
||||||
endingLineNumber = "47"
|
|
||||||
landmarkName = "splitViewController(_:collapseSecondary:onto:)"
|
|
||||||
landmarkType = "7">
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
uuid = "0D82204D-F9A5-486B-90AC-ED6A0FAE1468"
|
|
||||||
shouldBeEnabled = "No"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
filePath = "AutoCat/Controllers/MainSplitController.swift"
|
|
||||||
startingColumnNumber = "9223372036854775807"
|
|
||||||
endingColumnNumber = "9223372036854775807"
|
|
||||||
startingLineNumber = "12"
|
|
||||||
endingLineNumber = "12"
|
|
||||||
landmarkName = "splitViewController(_:showDetail:sender:)"
|
|
||||||
landmarkType = "7">
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
uuid = "CED2DE1A-E658-4DC2-AF2D-9FFC0A4AC9D1"
|
|
||||||
shouldBeEnabled = "No"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
filePath = "AutoCat/Controllers/MainSplitController.swift"
|
|
||||||
startingColumnNumber = "9223372036854775807"
|
|
||||||
endingColumnNumber = "9223372036854775807"
|
|
||||||
startingLineNumber = "34"
|
|
||||||
endingLineNumber = "34"
|
|
||||||
landmarkName = "splitViewController(_:separateSecondaryFrom:)"
|
|
||||||
landmarkType = "7">
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
</Breakpoints>
|
</Breakpoints>
|
||||||
</Bucket>
|
</Bucket>
|
||||||
|
|||||||
16
AutoCat/Assets.xcassets/SteeringWheel.imageset/Contents.json
vendored
Normal file
16
AutoCat/Assets.xcassets/SteeringWheel.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "steering_wheel.pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"preserves-vector-representation" : true,
|
||||||
|
"template-rendering-intent" : "template"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
AutoCat/Assets.xcassets/SteeringWheel.imageset/steering_wheel.pdf
vendored
Normal file
BIN
AutoCat/Assets.xcassets/SteeringWheel.imageset/steering_wheel.pdf
vendored
Normal file
Binary file not shown.
@ -171,7 +171,13 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
<viewLayoutGuide key="safeArea" id="fbN-WR-iQY"/>
|
<viewLayoutGuide key="safeArea" id="fbN-WR-iQY"/>
|
||||||
</view>
|
</view>
|
||||||
<navigationItem key="navigationItem" id="goK-kc-WCv"/>
|
<navigationItem key="navigationItem" id="goK-kc-WCv">
|
||||||
|
<barButtonItem key="rightBarButtonItem" systemItem="action" id="2MI-Nh-b8L">
|
||||||
|
<connections>
|
||||||
|
<action selector="onShare:" destination="i1k-Y4-pyh" id="SP4-ez-N4e"/>
|
||||||
|
</connections>
|
||||||
|
</barButtonItem>
|
||||||
|
</navigationItem>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="collection" destination="rG3-ze-Zre" id="f8S-jh-WSw"/>
|
<outlet property="collection" destination="rG3-ze-Zre" id="f8S-jh-WSw"/>
|
||||||
</connections>
|
</connections>
|
||||||
|
|||||||
@ -6,15 +6,18 @@ class VehicleHeaderCell: MagazineLayoutCollectionViewCell {
|
|||||||
@IBOutlet weak var logo: UIImageView!
|
@IBOutlet weak var logo: UIImageView!
|
||||||
@IBOutlet weak var name: UILabel!
|
@IBOutlet weak var name: UILabel!
|
||||||
|
|
||||||
|
private let placeholder = UIImage(named: "SteeringWheel")
|
||||||
|
|
||||||
override func prepareForReuse() {
|
override func prepareForReuse() {
|
||||||
self.logo.kf.cancelDownloadTask()
|
self.logo.kf.cancelDownloadTask()
|
||||||
}
|
}
|
||||||
|
|
||||||
func configure(with vehicle: Vehicle) {
|
func configure(with vehicle: Vehicle) {
|
||||||
self.name.text = vehicle.brand?.name?.original
|
self.name.text = vehicle.brand?.name?.original
|
||||||
|
self.logo.image = self.placeholder
|
||||||
|
|
||||||
if let url = vehicle.brand?.logo {
|
if let url = vehicle.brand?.logo {
|
||||||
self.logo.kf.setImage(with: URL(string: url))
|
self.logo.kf.setImage(with: URL(string: url), placeholder: self.placeholder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import MagazineLayout
|
import MagazineLayout
|
||||||
import Kingfisher
|
import Kingfisher
|
||||||
|
import LinkPresentation
|
||||||
|
|
||||||
enum ReportSection: Int, CaseIterable, CustomStringConvertible {
|
enum ReportSection: Int, CaseIterable, CustomStringConvertible {
|
||||||
case header = 0
|
case header = 0
|
||||||
@ -74,31 +75,41 @@ enum ReportEngineSection: Int, CaseIterable, CustomStringConvertible {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReportController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateMagazineLayout, MediaBrowserViewControllerDataSource, MediaBrowserViewControllerDelegate {
|
class ReportController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateMagazineLayout, MediaBrowserViewControllerDataSource, MediaBrowserViewControllerDelegate, UIActivityItemSource {
|
||||||
|
|
||||||
@IBOutlet weak var collection: UICollectionView!
|
@IBOutlet weak var collection: UICollectionView!
|
||||||
|
|
||||||
private let fullWidth = MagazineLayoutItemSizeMode(widthMode: .fullWidth(respectsHorizontalInsets: true), heightMode: .dynamic)
|
private let fullWidth = MagazineLayoutItemSizeMode(widthMode: .fullWidth(respectsHorizontalInsets: true), heightMode: .dynamic)
|
||||||
|
private var reportImageUrl: URL?
|
||||||
|
|
||||||
var vehicle: Vehicle? {
|
var vehicle: Vehicle? {
|
||||||
didSet {
|
didSet {
|
||||||
loadViewIfNeeded()
|
loadViewIfNeeded()
|
||||||
self.collection.reloadData()
|
self.collection.reloadData()
|
||||||
|
self.navigationController?.setNavigationBarHidden(self.vehicle == nil, animated: false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Lifecycle
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
self.collection.collectionViewLayout = MagazineLayout()
|
self.collection.collectionViewLayout = MagazineLayout()
|
||||||
let nib = UINib(nibName: "SectionHeader", bundle: nil)
|
let nib = UINib(nibName: "SectionHeader", bundle: nil)
|
||||||
self.collection.register(nib, forSupplementaryViewOfKind: MagazineLayout.SupplementaryViewKind.sectionHeader, withReuseIdentifier: "SectionHeader")
|
self.collection.register(nib, forSupplementaryViewOfKind: MagazineLayout.SupplementaryViewKind.sectionHeader, withReuseIdentifier: "SectionHeader")
|
||||||
|
|
||||||
|
if let vehicle = self.vehicle {
|
||||||
|
let urls = Array(vehicle.photos.compactMap { URL(string: $0.url) })
|
||||||
|
let prefetcher = ImagePrefetcher(urls: urls)
|
||||||
|
prefetcher.start()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
super.viewWillAppear(animated)
|
super.viewWillAppear(animated)
|
||||||
guard let ad = UIApplication.shared.delegate as? AppDelegate else { return }
|
guard let ad = UIApplication.shared.delegate as? AppDelegate else { return }
|
||||||
|
|
||||||
self.navigationController?.setNavigationBarHidden(self.traitCollection.horizontalSizeClass != .compact, animated: false)
|
self.navigationController?.setNavigationBarHidden(self.vehicle == nil, animated: false)
|
||||||
|
|
||||||
if ad.quickAction == .check {
|
if ad.quickAction == .check {
|
||||||
self.dismiss(animated: false, completion: nil)
|
self.dismiss(animated: false, completion: nil)
|
||||||
@ -109,10 +120,6 @@ class ReportController: UIViewController, UICollectionViewDataSource, UICollecti
|
|||||||
super.viewDidAppear(animated)
|
super.viewDidAppear(animated)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
|
||||||
self.navigationController?.setNavigationBarHidden(self.traitCollection.horizontalSizeClass != .compact, animated: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - UICollectionViewDataSource
|
// MARK: - UICollectionViewDataSource
|
||||||
|
|
||||||
func numberOfSections(in collectionView: UICollectionView) -> Int {
|
func numberOfSections(in collectionView: UICollectionView) -> Int {
|
||||||
@ -332,4 +339,62 @@ class ReportController: UIViewController, UICollectionViewDataSource, UICollecti
|
|||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Sharing
|
||||||
|
|
||||||
|
@IBAction func onShare(_ sender: UIBarButtonItem) {
|
||||||
|
guard let vehicle = self.vehicle else { return }
|
||||||
|
|
||||||
|
let sheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
|
||||||
|
sheet.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem
|
||||||
|
|
||||||
|
let cancel = UIAlertAction(title: "Cancel", style: .cancel) { _ in sheet.dismiss(animated: true, completion: nil) }
|
||||||
|
let share = UIAlertAction(title: "Share", style: .default) { _ in
|
||||||
|
let image = vehicle.reportImage(width: self.collection.contentSize.width)
|
||||||
|
|
||||||
|
do {
|
||||||
|
let fm = FileManager.default
|
||||||
|
let documentDirectory = try fm.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:false)
|
||||||
|
let fileURL = documentDirectory.appendingPathComponent("report.png")
|
||||||
|
if let imageData = image.pngData() {
|
||||||
|
try imageData.write(to: fileURL)
|
||||||
|
self.reportImageUrl = fileURL
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = UIActivityViewController(activityItems: [self], applicationActivities: nil)
|
||||||
|
controller.popoverPresentationController?.barButtonItem = sender
|
||||||
|
self.present(controller, animated: true)
|
||||||
|
} catch {
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let copyPlateNumber = UIAlertAction(title: "Copy plate number", style: .default) { _ in UIPasteboard.general.string = self.vehicle?.number }
|
||||||
|
let copyVin = UIAlertAction(title: "Copy VIN", style: .default) { _ in UIPasteboard.general.string = self.vehicle?.vin1 }
|
||||||
|
|
||||||
|
sheet.addAction(share)
|
||||||
|
sheet.addAction(copyPlateNumber)
|
||||||
|
sheet.addAction(copyVin)
|
||||||
|
sheet.addAction(cancel)
|
||||||
|
self.present(sheet, animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
|
||||||
|
return UIImage()
|
||||||
|
}
|
||||||
|
|
||||||
|
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
|
||||||
|
return self.reportImageUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
|
||||||
|
guard let url = self.reportImageUrl else { return nil }
|
||||||
|
|
||||||
|
let metadata = LPLinkMetadata()
|
||||||
|
metadata.title = self.vehicle?.number
|
||||||
|
metadata.originalURL = url
|
||||||
|
metadata.url = url
|
||||||
|
metadata.imageProvider = NSItemProvider.init(contentsOf: url)
|
||||||
|
metadata.iconProvider = NSItemProvider.init(contentsOf: url)
|
||||||
|
return metadata
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
43
AutoCat/Extensions/ResizeImage.swift
Normal file
43
AutoCat/Extensions/ResizeImage.swift
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension UIImage {
|
||||||
|
class func resize(image: UIImage, targetSize: CGSize) -> UIImage {
|
||||||
|
let size = image.size
|
||||||
|
|
||||||
|
let widthRatio = targetSize.width / image.size.width
|
||||||
|
let heightRatio = targetSize.height / image.size.height
|
||||||
|
|
||||||
|
var newSize: CGSize
|
||||||
|
if widthRatio > heightRatio {
|
||||||
|
newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
|
||||||
|
} else {
|
||||||
|
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
|
||||||
|
}
|
||||||
|
|
||||||
|
let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
|
||||||
|
|
||||||
|
UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
|
||||||
|
image.draw(in: rect)
|
||||||
|
let newImage = UIGraphicsGetImageFromCurrentImageContext()
|
||||||
|
UIGraphicsEndImageContext()
|
||||||
|
|
||||||
|
return newImage!
|
||||||
|
}
|
||||||
|
|
||||||
|
class func scale(image: UIImage, by scale: CGFloat) -> UIImage? {
|
||||||
|
let size = image.size
|
||||||
|
let scaledSize = CGSize(width: size.width * scale, height: size.height * scale)
|
||||||
|
return UIImage.resize(image: image, targetSize: scaledSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cutHeight(to newHeight: CGFloat) -> UIImage {
|
||||||
|
let newSize = CGSize(width: self.size.width, height: newHeight)
|
||||||
|
let rect = CGRect(origin: .zero, size: newSize)
|
||||||
|
|
||||||
|
let renderer = UIGraphicsImageRenderer(bounds: rect)
|
||||||
|
return renderer.image { _ in
|
||||||
|
self.draw(in: CGRect(origin: .zero, size: self.size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
175
AutoCat/Extensions/VehicleReportImage.swift
Normal file
175
AutoCat/Extensions/VehicleReportImage.swift
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
import UIKit
|
||||||
|
import Kingfisher
|
||||||
|
|
||||||
|
extension Vehicle {
|
||||||
|
func drawLine(y: CGFloat, width: CGFloat, margin: CGFloat = 15,context: CGContext) {
|
||||||
|
let lineWidth = 1/UIScreen.main.scale
|
||||||
|
context.move(to: CGPoint(x: margin, y: y + lineWidth/2))
|
||||||
|
context.addLine(to: CGPoint(x: width, y: y + lineWidth/2))
|
||||||
|
context.closePath()
|
||||||
|
context.setLineWidth(lineWidth)
|
||||||
|
context.setStrokeColor(UIColor.opaqueSeparator.cgColor)
|
||||||
|
context.strokePath()
|
||||||
|
}
|
||||||
|
|
||||||
|
func drawCell(y: CGFloat, width: CGFloat, height: CGFloat, title: String, value: String, lineMargin: CGFloat = 15, context: CGContext) {
|
||||||
|
let fontSize: CGFloat = 17
|
||||||
|
let font = UIFont.systemFont(ofSize: fontSize)
|
||||||
|
let offest = (height - fontSize)/2
|
||||||
|
let pStyle = NSMutableParagraphStyle()
|
||||||
|
pStyle.alignment = .right
|
||||||
|
let attributes: [NSAttributedString.Key: Any] = [.font: font, .foregroundColor: UIColor.label]
|
||||||
|
let valueAttributs: [NSAttributedString.Key: Any] = [.font: font, .foregroundColor: UIColor.secondaryLabel, .paragraphStyle: pStyle]
|
||||||
|
let rect = CGRect(x: 15, y: y + offest, width: width - 30, height: height)
|
||||||
|
UIColor.secondarySystemGroupedBackground.setFill()
|
||||||
|
UIRectFill(CGRect(x: 0, y: y, width: width, height: height))
|
||||||
|
title.draw(with: rect, options: .usesLineFragmentOrigin, attributes: attributes, context: nil)
|
||||||
|
value.draw(with: rect, options: .usesLineFragmentOrigin, attributes: valueAttributs, context: nil)
|
||||||
|
self.drawLine(y: y + height - 1/UIScreen.main.scale, width: width, margin: lineMargin, context: context)
|
||||||
|
}
|
||||||
|
|
||||||
|
func drawBigTextCell(y: CGFloat, width: CGFloat, title: String, value: String, lineMargin: CGFloat = 15, context: CGContext) -> CGFloat {
|
||||||
|
let pStyle = NSMutableParagraphStyle()
|
||||||
|
pStyle.alignment = .right
|
||||||
|
let attributes: [NSAttributedString.Key: Any] = [.font: UIFont.systemFont(ofSize: 17), .foregroundColor: UIColor.label]
|
||||||
|
let valueAttributs: [NSAttributedString.Key: Any] = [.font: UIFont.systemFont(ofSize: 15), .foregroundColor: UIColor.secondaryLabel, .paragraphStyle: pStyle]
|
||||||
|
UIColor.secondarySystemGroupedBackground.setFill()
|
||||||
|
|
||||||
|
let text = NSMutableAttributedString(string: title + " - " + value)
|
||||||
|
text.setAttributes(attributes, range: NSRange(location: 0, length: title.count))
|
||||||
|
text.setAttributes(valueAttributs, range: NSRange(location: title.count, length: value.count + 3))
|
||||||
|
let textRect = text.boundingRect(with: CGSize(width: width - 30, height: 1000), options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil)
|
||||||
|
let height = textRect.size.height > 28 ? textRect.size.height + 16 : 44
|
||||||
|
let offset = (height - textRect.size.height)/2
|
||||||
|
let rect = CGRect(x: 15, y: y + offset, width: width - 30, height: height)
|
||||||
|
UIRectFill(CGRect(x: 0, y: y, width: width, height: height))
|
||||||
|
text.draw(with: rect, options: .usesLineFragmentOrigin, context: nil)
|
||||||
|
self.drawLine(y: y + height - 1/UIScreen.main.scale, width: width, margin: lineMargin, context: context)
|
||||||
|
|
||||||
|
return height
|
||||||
|
}
|
||||||
|
|
||||||
|
func reportImage(width: CGFloat) -> UIImage {
|
||||||
|
var realHeight: CGFloat = 0
|
||||||
|
let rect = CGRect(origin: .zero, size: CGSize(width: width, height: CGFloat(10000)))
|
||||||
|
let renderer = UIGraphicsImageRenderer(bounds: rect)
|
||||||
|
let image = renderer.image { rendererContext in
|
||||||
|
let cellHeight: CGFloat = 44
|
||||||
|
let ctx = rendererContext.cgContext
|
||||||
|
let centeredStyle = NSMutableParagraphStyle()
|
||||||
|
centeredStyle.alignment = .center
|
||||||
|
let titleAttributes: [NSAttributedString.Key: Any] = [.font: UIFont.systemFont(ofSize: 20), .paragraphStyle: centeredStyle, .foregroundColor: UIColor.label]
|
||||||
|
let headerAttributes: [NSAttributedString.Key: Any] = [.font: UIFont.systemFont(ofSize: 13), .foregroundColor: UIColor.secondaryLabel]
|
||||||
|
|
||||||
|
let w: CGFloat = width
|
||||||
|
var y: CGFloat = 0
|
||||||
|
|
||||||
|
UIColor.systemBackground.setFill()
|
||||||
|
UIRectFill(rect)
|
||||||
|
|
||||||
|
y += 12
|
||||||
|
"\(self.brand?.name?.original ?? "Unknown model") (\(self.number))".draw(with: CGRect(x: 0, y: y, width: w, height: 30), options: .usesLineFragmentOrigin, attributes: titleAttributes, context: nil)
|
||||||
|
y += 50
|
||||||
|
"GENERAL".draw(with: CGRect(x: 15, y: y, width: w - 15, height: 24), options: .usesLineFragmentOrigin, attributes: headerAttributes, context: nil)
|
||||||
|
y += 24
|
||||||
|
self.drawLine(y: y, width: w, margin: 0, context: ctx)
|
||||||
|
y += 1/UIScreen.main.scale
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "Year", value: String(self.year), context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "Color", value: self.color ?? "<unknown>", context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "Category", value: self.category ?? "<unknown>", context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "Steering wheel position", value: self.isRightWheel ? "Right" : "Left", context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "Japanese", value: self.isJapanese ? "Yes" : "No", lineMargin: 0, context: ctx)
|
||||||
|
y += cellHeight + 32
|
||||||
|
|
||||||
|
"IDENTIFIERS".draw(with: CGRect(x: 15, y: y, width: w - 15, height: 24), options: .usesLineFragmentOrigin, attributes: headerAttributes, context: nil)
|
||||||
|
y += 24
|
||||||
|
self.drawLine(y: y, width: w, margin: 0, context: ctx)
|
||||||
|
y += 1/UIScreen.main.scale
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "Plate number", value: self.number, context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "VIN", value: self.vin1 ?? "<unknown>", context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "STS", value: self.sts ?? "<unknown>", context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "PTS", value: self.pts ?? "<unknown>", context: ctx)
|
||||||
|
y += cellHeight + 32
|
||||||
|
|
||||||
|
"ENGINE".draw(with: CGRect(x: 15, y: y, width: w - 15, height: 24), options: .usesLineFragmentOrigin, attributes: headerAttributes, context: nil)
|
||||||
|
y += 24
|
||||||
|
self.drawLine(y: y, width: w, margin: 0, context: ctx)
|
||||||
|
y += 1/UIScreen.main.scale
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "Number", value: self.engine?.number ?? "<unknown>", context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "Fuel type", value: self.engine?.fuelType ?? "<unknown>", context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "Volume", value: String(self.engine?.volume ?? 0), context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "Power (HP)", value: String(self.engine?.powerHp ?? 0), context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "Power (kw)", value: String(self.engine?.powerKw ?? 0), context: ctx)
|
||||||
|
y += cellHeight + 32
|
||||||
|
|
||||||
|
"OWNERSHIP PERIODS (\(self.ownershipPeriods.count))".draw(with: CGRect(x: 15, y: y, width: w - 15, height: 24), options: .usesLineFragmentOrigin, attributes: headerAttributes, context: nil)
|
||||||
|
y += 24
|
||||||
|
self.drawLine(y: y, width: w, margin: 0, context: ctx)
|
||||||
|
y += 1/UIScreen.main.scale
|
||||||
|
|
||||||
|
let formatter = DateFormatter()
|
||||||
|
formatter.dateStyle = .long
|
||||||
|
formatter.timeStyle = .none
|
||||||
|
for period in self.ownershipPeriods {
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "Owner type", value: period.ownerType, context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
|
||||||
|
let fromDate = Date(timeIntervalSince1970: TimeInterval(period.from/1000))
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "From", value: formatter.string(from: fromDate), context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
|
||||||
|
let toDate = Date(timeIntervalSince1970: TimeInterval(period.to/1000))
|
||||||
|
let toString = period.to == 0 ? "now" : formatter.string(from: toDate)
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: "To", value: toString, context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
|
||||||
|
let height = self.drawBigTextCell(y: y, width: w, title: "Last operation", value: period.lastOperation, lineMargin: 0, context: ctx)
|
||||||
|
y += height + 8
|
||||||
|
}
|
||||||
|
|
||||||
|
y += 24
|
||||||
|
|
||||||
|
"PHOTOS (\(self.photos.count))".draw(with: CGRect(x: 15, y: y, width: w - 15, height: 24), options: .usesLineFragmentOrigin, attributes: headerAttributes, context: nil)
|
||||||
|
y += 24
|
||||||
|
self.drawLine(y: y, width: w, margin: 0, context: ctx)
|
||||||
|
y += 1/UIScreen.main.scale
|
||||||
|
|
||||||
|
for photo in self.photos {
|
||||||
|
let date = Date(timeIntervalSince1970: TimeInterval(photo.date/1000))
|
||||||
|
var name = "<Unknown model>"
|
||||||
|
if let brand = photo.brand, let model = photo.model {
|
||||||
|
name = "\(brand) \(model)"
|
||||||
|
}
|
||||||
|
|
||||||
|
if let url = URL(string: photo.url) {
|
||||||
|
if let image = ImageCache.default.retrieveImageInDiskCache(forKey: url.cacheKey) {
|
||||||
|
let imgHeight = image.size.height*w/image.size.width
|
||||||
|
let rect = CGRect(x: 0, y: y, width: w, height: imgHeight)
|
||||||
|
image.draw(in: rect)
|
||||||
|
y += imgHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.drawCell(y: y, width: w, height: cellHeight, title: name, value: formatter.string(from: date), lineMargin: 0, context: ctx)
|
||||||
|
y += cellHeight
|
||||||
|
|
||||||
|
y += 16
|
||||||
|
}
|
||||||
|
|
||||||
|
realHeight = y
|
||||||
|
}
|
||||||
|
|
||||||
|
return image.cutHeight(to: realHeight)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -42,6 +42,8 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||||
|
<string>AutoCat needs access to photo library to save reports</string>
|
||||||
<key>UIAppFonts</key>
|
<key>UIAppFonts</key>
|
||||||
<array>
|
<array>
|
||||||
<string>RoadNumbers2.0.otf</string>
|
<string>RoadNumbers2.0.otf</string>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user