> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Filter Toggle

> Lets users toggle a specific filter.

```swift Signature theme={"system"}
FilterToggleConnector<Filter: FilterType>(
  filterState: FilterState,
  filter: Filter,
  isSelected: Bool,
  refinementOperator: RefinementOperator,
  groupName:  String?,
  controller: FilterSwitchController<FilterType>
)
```

<Card title="Explore example code" icon="github" href="https://github.com/algolia/instantsearch-ios/tree/master/Examples/Showcase">
  Browse the Filter Toggle example code on GitHub.
</Card>

## About this widget

`Filter Toggle` is a filtering component that displays any kind of [filter](/doc/guides/managing-results/refine-results/filtering), and lets users refine the search results by toggling it on or off.

## Examples

Instantiate a `FilterToggleConnector` and launch an initial search on its [`Searcher`](/doc/api-reference/widgets/instantsearch/ios).

```swift Swift icon=code theme={"system"}
let searcher = HitsSearcher(appID: "YourApplicationID",
                            apiKey: "YourSearchOnlyAPIKey",
                            indexName: "YourIndexName")

let filterState: FilterState = .init()
let filterToggleSwitchController: FilterSwitchController<Filter.Tag> = .init(switch: UISwitch())

let filterToggleConnector = FilterToggleConnector(filterState: filterState,
                                                  filter: "on sale" as Filter.Tag,
                                                  controller: filterToggleSwitchController)

searcher.connectFilterState(filterState)
searcher.search()
```

## Parameters

<ParamField body="filterState" type="FilterState" required>
  The [`FilterState`](/doc/api-reference/widgets/filter-state/ios) that holds your filters.
</ParamField>

<ParamField body="filter" type="Filter" required>
  The Filter to toggle.
</ParamField>

<ParamField body="interactor" type="SelectableInteractor<Filter>" post={["default: .init()"]} required>
  The logic applied to Filter Toggle.
</ParamField>

<ParamField body="isSelected" type="Bool" required>
  Whether the filter is initially selected.
</ParamField>

<ParamField body="refinementOperator" type="RefinementOperator" post={["default: .and"]}>
  Whether the filter is added to a conjuncitve(`and`) or a disjuncitve (`or`) group in the filter state.
</ParamField>

<ParamField body="groupName" type="String" post={["default: nil"]}>
  Defines the group name in which filter will be placed in `FilterState`.
  If not specified, the name of the filter attribute will be used as a group name.
</ParamField>

<ParamField body="controller" type="CurrentFiltersController" post={["default: nil"]}>
  The Controller interfacing with a concrete toggle filter view.
</ParamField>

## Low-level API

If you want to fully control the `Filter Toggle` components and connect them manually, use the following components:

```swift Swift icon=code theme={"system"}
let searcher = HitsSearcher(appID: "YourApplicationID",
                            apiKey: "YourSearchOnlyAPIKey",
                            indexName: "YourIndexName")
let filterState: FilterState = .init()
let filter: Filter.Tag = "on sale"
let filterToggleSwitchController: FilterSwitchController<Filter.Tag> = .init(switch: UISwitch())
let onSaleFilterInteractor: SelectableInteractor<Filter.Tag> = .init(item: filter)

searcher.connectFilterState(filterState)
onSaleFilterInteractor.connectFilterState(filterState)
onSaleFilterInteractor.connectController(filterToggleSwitchController)
searcher.search()
```

## Customizing your view

The default controllers, such as `FilterSwitchController`,
work well when you want to use native UIKit with their default behavior.

If you want to use another component such as a `UIButton`,
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 `SelectableController` protocol.

### Protocol

`var onClick: ((Bool) -> Void)?`:

Closure to call when a filter is toggled.

`func setSelected(_ isSelected: Bool)`

Function called when a selection state of filter is updated. This is the UI State of the toggle. Make sure to update your view here when you get the new selection state.

### Example

```swift Swift icon=code theme={"system"}
public class FilterSwitchController<F: FilterType>: SelectableController {

  public typealias Item = F

  public let `switch`: UISwitch

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

  public init(`switch`: UISwitch) {
    self.switch = `switch`
    `switch`.addTarget(self, action: #selector(didToggleSwitch), for: .valueChanged)
  }

  @objc func didToggleSwitch(_ switch: UISwitch) {
    onClick?(`switch`.isOn)
  }

  public func setSelected(_ isSelected: Bool) {
    self.switch.isOn = isSelected
  }

  public func setItem(_ item: F) {

  }

}
```

### SwiftUI

InstantSearch provides the `FilterToggleObservableController` data model,
which is an implementation of the `SelectableController` protocol adapted for usage with SwiftUI.
`FilterToggleObservableController` must be connected to the `FilterToggleConnector` or `SelectableInteractor<Filter>` like any other `SelectableController` implementation.

The example of the toggle filter view using the `Toggle` component provided by SwiftUI.

```swift Swift icon=code theme={"system"}
struct ContentView: View {

  @ObservedObject var toggleController: FilterToggleObservableController<Filter.Tag>

  var body: some View {
    Toggle(toggleController.filter?.description ?? "No filter",
           isOn: $toggleController.isSelected).padding()
  }

}
```

If you prefer to create a custom filter toggle SwiftUI view,
you can directly use the `FilterToggleObservableController` as a data model.
It provides `filter` and `isSelected` properties to streamline the design process of your custom SwiftUI view.
