#swift #uinavigationbar #uisearchbar
#swift #uinavigationbar #панель пользовательского поиска
Вопрос:
Я создаю базовый ViewController, содержащий CollectionViewController с несколькими разделами. Я хотел бы, чтобы панель пользовательского поиска содержалась на панели навигации, но, похоже, Swift допускает только два варианта поведения: сначала скрыть панель поиска, а затем показать ее, как только пользователь прокрутит вниз, или всегда показывать панель поиска.
Я бы хотел, чтобы панель поиска функционировала так же, как, скажем, в приложении «Сообщения», где она появляется без необходимости прокрутки пользователем, а затем скрывается при прокрутке пользователем страницы вниз. Я уверен, что для этого есть простое решение, но я довольно новичок в разработке iOS и не смог найти какие-либо ранее задаваемые вопросы по этому поводу.
Пример того, как это выглядит, когда панель поиска присутствует всегда:
Пример того, как это выглядит, когда пользователь должен прокрутить вниз, чтобы появилась панель поиска:
Инициализация контроллера и панели поиска:
let searchController = UISearchController(searchResultsController: nil)
let searchBar: UISearchBar = {
let search = UISearchBar()
search.placeholder = "Search"
search.translatesAutoresizingMaskIntoConstraints = false
search.sizeToFit()
search.barStyle = .default
return search
}()
// Truncated...
// Called from viewDidLoad()
func configureSearchBar() {
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search"
searchController.searchBar.translatesAutoresizingMaskIntoConstraints = false
searchController.isActive = true
definesPresentationContext = true
navigationItem.title = "Test Title"
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
}
Я знаю, что этот код не приведет к ожидаемому поведению, но есть ли простая модификация, которую я мог бы внести, чтобы она вела себя должным образом?
Комментарии:
1. » приложение «Сообщения», где оно появляется без необходимости прокрутки пользователем, «, ну, когда вы просто запускаете приложение «Сообщения», оно не отображает поле поиска по умолчанию и отображается только при прокрутке вверх, когда вы находитесь наверху
2. Ну, почему бы вам не установить первую ячейку вашего пользовательского CollectionView в качестве строки поиска, таким образом, всякий раз, когда загружается CollectionView, строка поиска всегда будет присутствовать вверху, и при прокрутке она будет скрыта, а затем, когда вы снова прокрутите до верха, она будет видна . Но это, похоже, не является частью панели навигации
Ответ №1:
Я нашел способ изначально отобразить панель пользовательского поиска. На данный момент я не совсем уверен, предназначено ли это Apple или это просто еще один взлом, чтобы заставить простое поведение работать.
В viewDidLoad
после настройки вашего UISearchController
вызова:
present(searchController, animated: true)
Затем это оживит и расширит панель навигации и покажет панель поиска. Не забудьте снова отключить ее, когда закончите редактировать текст внутри панели. Это необходимо сделать, даже если вы изначально скрываете панель поиска, потому что в противном случае она будет сохранена, и в итоге произойдет утечка.
Редактировать: Чтобы ответить на остальную часть вашего вопроса, я предоставил некоторый демонстрационный код, чтобы донести идею:
Вы можете наблюдать за contentOffset и отклонять его, когда оно принимает определенное значение:
observable = self.viewDictionary.tableView.observe(.contentOffset) { [unowned self] value in
guard let offset = value else { return }
if offset.y > 30 {
self.navigationItem.searchController?.dismiss(animated: true)
}
}
Код observer использует простое расширение, найденное и объясненное здесь, но использование стандартной версии библиотеки также работает.
Ответ №2:
Установите hidesSearchBarWhenScrolling = true
в viewDidLoad()
Установите для параметра contentOffset для просмотра прокрутки значение, обратное высоте панели поиска в viewWillAppear().
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let offset = -(searchController.searchBar.frame.height)
tableView.setContentOffset(CGPoint(x: 0, y: offset), animated: false)
}
Ответ №3:
Сделайте подобное в viewDidLoad
navigationItem.hidesSearchBarWhenScrolling = false
DispatchQueue.main.async {
self.navigationItem.hidesSearchBarWhenScrolling = true
}
Ответ №4:
Лучший способ — использовать возможности UISearchController без использования вашего ScrollView.
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.hidesSearchBarWhenScrolling = false
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.navigationItem.hidesSearchBarWhenScrolling = true
}