Пользовательская анимация для UISearchController?
Я представляю UISearchController
из моего контроллера, встроенного в контроллер навигации. Появляется анимация по умолчанию, где окно поиска падает сверху вниз на панели навигации:
![введите описание изображения здесь]()
Это не очень хороший UX в моем случае, потому что я представляю поиск, когда пользователь вступает в UITextField
в середине экрана. То, что я хотел бы сделать, это иметь float UITextField
сверху и преобразовать в поле поиска, но я не могу понять, как это сделать.
Это то, что у меня есть:
class PlacesSearchController: UISearchController, UISearchBarDelegate {
convenience init(delegate: PlacesAutocompleteViewControllerDelegate) {
let tableViewController = PlacesAutocompleteContainer(
delegate: delegate
)
self.init(searchResultsController: tableViewController)
self.searchResultsUpdater = tableViewController
self.hidesNavigationBarDuringPresentation = false
self.definesPresentationContext = true
self.searchBar.placeholder = searchBarPlaceholder
}
}
private extension ShowAddressViewController {
@objc func streetAddressTextFieldEditingDidBegin() {
present(placesSearchController, animated: true, completion: nil)
}
}
Фактически вы можете загрузить и запустить пример приложения, которое делает это:
https://expirebox.com/download/a105093cea111da24b310a35179e04dc.html
Вместо поиска, снижающегося сверху, я надеюсь, что текстовое поле выйдет на навигационную панель. То, что Im after - тот же эффект, что и в приложении iOS 11 File:
![введите описание изображения здесь]()
Он имеет текстовое поле в середине экрана, а затем анимируется до панели навигации, когда вы нажимаете на него. В моем случае tho текстовое поле является более низким на экране, а не изначально частью навигационной панели.
Ответы
Ответ 1
UISearchController
UISearchController - это компонент, который очень сложно настроить. Из моего опыта я могу сказать, что лучше использовать его, как без какой-либо радикальной или значительной настройки. В противном случае настройка может привести к беспорядочному коду, глобальным переменным состояния, трюкам выполнения с иерархией UIView и т.д.
Если по-прежнему требуется определенное поведение, лучше реализовать контроллер поиска с нуля или использовать сторонний вариант.
Реализация по умолчанию
Похоже, UISearchController был разработан для использования в паре с UITableView и UISearchBar, установленными в виде заголовка таблицы. Даже примеры и документация официального кода Apple предоставляют такой пример использования (см. UISearchController). Попытка установить UISearchBar где-то еще часто приводит к многочисленным уродливым побочным эффектам с рамкой ракурса, позицией, подергиванием анимаций, изменениями ориентации и т.д.
Начиная с iOS 11, UINavigationItem получил свойство searchController. Это позволяет интегрировать контроллер поиска в ваш навигационный интерфейс, поэтому поиск будет выглядеть точно так же, как iOS Files или приложение App Store iOS. Поведение UISearchController по-прежнему связано с другим компонентом, но я считаю, что это лучше, чем соединение с UITableView все время.
Возможные решения
С моей точки зрения существует несколько возможных решений для вашей проблемы. Я предоставлю их в порядке увеличения усилий, необходимых для реализации:
- Если вы все еще хотите использовать UISearchController, подумайте над его использованием, как без особых настроек. Apple предоставляет пример кода, который демонстрирует, как использовать UISearchController (см. Поиск таблиц с помощью UISearchController).
- Существует несколько сторонних библиотек, которые могут быть более гибкими с большим количеством дополнительных функций. Например: YNSearch, PYSearch. Пожалуйста, посмотрите.
- Наряду с представлением UISearchController вы можете попытаться переместить UITextField с изменением альфа от 1 до 0. Это создаст ощущение, что UITextField плавно трансформируется в UISearchBar. Этот подход описан в статье, которую предоставил Крис Слоуик (см. Комментарий к вашему оригинальному сообщению). Единственное, что я хотел бы улучшить, это анимация с использованием координаторов перехода (см. Пример здесь), это сделает анимацию более плавной с синхронизированным временем. Окончательная реализация также будет намного чище.
- В качестве опции вы можете попробовать создать собственный контроллер поиска, используя только UISearchBar или даже простой UITextField.
- Вы можете подклассифицировать UISearchController и добавить объект UITextField. UISearchController соответствует протоколам UIViewControllerAnimatedTransitioning и UIViewControllerTransitioningDelegate, где UITextFiled можно удалить или добавить вместе с анимацией перехода.
Надеюсь, это поможет.
Обновление:
Я реализовал подход, который я описал в пункте 3. Вот как это работает:
![UISearchController с UITextField]()
Вы можете найти фрагмент кода здесь. Обратите внимание, что это только пример кода, могут быть ситуации, которые не обрабатываются. Проверьте его дважды.
Ответ 2
- Создайте один UIView в XIB. назовите его searchView.
-
Добавьте UIButton внутри над UIView в том же xib и назовите его btnSearch. Как ниже
 ![в вашем сценарии вы добавили текстовое поле, которое не является ментальным]()
