Skip to main content

Custom search box

ViewController
import UIKit
import MapboxSearch

class ContinuousSearchViewController: TextViewLoggerViewController {
let searchEngine = SearchEngine()
let textField = UITextField()
let responseLabel = UILabel()

override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white

textField.borderStyle = .line
textField.addTarget(self, action: #selector(textFieldTextDidChanged), for: .editingChanged)
responseLabel.lineBreakMode = .byTruncatingMiddle

view.addSubview(textField)
view.addSubview(responseLabel)

searchEngine.delegate = self
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

textField.becomeFirstResponder()
}

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()

textField.frame = CGRect(x: 50, y: 100, width: view.bounds.width - 50*2, height: 32)
responseLabel.frame = CGRect(x: 50, y: textField.frame.maxY + 16, width: view.bounds.width - 50*2, height: 32)
}
}

extension ContinuousSearchViewController {
@objc
func textFieldTextDidChanged() {
/// Update `SearchEngine.query` field as fast as you need. `SearchEngine` waits a short amount of time for the query string to optimize network usage.
searchEngine.query = textField.text!
}
}

extension ContinuousSearchViewController: SearchEngineDelegate {
func suggestionsUpdated(suggestions: [SearchSuggestion], searchEngine: SearchEngine) {
dumpSuggestions(suggestions, query: searchEngine.query)
}

func resultResolved(result: SearchResult, searchEngine: SearchEngine) {
print("Dumping resolved result:", dump(result))
}

func searchErrorHappened(searchError: SearchError, searchEngine: SearchEngine) {
print("Error during search: \(searchError)")
}
}
TextViewLoggerViewController
import UIKit
import MapboxSearch

class TextViewLoggerViewController: UIViewController, ExampleController {
let responseTextView = UITextView()

func logUI(_ message: String) {
responseTextView.text = message
}

func dumpSuggestions(_ suggestions: [SearchSuggestion], query: String) {
print("Number of search results: \(suggestions.count) for query: \(query)")
let headerText = "query: \(query), count: \(suggestions.count)"

let suggestionsLog = suggestions.map { suggestion in
var suggestionString = "\(suggestion.name)"
if let description = suggestion.descriptionText {
suggestionString += "\n\tdescription: \(description)"
} else if let address = suggestion.address?.formattedAddress(style: .medium) {
suggestionString += "\n\taddress: \(address)"
}
if let distance = suggestion.distance {
suggestionString += "\n\tdistance: \(Int(distance / 1000)) km"
}
return suggestionString + "\n"
}.joined(separator: "\n")

logUI(headerText + "\n\n" + suggestionsLog)
}

override func viewDidLoad() {
super.viewDidLoad()

responseTextView.isEditable = false
view.addSubview(responseTextView)

addConstraints()
}

func addConstraints() {
let textViewConstraints = [
responseTextView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
responseTextView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
responseTextView.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor),
responseTextView.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor, constant: 60)
]
responseTextView.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate(textViewConstraints)
}
}
Was this example helpful?