Ответ 1
Настройка
extendedLayoutIncludesOpaqueBars = true
в UIViewController
, используемом для отображения результатов поиска, исправил проблему для меня.
Когда я запускаю приложение на iOS 13 beta 6 и Xcode 11 beta 5, я сталкиваюсь со странным пробелом при представлении контроллера представления результатов поиска:
Здесь немного о том, как это настроить:
let searchResultsController = BLSearchResultsController()
let ret = UISearchController(searchResultsController: searchResultsController)
ret.searchResultsUpdater = self
ret.delegate = self
ret.searchBar.delegate = self;
ret.searchBar.autocapitalizationType = .none
ret.searchBar.placeholder = NSLocalizedString("SearchMsg", comment: "")
ret.searchBar.enablesReturnKeyAutomatically = true
if #available(iOS 13.0, *) {
ret.searchBar.showsScopeBar = false
ret.searchBar.backgroundColor = .white
let searchTextField = ret.searchBar.searchTextField
searchTextField.font = UIFont.tuttiRegularFont(16)
searchTextField.accessibilityIdentifier = "Main Search Field"
if let searchImageView = searchTextField.leftView as? UIImageView {
searchImageView.image = UIImage(named: "home-search-icon")
}
}
Контроллер поиска результатов является обычным UITableViewController
и только что добавлен в navigationItem.searchController
. Там нет причудливого кода презентации. При сборке на последнем живом Xcode и запуске на устройстве iOS 11/12 эта проблема не возникает, что позволяет мне полагать, что некоторые базовые изменения iOS 13 могут вызывать этот сбой.
При отладке иерархии представлений похоже, что контроллер представления результатов не достигает верхней части перемещенной панели поиска.
Я пытался возиться с modalPresentationModes
, пытаясь исключить возможность того, что изменения в презентации могли быть причиной, мне не повезло.
Кто-нибудь сталкивался с этой проблемой, и ей повезло, исправляя ее?
Настройка
extendedLayoutIncludesOpaqueBars = true
в UIViewController
, используемом для отображения результатов поиска, исправил проблему для меня.
У нас возникла та же проблема, и было решено установить Under Opaque Bars (поскольку мы используем непрозрачные бары)
Мы уже проверили Top и Bottom, добавив третий, переместил контроллер результатов поиска в правильное местоположение.
К вашему сведению Я подал отчет об ошибке в Apple - в соответствии с презентацией WWDC, которая описывает недавно переписанный SearchController и некоторые другие обновления пользовательского интерфейса, похоже, что архитектура SearchController была переписана с нуля вверх. Я не могу поверить, что этот пробел, который мы наблюдаем, является ожидаемым поведением - я потратил большую часть двух дней, пытаясь обойти это, и я больше не буду беспокоиться - приложение моего магазина приложений Это бесплатное приложение, которое имеет несколько пользователей, и я не смог посвятить время отслеживанию изменений/поведения в API во время бета-тестирования. Я немного устал от того, что Apple делает подобные вещи ежегодно.
extendedLayoutIncludesOpaqueBars = true
в некоторой степени помог.
Наряду с этим мне пришлось обновить
navigationController?.navigationBar.prefersLargeTitles = false
когда мы начинаем поиск и устанавливаем его обратно в true
, когда строка поиска закрывается.
Вы должны установить для вашего navigationBar.standardAppearance объект UINavigationBarAppearance, описывающий белый фон.
if #available(iOS 13.0, *) {
let appearance = UINavigationBarAppearance()
appearance.backgroundColor = .white
self.navigationController?.navigationBar.standardAppearance = appearance
}
Наконец пройти через жесткий Просто чтобы первый контроллер содержал UISearchController, чтобы иметь полупрозрачную панель навигации. Работай для меня отлично!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.isTranslucent = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.isTranslucent = false
}
Я наконец решил эту проблему, заменив UISearchController на простой (r) UISearchBar.
Возможно, это не тот ответ, который вы хотели услышать, но UISsearchController уже был беспорядок на iOS12, тот же код на iOS13 работает, но дает ужасные артефакты пользовательского интерфейса. Например, исчезновение или перекрытие панели поиска с заголовком, пробел между строкой поиска и первым элементом таблицы или скрытие первого элемента списка под кнопками области действия... Все разные проблемы между iOS12 и 13, но никогда не выглядят хорошо.
So overall я spent 6 hours trying to fix the searchcontroller, failed, then spent 30 mins migrating to the Searchbar.
В общем, я потратил 6 часов, пытаясь починить контроллер поиска, потерпел неудачу, а затем потратил 30 минут на миграцию на панель поиска. Я добавил UISearchBar, просто используя Interface Builder в Xcode10.3. Для рефакторинга в основном мне пришлось просто заменить searchController.searchBar.xx на searchBar.xx. Основное усилие было переопределить UISeachBarDelegates. Просто чтобы показывать только кнопки и кнопки отмены, пока пользователь выполняет поиск, и удалять их потом. Код ниже дает хороший обзор того, что я сделал:
class MasterViewController: UITableViewController, NSFetchedResultsControllerDelegate {
var fetchedItemsController: NSFetchedResultsController<Item>! = NSFetchedResultsController()
@IBOutlet weak var searchBar: UISearchBar! //hooked up to IB
//GONE IS: let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
initializeFetchedResultsControllerForItems()
//Enable search controller
searchBar.scopeButtonTitles = [NSLocalizedString("Name", comment: ""),
NSLocalizedString("Birthdate", comment: ""),
NSLocalizedString("Employer", comment: "") ]
searchBar.placeholder = NSLocalizedString("Search", comment: "")
searchBar.delegate = self
searchBar.showsScopeBar = false
searchBar.showsCancelButton = false
tableView.contentInsetAdjustmentBehavior = .automatic
self.tableView.tableHeaderView = searchBar //add the searchbar as tableheader view
self.initializeFetchedResultsControllerForItems()
}
// MARK: - Data loading from CoreData
private func initializeFetchedResultsControllerForItems(searchText: String = "", scopeIndex: Int = 0) {
//print("FETCH RESULTS WITH FILTER: \(searchText) en SCOPE: \(scopeIndex)")
//Do whatever searches you need to do to update the FetchedResultsController
//..
self.tableView.reloadData()
}
}
extension MasterViewController: UISearchBarDelegate { //the delegates for the searchbar
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchBar.showsScopeBar = true //show the scopebar when users adds text to searchbar
searchBar.showsCancelButton = true //also show the cancel button
searchBar.sizeToFit()
self.tableView.reloadData() //since the scopebar is there, the table needs to move a bit down
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
initializeFetchedResultsControllerForItems(searchText: searchBar.text!, scopeIndex: searchBar.selectedScopeButtonIndex)
}
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
switch (selectedScope) {
case 0: searchBar.placeholder = NSLocalizedString("Seach on name", comment: "")
case 1: searchBar.placeholder = NSLocalizedString("Search on birthdate", comment: "")
case 2: searchBar.placeholder = NSLocalizedString("Search on employer", comment: "")
default: searchBar.placeholder = NSLocalizedString("Search", comment: "")
searchBar.showsScopeBar = true
searchBar.sizeToFit()
}
initializeFetchedResultsControllerForItems(searchText: searchBar.text!, scopeIndex: selectedScope)
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.placeholder = NSLocalizedString("Search", comment: "")
searchBar.showsScopeBar = false
searchBar.showsCancelButton = false
searchBar.endEditing(true)
searchBar.text = ""
searchBar.sizeToFit()
initializeFetchedResultsControllerForItems(searchText: searchBar.text!, scopeIndex: searchBar.selectedScopeButtonIndex)
}
}
- (void)willPresentSearchController:(UISearchController *)searchController
{
if (@available(iOS 13.0, *))
{
self.navigationController.navigationBar.translucent = YES;
}
}
- (void)willDismissSearchController:(UISearchController *)searchController
{
if (@available(iOS 13.0, *))
{
self.navigationController.navigationBar.translucent = NO;
}
}
Просто принесу мое решение. В моем случае:
edgesForExtendedLayout = .all
на UIViewController, который содержит UISearchController работал.
//MARK: - Properties
var presenter: ExplorePresenting?
var searchController: UISearchController?
var searchUpdater: SearchUpdating?
//MARK: - Lifecycle methods
public override func viewDidLoad() {
super.viewDidLoad()
headerTitle = "explore".localised
tableView.allowsSelection = false
registerCell(cellClass: ExploreTableViewCell.self, with: tableView)
if let searchController = searchController {
searchController.searchBar.delegate = self
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "explore_search_placeholder".localised
definesPresentationContext = true
navigationItem.hidesSearchBarWhenScrolling = false
navigationItem.searchController = searchController
edgesForExtendedLayout = .all
}
presenter?.viewReady()
}