Показать UISearchController SearchResultsController на SearchBar Tap
Я использую UISearchController, а не UISearchDisplayController, и я хочу сразу показать SearchResultController на SearchBar Tap. Сейчас это выглядит так (когда я нажимаю на строку поиска):
![x4eTZ.png]()
Ответы
Ответ 1
Когда результаты пусты, UISearchController
viewController
по-прежнему скрыт. Вот почему мы должны крутить нас, используя UISearchControllerDelegate
willPresentSearchController:
После инициализации self.searchController
сделайте ваш ViewController совместимым с `UISearchControllerDelegate:
self.searchController.delegate = self;
Внесите willPresentSearchController:
в ViewController:
- (void)willPresentSearchController:(UISearchController *)searchController
{
dispatch_async(dispatch_get_main_queue(), ^{
searchController.searchResultsController.view.hidden = NO;
});
}
Асинхронная отправка необходима, поскольку в противном случае она будет переопределена внутренним поведением. Вы могли бы придумать здесь и использовать анимацию, чтобы увидеть, как выглядит таблица.
Кроме того, используйте didPresentSearchController:
для удобства:
- (void)didPresentSearchController:(UISearchController *)searchController
{
searchController.searchResultsController.view.hidden = NO;
}
Ответ 2
Я обнаружил, что другие ответы мерцали из-за использования dispatch_async
. Они использовали это, чтобы их изменения применялись после того, как внутреннее поведение контроллера поиска было завершено, но это оставляет пару кадров, где внутреннее поведение применяется до того, как оно будет переопределено. Использование KVO позволило мне сразу переопределить внутреннее поведение без каких-либо мерцаний.
Я также обнаружил, что другие ответы не отображали видимость контроллера результатов поиска, когда пользователь нажал кнопку ⓧ, чтобы очистить содержимое панели поиска, что кажется мне неправильным.
- (void) viewDidLoad
{
...
self.searchController.delegate = self;
[self.searchController.searchResultsController.view addObserver:self forKeyPath:@"hidden" options:0 context:NULL];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ( object == self.searchController.searchResultsController.view &&
[keyPath isEqualToString:@"hidden"] &&
self.searchController.searchResultsController.view.hidden &&
self.searchController.searchBar.isFirstResponder )
{
self.searchController.searchResultsController.view.hidden = NO;
}
}
- (void) willPresentSearchController:(UISearchController *)searchController
{
searchController.searchResultsController.view.hidden = NO;
}
- (void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if ( searchText.length == 0 )
self.searchController.searchResultsController.view.hidden = NO;
}
- (void) searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
self.searchController.searchResultsController.view.hidden = YES;
}
Ответ 3
Ответ Криса Васселли - самый чистый способ реализовать это.
Здесь он находится в Swift 3
override func viewDidLoad() {
super.viewDidLoad()
searchController.delegate = self
self.searchController.searchResultsController?.view.addObserver(self, forKeyPath: "hidden", options: [], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if let someView: UIView = object as! UIView? {
if (someView == self.searchController.searchResultsController?.view &&
(keyPath == "hidden") &&
(searchController.searchResultsController?.view.isHidden)! &&
searchController.searchBar.isFirstResponder) {
searchController.searchResultsController?.view.isHidden = false
}
}
}
func willPresentSearchController(_ searchController: UISearchController) {
searchController.searchResultsController?.view.isHidden = false
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if (searchText.characters.count == 0) {
searchController.searchResultsController?.view.isHidden = false
}
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
searchController.searchResultsController?.view.isHidden = true
}
Ответ 4
Я думаю, что этот метод лучше, будьте осторожны, когда searchBar пуст, а preload tableview снова исчезнет.
UISearchBarDelegate
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.isEmpty {
dispatch_async(dispatch_get_main_queue()) {
self.searchController.searchResultsController?.view.hidden = false
}
}
}
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
dispatch_async(dispatch_get_main_queue()) {
self.searchController.searchResultsController?.view.hidden = false
}
}
UISearchControllerDelegate
func willPresentSearchController(searchController: UISearchController) {
dispatch_async(dispatch_get_main_queue()) {
self.searchController.searchResultsController?.view.hidden = false
}
}