-
Контроллер поиска в ViewDidLoad, как показано ниже:
func setupSearchController() {
self.searchController = UISearchController(searchResultsController: nil)
self.searchController.delegate = self
self.searchController.searchBar.delegate = self
definesPresentationContext = true
self.searchController.dimsBackgroundDuringPresentation = false
self.searchController.searchBar.sizeToFit()
searchView.addSubview(self.searchController.searchBar)
self.searchController.searchBar.isHidden = true
self.searchController.searchBar.tintColor = UIColor.white
self.searchController.searchBar.showsCancelButton = false
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).tintColor = session?.makeColor(fromHexString: TYPE_COLOR, alpha: 1.0)
self.searchController.searchBar.isTranslucent = false
self.searchController.searchBar.barTintColor = UIColor(red: 239.0 / 255.0, green: 135.0 / 255.0, blue: 1.0 / 255.0, alpha: 1.0)
}
Этот метод будет автоматически настраивать searchcontroller внутри searchview.
-
Теперь вам нужно просто программно отобразить searchcontroller. добавьте метод щелчка кнопки на шаге 2. Вызовите это ниже имя метода showearchAnimation:
func ShowSeachAnimation() {
searchFrame = searchView.frame (add one global variable "searchFrame" in controller which saves searchView.frame so it will be used when cancel button clicked on search)
self.btnSearch.isHidden = true
var yAxis : CGFloat = 20
if #available(iOS 11 , *) {
yAxis = 8
} else {
yAxis = 20
}
searchView.translatesAutoresizingMaskIntoConstraints = true
searchView.frame = CGRect(x: 0, y: yAxis, width: view.frame.size.width, height: view.frame.size.height - yAxis)
self.searchController.searchBar.isHidden = false
self.searchController.searchBar.becomeFirstResponder()
self.searchController.searchBar.showsCancelButton = true
self.searchBar(self.searchController.searchBar, textDidChange: "")
searchView.layoutIfNeeded()
}
-
Чтобы скрыть панель поиска, добавьте метод поиска поиска с именем "searchbarcancelbuttonclicked" в делегате searchcontroller:
func searchViewHideAnimation() {
self.removeNavigationBar()
self.navigationController?.isNavigationBarHidden = false
self.searchController.searchBar.text = " "
self.searchController.searchBar.isHidden = true
UIView.animate(withDuration: 0.3, animations: {() -> Void in
self.searchView.frame = self.searchFrame!
self.btnSearch.isHidden = false
}, completion: {(_ finished: Bool) -> Void in
self.searchView.layoutIfNeeded()
})
}
Ответ 3
вы можете попробовать использовать https://github.com/Blackjacx/SHSearchBar, который по существу будет вашим текстовым полем. Вы можете добавить ограничения влево, вправо и вверх и отрегулировать верхнее ограничение, когда начнется редактирование текстового поля. В то же время вы скрываете навигационную панель, анимированную и серой, на фоне, используя представление наложения. Таким образом, у вас есть максимальный контроль над анимацией, и это приложение не так сложно, как может показаться.