У меня есть UITableViewController
, на котором я установил действие смахивания влево, которое поднимает модальный лист страницы с некоторыми деталями, связанными с прокрученной строкой таблицы. Этот лист страницы имеет кнопки «Отмена» и «Сохранить» на панели навигации и настроен как UIAdaptivePresentationControllerDelegate
, так что отмена и сохранение работают так же, как описано в этом видео с WWDC19 и в сопутствующем образце проекта . Он работает точно так, как ожидалось.
Однако, когда я добавил UISearchController
в свое представление таблицы и использовал действие смахивания влево для одного из отфильтрованных результатов, кнопка отмены перестает работать правильно. Мне нужно дважды щелкнуть по нему, чтобы закрыть модальный лист.
В моем UITableViewController
классе:
let searchController = UISearchController(searchResultsController: nil)
И затем в табличном представлении viewDidLoad
:
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search Bookmarks"
searchController.searchBar.autocapitalizationType = .none
navigationItem.searchController = searchController
Действие смахивания влево:
override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .normal, title: "Edit") { (action, view, completionHandler) in
self.selectedRow = indexPath.row
self.performSegue(withIdentifier: "showBookmarkDetail", sender: self)
completionHandler(true)
}
action.image = UIImage(systemName: "pencil")
action.backgroundColor = .green
let config = UISwipeActionsConfiguration(actions: [action])
return config
}
И подготовка перехода:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "showBookmarkDetail":
let navController = segue.destination as! UINavigationController
let bookmarkController = navController.topViewController as! BookmarkDetailViewController
navController.presentationController?.delegate = bookmarkController
bookmarkController.delegate = self
if isFiltering {
bookmarkController.bookmark = filteredBookmarks[selectedRow]
} else {
bookmarkController.bookmark = bookmarks[selectedRow]
}
default:
break
}
}
Одна вещь, которую я пробовал, - это расширить UISearchController
, чтобы соответствовать соответствующему делегату протокол, поэтому он будет вызван для отмены и сохранения на модальном листе (согласно образцу кода Apple), затем я установил его в качестве делегата вместо основного UITableViewController
. Хотя эти методы вызываются правильно, лист никогда не закрывается, независимо от того, сколько раз я нажимаю кнопку.
Вот этот код:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "showBookmarkDetail":
//searchController.dismiss(animated: false)
let navController = segue.destination as! UINavigationController
let bookmarkController = navController.topViewController as! BookmarkDetailViewController
navController.presentationController?.delegate = bookmarkController
if isFiltering {
bookmarkController.bookmark = filteredBookmarks[selectedRow]
bookmarkController.delegate = searchController
} else {
bookmarkController.bookmark = bookmarks[selectedRow]
bookmarkController.delegate = self
}
default:
break
}
}
Я полагаю, он должен что-то делать с наличием UISearchController
в моем представлении иерархия как-то мешает, но, хоть убей, я не могу понять, как это исправить. Из отладчика представления:
Подробный вид представлен из UITableViewController
: Представлен из UISearchController
: