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

# Customize existing widgets

> Learn how you can customize an existing InstantSearch iOS widget.

<Info>
  Starting May 1, 2024,
  Apple requires all iOS apps to include a privacy manifest.
  For more information, see [Privacy manifest](/doc/guides/building-search-ui/resources/privacy-manifest/ios/).
</Info>

With InstantSearch iOS, you are in control of every widget's UI.
Each widget is represented by a protocol, for which Algolia provides 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 the text content type of a `UISearchBar` embedded in the `SearchBarController`:

```swift Swift icon=code theme={"system"}
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

If you want to **replace the existing behavior** of a default implementation,
implement your own `Controller`.

### Example

Here is a custom search box controller that uses `UITextView` as the input field:

```swift Swift icon=code theme={"system"}
public class TextFieldController: NSObject, SearchBoxController {
 
  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)
  }
}
```
