
For my case, there is no absolute necessary for cancel button. But, search cancelling when tapping outside of search controller feels broken.
In our app, there is some sheets presented during search to add filters.
When any action is performed in the screen, that does not overlays Search Controller, search is getting cancelled.
In the sample code, the right button does not perform its action on first tap, instead it dismisses the search controller.
It would be better If I have better control over when search should cancel.
Sample code:
import UIKit
import SwiftUI
class BaseSplitViewController: UISplitViewController { // Window root view controller
init() {
super.init(style: .tripleColumn)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
self.viewControllers = [
UIViewController(),
ContentViewController(),
UIViewController(),
]
}
}
class ContentViewController: UIViewController {
lazy var searchResultsController = SearchResultsViewController()
lazy var searchController = {
let searchController = UISearchController(searchResultsController: searchResultsController)
searchController.showsSearchResultsController = true
return searchController
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemYellow
configureNavigationBar()
}
private func configureNavigationBar() {
navigationItem.title = "Test Title"
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .always
navigationItem.searchController = searchController
}
}
class SearchResultsViewController: UIViewController {
weak var searchController: UISearchController?
lazy var showSheetButton: UIButton = {
let button = UIButton()
button.setTitleColor(.label, for: .normal)
button.setTitle("Show Sheet", for: .normal)
button.addTarget(self, action: #selector(showSheetButtonTapped), for: .touchUpInside)
return button
}()
@objc func showSheetButtonTapped() {
searchController?.isActive = false
present(UINavigationController(rootViewController: TestViewController()), animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemGreen
configureSubviews()
}
private func configureSubviews() {
view.addSubview(showSheetButton)
showSheetButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
showSheetButton.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor),
showSheetButton.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor, constant: -20),
])
}
}
class TestViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBlue
let leftDoneButton = UIBarButtonItem(title: "Left", image: nil, target: self, action: #selector(didTapLeftButton))
leftDoneButton.tintColor = .label
navigationItem.leftBarButtonItem = leftDoneButton
let rightDoneButton = UIBarButtonItem(title: "Right", image: nil, target: self, action: #selector(didTapRightButton))
rightDoneButton.tintColor = .label
navigationItem.rightBarButtonItem = rightDoneButton
}
@objc func didTapLeftButton() {
print("Left button tapped")
}
@objc func didTapRightButton() {
print("Right button tapped")
}
}