Я реализовал новый SearchController
с searchBar
и searchResultsController
.
Вот как я его реализовал:
resultViewController:
lazy var resultViewController: SearchResultViewController = {
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let searchResultViewController = storyboard.instantiateViewController(withIdentifier: "SearchResultViewController") as! SearchResultViewController
searchResultViewController.delegate = self
return searchResultViewController
}()
А это SearchController:
lazy var searchController: UISearchController = {
let searchController = UISearchController(searchResultsController: resultViewController)
searchController.searchBar.delegate = self
searchController.obscuresBackgroundDuringPresentation = true
searchController.searchResultsUpdater = self
searchController.searchBar.placeholder = "Search.city.label".localizable()
searchController.searchBar.tintColor = UIColor.white
searchController.searchBar.barTintColor = UIColor.white
UITextField.appearance(whenContainedInInstancesOf: [type(of: searchController.searchBar)]).tintColor = UIColor(red:0.00, green:0.47, blue:0.78, alpha:1.0)
if let textfield = searchController.searchBar.value(forKey: "searchField") as? UITextField {
if let backgroundview = textfield.subviews.first {
// Background color
backgroundview.backgroundColor = UIColor.white
// Rounded corner
backgroundview.layer.cornerRadius = 10;
backgroundview.clipsToBounds = true;
}
}
definesPresentationContext = true
return searchController
}()
В моем viewWillAppear
я установил navigItem.searchController:
self.searchController.isActive = true
if #available(iOS 11.0, *) {
self.navigationItem.searchController = searchController
self.navigationItem.hidesSearchBarWhenScrolling = true
} else {
// Fallback on earlier versions
}
Мне удалось обработать cancelButtonClicked:
extension HomeViewController: UISearchBarDelegate {
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.endEditing(true)
self.searchController.isActive = false
}
}
Это делает анимацию «отмена», скрывая клавиатуру + неактивное состояние на searchBar / searchController.Оба одновременно, с одним нажатием на кнопку отмены.
Но я не могу этого добиться, когда пользователь нажимает в любом месте на экране.
Я пытался с жестом касания, но это требует меня2 нажмите, чтобы добиться того же поведения.
NB:
Я получил UICollectionView в моем UIViewController, который занимает все место в UIView.
Вот что я пробовал:
override func viewDidLoad() {
super.viewDidLoad()
handleTapAnywhereToRemoveKeyboard()
}
func handleTapAnywhereToRemoveKeyboard() {
let singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.singleTap(sender:)))
//singleTapGestureRecognizer.numberOfTapsRequired = 1
singleTapGestureRecognizer.cancelsTouchesInView = false
self.view.addGestureRecognizer(singleTapGestureRecognizer)
}
@objc func singleTap(sender: UITapGestureRecognizer) {
self.searchController.isActive = false
self.searchController.searchBar.resignFirstResponder()
self.searchController.searchBar.endEditing(true)
}
РЕДАКТИРОВАТЬ:
Я думал, может быть, это потому, что мои searchBar и searchController не находятся в иерархии представления UIViewController, но больше в NavigationController one.
Так что я также попытался с:
navigationController?.view.endEditing(true)
Я тогда подумал, может быть, это потому, что UIScrollView в моем UICollectionView ловит нажатие.Поэтому я попытался связать жест касания в UICollectionView вместо UIView, но безуспешно.