API Reference / iOS InstantSearch Widgets / RefinementList
Apr. 24, 2019

RefinementList

About this widget

The RefinementList is a filtering widget made to display facets and let the user refine the search results. There are two RefinementList widget in InstantSearch:

  • RefinementTableWidget built over a UITableView.
  • RefinementCollectionWidget built over a UICollectionView.

Examples

1
2
3
4
5
6
  var tableView = RefinementTableWidget(frame: CGRect.zero, style: .grouped)
  tableView.attribute = "brand"
  tableView.operator = "or"
  tableView.limit = 10
  tableView.isRefined = true
  tableView.sortBy = "count:desc"

Parameters

attribute
type: string
default:
Required

The faceted attribute used by the widget.

1
refinementWidget.attribute = "brand"
operator
type: string
default: or
Optional

Can either be "or" or "and", to control if the results should match any selected value or all selected values.

1
refinementWidget.operator = "or"
limit
type: UInt
default: 10
Optional

The maximum amount of facet values to display. If there are more values, displays those with the biggest count.

1
refinementWidget.limit = 12
isRefined
type: Bool
default: true
Optional

Whether the refined values are displayed first or not.

1
refinementWidget.isRefined = true
sortBy
type: String
default: count:desc
Optional

The sort order of the attributes. This attribute accepts the following values:

  • count:asc to sort the facets by ascending count.
  • count:desc to sort the facets by descending count.
  • name:asc to sort the facet values by alphabetical order.
  • name:desc to sort the facet values by reverse alphabetical order.
1
refinementWidget.sortBy = "count:desc"

Layout and Content

Delegate and DataSource

InstantSearch provides two ways to handle the Delegate and DataSource of a RefinementList widget:

ViewController Inheritance

  • Have your ViewController inherit from RefinementTableViewController or RefinementCollectionViewController.
  • In viewDidLoad, assign refinementTableView to your refinement widget, whether it was created programmatically or through Interface Builder.
  • At the end of ViewDidLoad, call InstantSearch.shared.registerAllWidgets(in:) to add your widget to InstantSearch.
  • To specify the look and feel of your cell, override one of the two methods:
    • tableView(_:cellForRowAt:containing:with:is:)
    • collectionView(_:cellForItemAt:containing:with:is:) -> UICollectionViewCell
  • Optional: To specify what happens when a refinement is selected, override one of these two methods:
    • tableView(_:didSelectRowAt:containing:with:is:)
    • collectionView(_:didSelectItemAt:containing:with:is:)
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
import InstantSearch

class RefinementTableViewControllerDemo: RefinementTableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        refinementTableView = RefinementTableWidget()
        refinementTableView.attribute = "category"
        refinementTableView.frame = self.view.frame

        self.view.addSubview(refinementTableView)
        InstantSearch.shared.registerAllWidgets(in: self.view)

    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath, containing facet: String, with count: Int, is refined: Bool) -> UITableViewCell {
        var cell = refinementTableView.dequeueReusableCell(withIdentifier: "refinementCell")

        if cell == nil {
            cell = UITableViewCell(style: .subtitle, reuseIdentifier: "refinementCell")
        }

        cell!.textLabel?.text = facet
        cell!.detailTextLabel?.text = String(count)
        cell!.accessoryType = refined ? .checkmark : .none

        return cell!
    }
}

ViewController Composition

With this method, your ViewController owns a RefinementController object.

The RefinementController provides tableDataSource and tableDelegate properties for the RefinementTableWidget, as well as collectionDataSource and collectionDelegate for the RefinementCollectionWidget.

The protocols to implement are:

  • RefinementTableViewDataSource: specifiy the rendering of the table refinement cells.
  • RefinementTableViewDelegate: specifiy what happens when table refinement cell is clicked.
  • RefinementCollectionViewDataSource: specifiy the rendering of the collection refinement cells.
  • RefinementCollectionViewDelegate: specifiy what happens when collection refinement cell is clicked.
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
import InstantSearch

class RefinementTableViewDataSourceDemo: UIViewController, RefinementTableViewDataSource {

    var instantSearch: InstantSearch!
    @IBOutlet weak var refinementList: RefinementTableWidget!

    var refinementController: RefinementController!

    override func viewDidLoad() {
        refinementController = RefinementController(table: refinementList)
        refinementList.dataSource = refinementController
        refinementList.delegate = refinementController
        refinementController.tableDataSource = self
        // refinementController.tableDelegate = self

        instantSearch = InstantSearch.shared
        instantSearch.register(widget: refinementList)
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath, containing facet: String, with count: Int, is refined: Bool) -> UITableViewCell {
        let cell = refinementList.dequeueReusableCell(withIdentifier: "facetCell", for: indexPath)

        cell.textLabel?.text = facet
        cell.detailTextLabel?.text = String(count)
        cell.accessoryType = refined ? .checkmark : .none

        return cell
    }
}

RefinementMenuViewModel

You can use this to customize any kind of refinement list view.

Methods

  • numberOfRows()
  • facetForRow(at:)
  • isRefined(at:)
  • didSelectRow(at:)

Did you find this page helpful?