API Reference / iOS InstantSearch Widgets / Filter List (Facet)
Apr. 24, 2019

Filter List (Facet)

About this widget

FilterList.Facet is a filtering view that displays any kind of facet filters and lets the user refine the search results by selecting them.

Compared to the RefinementList, which takes its values from the search response facets, this widget displays facet filters that you add yourself.

To add a filter list to your search experience, use these components:

  • Searcher: The Searcher that handles your searches.
  • FilterState: The current state of the filters.
  • FacetFilterListInteractor: The logic applied to the facet filters.
  • FilterListController: The view that will render the facet filters.

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
26
27
28
class FacetFilterListViewController: UIViewController {

  let searcher: SingleIndexSearcher = SingleIndexSearcher(appID: "YourApplicationID",
                                                          apiKey: "YourSearchOnlyAPIKey",
                                                          indexName: "YourIndexName")
  let filterState: FilterState = .init()

  let facetFilters: [Filter.Facet] = ["red", "blue", "green", "yellow", "black"].map {
    .init(attribute: "color", stringValue: $0)
  }

  lazy var filterListInteractor: FacetFilterListInteractor = { .init(items: facetFilters, selectionMode: .multiple) }()

  let filterListController: FilterListTableController<Filter.Facet> = .init(tableView: UITableView())

  override func viewDidLoad() {
    super.viewDidLoad()
    setup()
  }

  func setup() {
    searcher.connectFilterState(filterState)
    filterListInteractor.connectFilterState(filterState, operator: .or)
    filterListInteractor.connect(to: filterListController)
    searcher.search()
  }

}

Parameters

items
type: [Filter.Facet]
default: []
Required

The facet filters to display.

1
FacetFilterListInteractor(items: [Filter.Facet(attribute: "foo", stringValue: "bar")])
operator
type: RefinementOperator
Required

Whether we apply an and or or behavior to the filters in the filterState.

For example if we have an or behavior, the filter sent to Algolia will be _tags:promo OR color:green.

1
filterListInteractor.connectFilterState(filterState, operator: .or)
selectionMode
type: SelectionMode
default: .multiple
Optional

Whether the list can have Single or Multiple selections.

1
FacetFilterListInteractor(items: items, selectionMode: .multiple)

Customize your view

The controllers provided by default, like the FilterListTableController work well when you want to use native UIKit components 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 FacetFilterListController protocol.

Protocol

var onClick: ((Filter.Facet) -> Void)?:

Closure to call when a filter is clicked.

func setSelectableItems(selectableItems: [SelectableItem<Filter.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
class FacetFilterListTableController: NSObject, FacetFilterListController, UITableViewDataSource, UITableViewDelegate {
  
  public var onClick: ((Filter.Facet) -> Void)?
  
  public let tableView: UITableView
  
  public var selectableItems: [SelectableItem<Filter.Facet>] = []
  public var filterPresenter: FilterPresenter?
  
  let cellID: String
  
  public init(tableView: UITableView, cellID: String = "cellID") {
    self.tableView = tableView
    self.cellID = cellID
    super.init()
    tableView.dataSource = self
    tableView.delegate = self
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellID)
  }
  
  // MARK: - FilterListController
  
  public func setSelectableItems(selectableItems: [SelectableItem<Filter.Facet>]) {
    self.selectableItems = selectableItems
  }
  
  public func reload() {
    tableView.reloadData()
  }
  
  // MARK: - UITableViewDataSource
  
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return selectableItems.count
  }
  
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath)
    let filter = selectableItems[indexPath.row]
    let filterPresenter = self.filterPresenter ?? DefaultPresenter.Filter.present
    cell.textLabel?.text = filterPresenter(Filter(filter.item))
    cell.accessoryType = filter.isSelected ? .checkmark : .none
    
    return cell
  }
  
  // MARK: - UITableViewDelegate
  
  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let selectableItem = selectableItems[indexPath.row]
    onClick?(selectableItem.item)
  }
  
}

Did you find this page helpful?