-
Notifications
You must be signed in to change notification settings - Fork 59
/
CategoriesHits.SearchResultsController.swift
147 lines (127 loc) · 4.29 KB
/
CategoriesHits.SearchResultsController.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//
// SearchResultsController.swift
// CategoriesHits
//
// Created by Vladislav Fitc on 19/11/2021.
//
import Foundation
import InstantSearch
import UIKit
extension CategoriesHits {
class SearchResultsController: UITableViewController {
var didSelectSuggestion: ((String) -> Void)?
enum Section: Int, CaseIterable {
case categories
case hits
var title: String {
switch self {
case .categories:
return "Categories"
case .hits:
return "Products"
}
}
var cellReuseIdentifier: String {
switch self {
case .categories:
return "categories"
case .hits:
return "hits"
}
}
init?(section: Int) {
self.init(rawValue: section)
}
init?(indexPath: IndexPath) {
self.init(section: indexPath.section)
}
}
weak var categoriesInteractor: FacetListInteractor? {
didSet {
oldValue?.onResultsUpdated.cancelSubscription(for: tableView)
guard let interactor = categoriesInteractor else { return }
interactor.onResultsUpdated.subscribe(with: tableView) { tableView, _ in
tableView.reloadData()
}.onQueue(.main)
}
}
weak var hitsInteractor: HitsInteractor<Hit<Product>>? {
didSet {
oldValue?.onResultsUpdated.cancelSubscription(for: tableView)
guard let interactor = hitsInteractor else { return }
interactor.onResultsUpdated.subscribe(with: tableView) { tableView, _ in
tableView.reloadData()
}.onQueue(.main)
}
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(CategoryTableViewCell.self, forCellReuseIdentifier: Section.categories.cellReuseIdentifier)
tableView.register(ProductTableViewCell.self, forCellReuseIdentifier: Section.hits.cellReuseIdentifier)
}
override func numberOfSections(in _: UITableView) -> Int {
return Section.allCases.count
}
override func tableView(_: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let section = Section(rawValue: section) else { return 0 }
switch section {
case .categories:
return categoriesInteractor?.items.count ?? 0
case .hits:
return hitsInteractor?.numberOfHits() ?? 0
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let section = Section(rawValue: indexPath.section) else { return UITableViewCell() }
let cell: UITableViewCell
switch section {
case .categories:
cell = tableView.dequeueReusableCell(withIdentifier: Section.categories.cellReuseIdentifier, for: indexPath)
if
let categoryCell = cell as? CategoryTableViewCell,
let category = categoriesInteractor?.items[indexPath.row] {
categoryCell.setup(with: category)
}
case .hits:
cell = tableView.dequeueReusableCell(withIdentifier: Section.hits.cellReuseIdentifier, for: indexPath)
if
let productTableViewCell = cell as? ProductTableViewCell,
let hit = hitsInteractor?.hit(atIndex: indexPath.row) {
productTableViewCell.setup(with: hit)
}
}
return cell
}
override func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? {
guard let section = Section(rawValue: section) else { return nil }
switch section {
case .categories where categoriesInteractor?.items.count ?? 0 == 0:
return nil
case .hits where hitsInteractor?.numberOfHits() ?? 0 == 0:
return nil
default:
return section.title
}
}
override func tableView(_: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
guard let section = Section(indexPath: indexPath) else { return 0 }
switch section {
case .categories:
return 44
case .hits:
return 100
}
}
override func tableView(_: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let section = Section(rawValue: indexPath.section) else { return }
switch section {
case .hits:
// Handle hit selection
break
case .categories:
// Handle category selection
break
}
}
}
}