Basic report screen
This commit is contained in:
parent
1b952af498
commit
b3c8a809dd
@ -31,6 +31,7 @@
|
||||
7A28283327E7263B0049BDBF /* UIStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A28283227E7263B0049BDBF /* UIStackView.swift */; };
|
||||
7A28283627E74C110049BDBF /* SwiftEntryKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7A28283527E74C110049BDBF /* SwiftEntryKit */; };
|
||||
7A28283827E74D930049BDBF /* CheckController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A28283727E74D930049BDBF /* CheckController.swift */; };
|
||||
7A2977212857595700060A2A /* ReportController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2977202857595700060A2A /* ReportController.swift */; };
|
||||
7A2B6CD427FCE93C00519F1E /* TestSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2B6CD327FCE93C00519F1E /* TestSettings.swift */; };
|
||||
7A2B6CD727FCED0500519F1E /* XCUIApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2B6CD527FCEC8600519F1E /* XCUIApplication.swift */; };
|
||||
7A36E55C27FB55570025AACB /* Testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A36E55B27FB55570025AACB /* Testing.swift */; };
|
||||
@ -163,6 +164,7 @@
|
||||
7A28283027E721A70049BDBF /* UIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIView.swift; sourceTree = "<group>"; };
|
||||
7A28283227E7263B0049BDBF /* UIStackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIStackView.swift; sourceTree = "<group>"; };
|
||||
7A28283727E74D930049BDBF /* CheckController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckController.swift; sourceTree = "<group>"; };
|
||||
7A2977202857595700060A2A /* ReportController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportController.swift; sourceTree = "<group>"; };
|
||||
7A2B6CD327FCE93C00519F1E /* TestSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSettings.swift; sourceTree = "<group>"; };
|
||||
7A2B6CD527FCEC8600519F1E /* XCUIApplication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCUIApplication.swift; sourceTree = "<group>"; };
|
||||
7A36E55B27FB55570025AACB /* Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Testing.swift; sourceTree = "<group>"; };
|
||||
@ -298,6 +300,7 @@
|
||||
6841A0A6580C6E9FF26DC6E2 /* HistoryController.swift */,
|
||||
6841A5A586BC03AA21D73DF4 /* SettingsController.swift */,
|
||||
7A28283727E74D930049BDBF /* CheckController.swift */,
|
||||
7A2977202857595700060A2A /* ReportController.swift */,
|
||||
);
|
||||
path = Controllers;
|
||||
sourceTree = "<group>";
|
||||
@ -815,6 +818,7 @@
|
||||
7A28283827E74D930049BDBF /* CheckController.swift in Sources */,
|
||||
6841A7D2375D35B0102D7DEC /* SwiftMaskTextfield.swift in Sources */,
|
||||
6841ABD5E4B126DEF3612BBD /* PNKeyboard.swift in Sources */,
|
||||
7A2977212857595700060A2A /* ReportController.swift in Sources */,
|
||||
7A24C19C27EE25B400049E7F /* PlateView.swift in Sources */,
|
||||
7A24C19D27EE25B400049E7F /* FlagLayer.swift in Sources */,
|
||||
);
|
||||
|
||||
@ -9,6 +9,18 @@
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>AutoCat2.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>AutoCat2UITests.testExample.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>8</integer>
|
||||
</dict>
|
||||
<key>AutoCatCore.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
@ -56,13 +68,6 @@
|
||||
<key>orderHint</key>
|
||||
<integer>5</integer>
|
||||
</dict>
|
||||
<key>AutoCat2UITests.testExample.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false />
|
||||
<key>orderHint</key>
|
||||
<integer>8</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
|
||||
@ -66,6 +66,10 @@ class CoreDataSource<Item: NSManagedObject & Dated & Differentiable, Cell: Confi
|
||||
}
|
||||
}
|
||||
|
||||
func item(at indexPath: IndexPath) -> Item {
|
||||
sections[indexPath.section].elements[indexPath.row]
|
||||
}
|
||||
|
||||
// MARK: - NSFetchedResultsControllerDelegate
|
||||
|
||||
|
||||
|
||||
@ -6,8 +6,7 @@ import UIKit
|
||||
import PKHUD
|
||||
import AutoCatCore
|
||||
|
||||
class HistoryController: UIViewController {
|
||||
|
||||
class HistoryController: UIViewController, UITableViewDelegate {
|
||||
|
||||
private lazy var tableView: UITableView = {
|
||||
let table = UITableView()
|
||||
@ -15,6 +14,7 @@ class HistoryController: UIViewController {
|
||||
table.register(VehicleCell.self, forCellReuseIdentifier: cellIdentifier)
|
||||
table.translatesAutoresizingMaskIntoConstraints = false
|
||||
table.accessibilityIdentifier = "historyTable"
|
||||
table.delegate = self
|
||||
return table
|
||||
}()
|
||||
|
||||
@ -52,4 +52,18 @@ class HistoryController: UIViewController {
|
||||
show(error: error)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UITableViewDelegate
|
||||
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
|
||||
guard let vehicle = dataSource?.item(at: indexPath) else {
|
||||
return
|
||||
}
|
||||
|
||||
let controller = ReportController(vehicle: vehicle)
|
||||
controller.hidesBottomBarWhenPushed = true
|
||||
navigationController?.pushViewController(controller, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
278
AutoCat2/Controllers/ReportController.swift
Normal file
278
AutoCat2/Controllers/ReportController.swift
Normal file
@ -0,0 +1,278 @@
|
||||
//
|
||||
// ReportController.swift
|
||||
// AutoCat2
|
||||
//
|
||||
// Created by Selim Mustafaev on 13.06.2022.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import AutoCatCore
|
||||
|
||||
enum ReportSection: Int, CaseIterable {
|
||||
|
||||
case title
|
||||
case general
|
||||
case identifiers
|
||||
case engine
|
||||
// case history = 3
|
||||
// case debug = 4
|
||||
|
||||
var name: String {
|
||||
switch self {
|
||||
case .title: return ""
|
||||
case .general: return "General"
|
||||
case .identifiers: return "Identifiers"
|
||||
case .engine: return "Engine"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ReportGeneralItem: Int, CaseIterable {
|
||||
|
||||
case year
|
||||
case color
|
||||
case category
|
||||
case steeringWheelPosition
|
||||
case isJapanese
|
||||
|
||||
var name: String {
|
||||
switch self {
|
||||
case .year: return "Year"
|
||||
case .color: return "Color"
|
||||
case .category: return "Category"
|
||||
case .steeringWheelPosition: return "Steering wheel position"
|
||||
case .isJapanese: return "Japanese vehicle"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ReportIdentifiersItem: Int, CaseIterable {
|
||||
|
||||
case number
|
||||
case vin
|
||||
case sts
|
||||
case pts
|
||||
|
||||
var name: String {
|
||||
switch self {
|
||||
case .number: return "Plate number"
|
||||
case .vin: return "VIN"
|
||||
case .sts: return "STS"
|
||||
case .pts: return "PTS"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ReportEngineItem: Int, CaseIterable {
|
||||
|
||||
case number
|
||||
case fuelType
|
||||
case volume
|
||||
case powerHp
|
||||
case powerKw
|
||||
|
||||
var name: String {
|
||||
switch self {
|
||||
case .number: return "Number"
|
||||
case .fuelType: return "Fuel type"
|
||||
case .volume: return "Volume"
|
||||
case .powerHp: return "Power (HP)"
|
||||
case .powerKw: return "Power (kw)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ReportItem {
|
||||
let name: String
|
||||
let value: String?
|
||||
let image: UIImage?
|
||||
|
||||
init(name: String, value: String?) {
|
||||
self.name = name
|
||||
self.value = value
|
||||
self.image = nil
|
||||
}
|
||||
|
||||
init(name: String, image: UIImage?) {
|
||||
self.name = name
|
||||
self.value = nil
|
||||
self.image = image
|
||||
}
|
||||
}
|
||||
|
||||
class ReportController: UIViewController, UICollectionViewDataSource {
|
||||
|
||||
private let reportTextItemId = String(describing: ReportTextItemCell.self)
|
||||
|
||||
private lazy var collectionView: UICollectionView = {
|
||||
let collection = UICollectionView(frame: .zero, collectionViewLayout: createLayout())
|
||||
collection.translatesAutoresizingMaskIntoConstraints = false
|
||||
collection.register(ReportTextItemCell.self,
|
||||
forCellWithReuseIdentifier: reportTextItemId)
|
||||
collection.dataSource = self
|
||||
return collection
|
||||
}()
|
||||
|
||||
private let textCellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, ReportItem> { cell, indexPath, item in
|
||||
var config = UIListContentConfiguration.valueCell()
|
||||
config.text = item.name
|
||||
config.secondaryText = item.value
|
||||
cell.contentConfiguration = config
|
||||
}
|
||||
|
||||
private let titleCellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, ReportItem> { cell, indexPath, item in
|
||||
var config = UIListContentConfiguration.cell()
|
||||
config.text = item.name
|
||||
cell.contentConfiguration = config
|
||||
}
|
||||
|
||||
private let supplementaryRegistration = UICollectionView.SupplementaryRegistration<UICollectionViewListCell>(elementKind: UICollectionView.elementKindSectionHeader) { supplementaryView, elementKind, indexPath in
|
||||
|
||||
guard let section = ReportSection(rawValue: indexPath.section) else {
|
||||
return
|
||||
}
|
||||
|
||||
var configutation = UIListContentConfiguration.groupedHeader()
|
||||
configutation.text = section.name
|
||||
supplementaryView.contentConfiguration = configutation
|
||||
}
|
||||
|
||||
let vehicle: CDVehicle
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
||||
init(vehicle: CDVehicle) {
|
||||
self.vehicle = vehicle
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
view.backgroundColor = .systemBackground
|
||||
title = vehicle.number
|
||||
|
||||
view.addSubview(collectionView)
|
||||
collectionView.pin(to: view)
|
||||
}
|
||||
|
||||
func createLayout() -> UICollectionViewLayout {
|
||||
|
||||
UICollectionViewCompositionalLayout { section, env in
|
||||
var config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
|
||||
config.headerMode = section == 0 ? .none : .supplementary
|
||||
|
||||
return NSCollectionLayoutSection.list(using: config, layoutEnvironment: env)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Getting data
|
||||
|
||||
func getTextData(for indexPath: IndexPath) -> ReportItem {
|
||||
guard let section = ReportSection(rawValue: indexPath.section) else {
|
||||
return ReportItem(name: "", value: nil)
|
||||
}
|
||||
|
||||
switch section {
|
||||
case .title: return ReportItem(name: vehicle.brand?.name?.original ?? "", image: nil)
|
||||
case .general: return getGeneralValue(index: indexPath.row)
|
||||
case .identifiers: return getIdentifiersValue(index: indexPath.row)
|
||||
case .engine: return getEngineValue(index: indexPath.row)
|
||||
}
|
||||
}
|
||||
|
||||
func getGeneralValue(index: Int) -> ReportItem {
|
||||
guard let item = ReportGeneralItem(rawValue: index) else {
|
||||
return ReportItem(name: "", value: nil)
|
||||
}
|
||||
|
||||
let value: String?
|
||||
|
||||
switch item {
|
||||
case .year: value = String(vehicle.year)
|
||||
case .color: value = vehicle.color
|
||||
case .category: value = vehicle.category
|
||||
case .steeringWheelPosition: value = vehicle.isRightWheel ? "Right" : "Left"
|
||||
case .isJapanese: value = vehicle.isJapanese ? "Yes" : "No"
|
||||
}
|
||||
|
||||
return ReportItem(name: item.name, value: value)
|
||||
}
|
||||
|
||||
func getIdentifiersValue(index: Int) -> ReportItem {
|
||||
guard let item = ReportIdentifiersItem(rawValue: index) else {
|
||||
return ReportItem(name: "", value: nil)
|
||||
}
|
||||
|
||||
let value: String?
|
||||
|
||||
switch item {
|
||||
case .number: value = vehicle.number
|
||||
case .vin: value = vehicle.vin1
|
||||
case .sts: value = vehicle.sts
|
||||
case .pts: value = vehicle.pts
|
||||
}
|
||||
|
||||
return ReportItem(name: item.name, value: value)
|
||||
}
|
||||
|
||||
func getEngineValue(index: Int) -> ReportItem {
|
||||
guard let item = ReportEngineItem(rawValue: index) else {
|
||||
return ReportItem(name: "", value: nil)
|
||||
}
|
||||
|
||||
let value: String?
|
||||
|
||||
switch item {
|
||||
case .number: value = vehicle.engine?.number
|
||||
case .fuelType: value = vehicle.engine?.fuelType
|
||||
case .volume: value = String(vehicle.engine?.volume ?? 0)
|
||||
case .powerHp: value = String(vehicle.engine?.powerHp ?? 0)
|
||||
case .powerKw: value = String(vehicle.engine?.powerKw ?? 0)
|
||||
}
|
||||
|
||||
return ReportItem(name: item.name, value: value)
|
||||
}
|
||||
|
||||
// MARK: - UICollectionViewDataSource
|
||||
|
||||
func numberOfSections(in collectionView: UICollectionView) -> Int {
|
||||
ReportSection.allCases.count
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
guard let sectionEnum = ReportSection(rawValue: section) else {
|
||||
return 0
|
||||
}
|
||||
|
||||
switch sectionEnum {
|
||||
case .title:
|
||||
return 1
|
||||
case .general:
|
||||
return ReportGeneralItem.allCases.count
|
||||
case .identifiers:
|
||||
return ReportIdentifiersItem.allCases.count
|
||||
case .engine:
|
||||
return ReportEngineItem.allCases.count
|
||||
}
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView,
|
||||
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
|
||||
let item = getTextData(for: indexPath)
|
||||
return collectionView.dequeueConfiguredReusableCell(using: textCellRegistration, for: indexPath, item: item)
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView,
|
||||
viewForSupplementaryElementOfKind kind: String,
|
||||
at indexPath: IndexPath) -> UICollectionReusableView {
|
||||
|
||||
collectionView.dequeueConfiguredReusableSupplementary(using: supplementaryRegistration,
|
||||
for: indexPath)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user