API Reference / InstantSearch iOS Widgets / Sort By
Widget signature
SortByConnector(
  searcher: SingleIndexSearcher,
  indices: [Index],
  selected: Int?,
  controller: SelectableSegmentController,
  presenter: Presenter
)

About this widget

SortBy displays a list of indices, allowing a user to change the way hits are sorted (using replica indices). Another common use case is to let the user switch between different indices to show different results.

For this to work, you must define all indices that you pass to SortBy as replicas of the main index.

Examples

Instantiate a SortByConnector.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let searcher: SingleIndexSearcher = .init(appID: "YourApplicationID",
                                          apiKey: "YourSearchOnlyAPIKey",
                                          indexName: "indexDefault")
let alertController = UIAlertController(title: "Change Index",
                                        message: "Please select a new index",
                                        preferredStyle: .actionSheet)
let selectIndexController: SelectIndexController = .init(alertController: alertController)
let sortByConnector: SortByConnector = .init(searcher: searcher,
                                             indicesNames: ["indexDefault",
                                                            "indexAscendingOrder",
                                                            "indexDescendingOrder"],
                                             selected: 0,
                                             controller: selectIndexController) { index -> String in
  switch index.name {
  case "indexDefault": return "Default"
  case "indexAscendingOrder": return "Year Asc"
  case "indexDescendingOrder": return "Year Desc"
  default: return index.name.rawValue
  }
}

Parameters

searcher
type: SingleIndexSearcher
Required

The Searcher that handles your searches.

interactor
type: FilterClearInteractor
default: .init()
Required

The logic applied to SortBy.

indices
type: [Index]
Required

The list of indices to search in.

selected
type: Int?
Optional

The consecutive index of the initially selected search index in the list.

controller
type: SelectableSegmentController
default: nil
Optional

Controller interfacing with a concrete switch index view.

presenter
type: Presenter
default: nil
Optional

The Presenter defining how the indices appear in the controller.

Presenter

Index Presenter
type: IndexPresenter
Optional

The presenter that defines the way we want to display an index, taking as input an Index and returning a String.

1
2
3
public static let present: IndexPresenter = { index in
  return index.name
}

Low-level API

If you want to fully control the SortBy components and connect them manually, you can use the following components:

  • Searcher: The Searcher that handles your searches.
  • IndexSegmentInteractor: The logic applied to the index sorting/switching.
  • SelectableSegmentController: The controller that interfaces with a concrete index list.
  • IndexPresenter: Optional. The presenter that converts an Index to a String output.
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
let searcher: SingleIndexSearcher = .init(appID: "YourApplicationID",
                                          apiKey: "YourSearchOnlyAPIKey",
                                          indexName: "indexDefault")

let indexDefault = searcher.client.index(withName: "indexDefault")
let indexAscendingOrder = searcher.client.index(withName: "indexAscendingOrder")
let indexDescendingOrder = searcher.client.index(withName: "indexDescendingOrder")
let alertController = UIAlertController(title: "Change Index",
                                        message: "Please select a new index",
                                        preferredStyle: .actionSheet)
let selectIndexController: SelectIndexController = .init(alertController: alertController)

let indexSegmentInteractor: IndexSegmentInteractor = .init(items: [
    0 : indexDefault,
    1 : indexAscendingOrder,
    2 : indexDescendingOrder
])

indexSegmentInteractor.connectSearcher(searcher: searcher)

indexSegmentInteractor.connectController(selectIndexController) { index -> String in
  switch index.name {
  case "indexDefault": return "Default"
  case "indexAscendingOrder": return "Year Asc"
  case "indexDescendingOrder": return "Year Desc"
  default: return index.name.rawValue
  }
}

Customizing your view

The controllers provided by default, like the SelectIndexController work well when you want to use native UIKit with their default behavior like a UIAlertController.

If you want to use another component, 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 SelectableSegmentController protocol.

Protocol

func setSelected(_ selected: Int?):

Function called when an index is selected, with the position that is selected.

func setItems(items: [Int: String])

Function called when a new array of indices is defined.

func reload()

Function called when we require a reload of the list view.

var onClick: ((Int) -> Void)?:

Closure to call when a new index is clicked.

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
public class SelectIndexController: NSObject, SelectableSegmentController {

  let alertController: UIAlertController

  public var onClick: ((Int) -> Void)?

  public init(alertController: UIAlertController) {
    self.alertController = alertController
    super.init()
  }

  public func setSelected(_ selected: Int?) {
    // Show a check mark next to the item selected here
  }

  public func setItems(items: [Int: String]) {
    guard alertController.actions.isEmpty else { return }
    for item in items {
      alertController.addAction(UIAlertAction(title: item.value, style: .default, handler: { [weak self] _ in
        self?.onClick?(item.key)
      }))
    }
    alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: .none))
  }

}

Did you find this page helpful?