About this widget #
RefinementList
is a filtering view that displays facets, and lets the user refine the search results by filtering on specific values.
To add a refinement list to your search experience, use these components:
Searcher
: TheSearcher
that handles your searches.FilterState
: The current state of the filters.FacetListInteractor
: The logic applied to the facets.FacetListController
: The controller that interfaces with a concrete facet list view.FacetListPresenter
: Optional. The presenter that controls the sorting and other settings of the facet list view.
Examples #
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
let searcher: SingleIndexSearcher = SingleIndexSearcher(appID: "AJ0P3S7DWQ",
apiKey: "90dfaaf5755e694f341fe68f6e41a6d4",
indexName: "YourIndexName")
let filterState: FilterState = .init()
let facetListInteractor: FacetListInteractor = .init(selectionMode: .multiple)
let facetListController: FacetListTableViewController = .init(tableView: UITableView())
// let facetListPresenter: FacetListPresenter = .init(sortBy: [.count(order: .descending)], limit: 5, showEmptyFacets: false)
let facetAttribute: Attribute = Attribute("facetName")
override func viewDidLoad() {
super.viewDidLoad()
facetListInteractor.connectSearcher(searcher, with: facetAttribute)
facetListInteractor.connectFilterState(filterState, with: facetAttribute, operator: .or)
facetListInteractor.connectController(facetListController)
//facetListInteractor.connectController(facetListController, with: facetListPresenter)
// Connect searcher to the filter state so that a change in the filter state triggers a new search
searcher.connectFilterState(filterState)
// In case we want to do a search when on empty query
searcher.search()
}
Parameters #
attribute
# |
type: Attribute
Required
The attribute to filter. |
||
Edit
Copy
|
|||
operator
# |
type: RefinementOperator
Required
Whether we apply an For example if we select |
||
Edit
Copy
|
|||
selectionMode
# |
type: SelectionMode
default: .multiple
Optional
Whether the list can have |
||
Edit
Copy
|
Presenter #
sortBy
# |
type: [FacetSortCriterion]
default: [.count(order: .descending)]
Optional
How to sort facets. Must be one or more of the following values:
|
||
Edit
Copy
|
|||
limit
# |
type: Int
default: 10
Optional
The number of facet values to retrieve. |
||
|
|||
showEmptyFacets
# |
type: Bool
default: true
Optional
Whether we show facets that have a facet count of 0. |
||
Edit
Copy
|
Customize your view#
The controllers provided by default, like the FacetListTableViewController
work well when you want to use native UIKit with their default behavior.
If you want to use another component such as a UICollectionView
, a third-party input view, or you want to introduce some custom behavior to the already provided UIKit component, you can create your own controller conforming to the FacetListController
protocol.
Protocol#
var onClick: ((Facet) -> Void)?
:
Closure to call when a new facet is clicked.
func setSelectableItems(selectableItems: [SelectableItem<Facet>])
Function called when a new array of selectable facets is updated. This is the UI State of the refinement list.
func reload()
Function called when we require a reload of the list view.
Example#
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
open class FacetListTableViewController: NSObject, FacetListController {
public var onClick: ((Facet) -> Void)?
public var tableView: UITableView
var selectableItems: [RefinementFacet] = []
var cellID: String
public init(tableView: UITableView, cellID: String = "FacetList") {
self.tableView = tableView
self.cellID = cellID
super.init()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellID)
tableView.dataSource = self
tableView.delegate = self
}
public func setSelectableItems(selectableItems: [RefinementFacet]) {
self.selectableItems = selectableItems
}
public func reload() {
tableView.reloadData()
}
}
extension FacetListTableViewController: UITableViewDataSource {
open func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return selectableItems.count
}
open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath)
let selectableRefinement: RefinementFacet = selectableItems[indexPath.row]
let facetAttributedString = NSMutableAttributedString(string: selectableRefinement.item.value)
let facetCountStringColor = [NSAttributedString.Key.foregroundColor: UIColor.gray, .font: UIFont.systemFont(ofSize: 14)]
let facetCountString = NSAttributedString(string: " (\(selectableRefinement.item.count))", attributes: facetCountStringColor)
facetAttributedString.append(facetCountString)
cell.textLabel?.attributedText = facetAttributedString
cell.accessoryType = selectableRefinement.isSelected ? .checkmark : .none
return cell
}
}
extension FacetListTableViewController: UITableViewDelegate {
open func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectableItem = selectableItems[indexPath.row]
self.onClick?(selectableItem.item)
}
}