-
Notifications
You must be signed in to change notification settings - Fork 60
/
Copy pathQuerySuggestionsAndHits.SearchResultsController.swift
133 lines (115 loc) · 4.03 KB
/
QuerySuggestionsAndHits.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
//
// SearchResultsController.swift
// QuerySuggestionsHits
//
// Created by Vladislav Fitc on 05/11/2021.
//
import Foundation
import InstantSearch
import UIKit
extension QuerySuggestionsAndHits {
class SearchResultsController: UITableViewController {
enum Section: Int, CaseIterable {
case suggestions
case hits
var title: String {
switch self {
case .suggestions:
return "Suggestions"
case .hits:
return "Products"
}
}
var cellReuseIdentifier: String {
switch self {
case .suggestions:
return "suggestionCellID"
case .hits:
return "productCellID"
}
}
init?(section: Int) {
self.init(rawValue: section)
}
init?(indexPath: IndexPath) {
self.init(section: indexPath.section)
}
}
weak var suggestionsHitsInteractor: HitsInteractor<QuerySuggestion>? {
didSet {
oldValue?.onResultsUpdated.cancelSubscription(for: tableView)
guard let interactor = suggestionsHitsInteractor 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(SearchSuggestionTableViewCell.self, forCellReuseIdentifier: Section.suggestions.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(section: section) else { return 0 }
switch section {
case .suggestions:
return suggestionsHitsInteractor?.numberOfHits() ?? 0
case .hits:
return hitsInteractor?.numberOfHits() ?? 0
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let section = Section(indexPath: indexPath) else { return UITableViewCell() }
let cell: UITableViewCell
switch section {
case .suggestions:
cell = tableView.dequeueReusableCell(withIdentifier: Section.suggestions.cellReuseIdentifier, for: indexPath)
if
let searchSuggestionCell = cell as? SearchSuggestionTableViewCell,
let suggestion = suggestionsHitsInteractor?.hit(atIndex: indexPath.row) {
searchSuggestionCell.setup(with: suggestion)
}
case .hits:
cell = tableView.dequeueReusableCell(withIdentifier: Section.hits.cellReuseIdentifier, for: indexPath)
if
let productTableViewCell = cell as? ProductTableViewCell,
let product = hitsInteractor?.hit(atIndex: indexPath.row) {
productTableViewCell.setup(with: product)
}
}
return cell
}
override func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? {
guard let section = Section(section: section) else { return nil }
switch section {
case .suggestions where suggestionsHitsInteractor?.numberOfHits() ?? 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 .suggestions:
return 44
case .hits:
return 100
}
}
}
}