-
Notifications
You must be signed in to change notification settings - Fork 60
/
Copy pathMultiIndex.SearchResultsController.swift
133 lines (116 loc) · 4.24 KB
/
MultiIndex.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
// Examples
//
// Created by Vladislav Fitc on 05/11/2021.
//
import Foundation
import InstantSearch
import UIKit
extension MultiIndex {
class SearchResultsController: UITableViewController {
enum Section: Int, CaseIterable {
case actors
case movies
var title: String {
switch self {
case .actors:
return "Actors"
case .movies:
return "Movies"
}
}
var image: UIImage? {
switch self {
case .movies:
return UIImage(systemName: "film")
case .actors:
return UIImage(systemName: "person.circle")
}
}
init?(section: Int) {
self.init(rawValue: section)
}
init?(indexPath: IndexPath) {
self.init(section: indexPath.section)
}
}
let cellReuseIdentifier = "cellID"
func numberOfHits(in section: Section) -> Int {
switch section {
case .actors:
return actorsHitsInteractor?.numberOfHits() ?? 0
case .movies:
return moviesHitsInteractor?.numberOfHits() ?? 0
}
}
func cellLabel(forRowIndex rowIndex: Int, at section: Section) -> NSAttributedString? {
switch section {
case .actors:
return actorsHitsInteractor?.hit(atIndex: rowIndex)?.hightlightedString(forKey: "name").map { highlightedString in
NSAttributedString(highlightedString: highlightedString, attributes: [.font: UIFont.systemFont(ofSize: 17, weight: .bold)])
}
case .movies:
return moviesHitsInteractor?.hit(atIndex: rowIndex)?.hightlightedString(forKey: "title").map { highlightedString in
NSAttributedString(highlightedString: highlightedString, attributes: [.font: UIFont.systemFont(ofSize: 17, weight: .bold)])
}
}
}
weak var actorsHitsInteractor: HitsInteractor<Hit<Actor>>? {
didSet {
oldValue?.onResultsUpdated.cancelSubscription(for: tableView)
guard let interactor = actorsHitsInteractor else { return }
interactor.onResultsUpdated.subscribe(with: tableView) { tableView, _ in
tableView.reloadData()
}.onQueue(.main)
}
}
weak var moviesHitsInteractor: HitsInteractor<Hit<Movie>>? {
didSet {
oldValue?.onResultsUpdated.cancelSubscription(for: tableView)
guard let interactor = moviesHitsInteractor else { return }
interactor.onResultsUpdated.subscribe(with: tableView) { tableView, _ in
tableView.reloadData()
}.onQueue(.main)
}
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: 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 }
return numberOfHits(in: section)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath)
guard let section = Section(indexPath: indexPath) else { return cell }
cell.tintColor = .lightGray
cell.imageView?.image = section.image
cell.textLabel?.attributedText = cellLabel(forRowIndex: indexPath.row, at: section)
return cell
}
override func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? {
guard let section = Section(section: section), numberOfHits(in: section) != 0 else { return nil }
return section.title
}
// swiftlint:disable unused_optional_binding
override func tableView(_: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let section = Section(indexPath: indexPath) else { return }
switch section {
case .actors:
if let _ = actorsHitsInteractor?.hit(atIndex: indexPath.row) {
// Handle actor selection
}
case .movies:
if let _ = moviesHitsInteractor?.hit(atIndex: indexPath.row) {
// Handle movie selection
}
}
}
// swiftlint:enable unused_optional_binding
}
}