Guides / Building Search UI / Widgets

Customize an Existing Widget

With InstantSearch iOS, you are in control of every widget’s UI. Each widget is represented by a protocol, for which we provide default implementations. If these implementations don’t fit your purpose, you can either customize the existing implementation, or create your own.

Customize the existing implementation

All InstantSearch widgets are built through composition. This enables you to adapt the underlying Controller and add the behavior you want on top of the existing implementation.

For example, here’s how you can set text content type of a UISearchBar embedded in the SearchBarController:

1
2
3
  let searchBarController = SearchBarController(searchBar: UISearchBar())
  // if your project targets iOS 13+, we recommend to use TextFieldController(searchBar: UISearchBar())
  searchBarController.searchBar.textContentType = .countryName

Implement your own Controller

When you want to replace the existing behavior of a default implementation, you should implement your own Controller.

Example

Here is a custom query input controller that uses UITextView as the input field.

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
public class TextFieldController: NSObject, QueryInputController {
  
  public var onQueryChanged: ((String?) -> Void)?
  public var onQuerySubmitted: ((String?) -> Void)?
  
  public let textField: UITextField
  
  public init(textField: UITextField) {
    self.textField = textField
    super.init()
    setupTextField()
  }
  
  public func setQuery(_ query: String?) {
    textField.text = query
  }
  
  private func setupTextField() {
    textField.returnKeyType = .search
    textField.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged)
    textField.addTarget(self, action: #selector(textFieldDidReturn), for: .editingDidEndOnExit)
  }
  
  @objc private func textFieldDidChange() {
    onQueryChanged?(textField.text)
  }
  
  @objc private func textFieldDidReturn() {
    textField.resignFirstResponder()
    onQuerySubmitted?(textField.text)
  }
  
}

Did you find this page helpful?