Ответ 1
Я нашел решение.
Я добавлю следующий код в HomeViewController.viewDidLoad
, и это работает!
definesPresentationContext = true
Это мое первое приложение для iOS.
Итак, у меня есть UIVIewController
с UITableView
, где я включил UISearchBar
и a UISearchController
для фильтрации TableCells для отображения
override func viewDidLoad() {
menuBar.delegate = self
table.dataSource = self
table.delegate = self
let nib = UINib(nibName: "ItemCellTableViewCell", bundle: nil)
table.registerNib(nib, forCellReuseIdentifier: "Cell")
let searchButton = UIBarButtonItem(barButtonSystemItem: .Search, target: self, action: "search:")
menuBar.topItem?.leftBarButtonItem = searchButton
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
return controller
})()
self.table.reloadData()
}
Я также использую modal segue, чтобы открыть элемент ViewController
, где я покажу детали элемента.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.index = indexPath.row
self.performSegueWithIdentifier("ItemDetailFromHome", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "ItemDetailFromHome") {
let settingsVC = segue.destinationViewController as! ItemDetailViewController
settingsVC.parent = self
if self.isSearching == true && self.searchText != nil && self.searchText != "" {
settingsVC.item = self.filteredItems[self.index!]
} else {
settingsVC.item = self.items[self.index!]
}
}
}
Это работает нормально, пока я не попытаюсь отобразить ItemDetailViewController
для фильтрованного элемента (через UISearchController
).
У меня есть следующее сообщение:
Warning: Attempt to present <ItemDetailViewController: *> on <HomeViewController: *> which is already presenting (null)
Каждый раз я перехожу к функции ItemDetailViewController.viewDidLoad()
, но после этого, когда поиск активирован, я имею предыдущую ошибку.
Любая идея? Я попытался использовать следующую рассылку async, но без успеха
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.index = indexPath.row
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.performSegueWithIdentifier("ItemDetailFromHome", sender: self)
})
}
Я нашел решение.
Я добавлю следующий код в HomeViewController.viewDidLoad
, и это работает!
definesPresentationContext = true
В моем случае я обнаружил, что мой код для представления нового viewController (a UIAlertController
) вызывается дважды.
Проверьте это, прежде чем возиться с definesPresentationContext
.
В моем случае я слишком рано пытался показать новый UIViewController перед закрытием предыдущего. Проблема была решена через звонок с небольшой задержкой:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.callMethod()
}
Это случилось со мной в нашем проекте. Я представлял наш журнал входа/выхода ViewController
в качестве всплывающего окна. Но всякий раз, когда я пытался снова выйти из системы и отображать всплывающее окно, я получал это в моей консоли:
Warning: Attempt to present UIViewController on <MY_HOME_VIEW_CONTROLLER> which is already presenting (null)
Я предполагаю, что pop-over все еще удерживался моим ViewController
, хотя он не был виден.
Однако вы пытаетесь отобразить новый ViewController
, следующий код, который я использовал для решения проблемы, должен работать для вас:
func showLoginForm() {
// Dismiss the Old
if let presented = self.presentedViewController {
presented.removeFromParentViewController()
}
// Present the New
let storyboard = UIStoryboard(name: "MPTLogin", bundle: Bundle(for: MPTLogin.self))
let loginVC = storyboard.instantiateViewController(withIdentifier: "LogInViewController") as? MPTLogInViewController
let loginNav = MPTLoginNav(rootViewController: loginVC!)
loginNav.modalPresentationStyle = .pageSheet;
self.present(loginNav, animated: true, completion: nil)
}
Я столкнулся с такой же проблемой То, что я сделал, - от Interface Builder, выбрал мой segue Его вид был "Настоящим Модом" и его презентация была "В текущем контексте"
я изменил презентацию на "Default", а затем это сработало для меня.
В моем случае я пытался представить UIAlertController
в некоторый момент времени жизни приложения после использования UISearchController
в том же UINavigationController
.
Я не использовал UISearchController
правильно и забыл установить searchController.isActive = false
прежде чем уволить. Позже в приложении я попытался представить предупреждение, но контроллер поиска, хотя и не видимый в то время, все еще контролировал контекст представления.
Это то, что, в конце концов, сработало для меня, так как в моем проекте точно не было NavigationVC, а вместо этого отдельные VC. как файлы XIB
Этот код породил ошибку:
present(alertVC, animated: true, completion: nil)
Этот код исправил ошибку:
if presentedViewController == nil{
navigationController?.present(alertVC, animated: true, completion: nil)
}
Для меня это было предупреждение, которое мешало новому VC, который я собирался представить.
Поэтому я переместил новый код присутствия VC в часть моего оповещения "ОК", например:
func showSuccessfullSignupAndGoToMainView(){
let alert = UIAlertController(title: "Alert", message: "Sign up was successfull.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
switch action.style{
case .default:
// Goto Main Page to show businesses
let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let vc : MainViewController = mainStoryboard.instantiateViewController(withIdentifier: "MainViewController") as! MainViewController
self.present(vc, animated: false, completion: nil)
case .cancel:
print("cancel")
case .destructive:
print("destructive")
}}))
self.present(alert, animated: true, completion: nil)
}
Я получил ту же проблему, когда я попытался представить VC, который вызывается внутри SideMenu (jonkykong).
сначала я попробовал внутри SideMenu и вызвал его у делегата в MainVC, у обоих была та же проблема.
Решение: сначала распустите SideMenu и представьте новый VC после того, как воля сработает отлично!
Проблема для меня состоит в том, что я представлял два модальных режима, и мне нужно закрыть оба, а затем выполнить некоторый код в родительском окне... и затем у меня появилась эта ошибка... Я решил ее, установив этот код в последнем сообщении о завершении модал представлен:
self.dismiss(animated: true, completion: {
self.delegate?.callingDelegate()
})
другими словами, вместо двух раз отклонить.. в блоке завершения первого делегата вызова отклонения, который выполнит второе отклонение.
Моя проблема заключалась в том, что я пытался представить предупреждение с точки зрения, который не был сверху. Убедитесь, что вы представляете самый верхний viewController.
В моем случае это была проблема кнопки, которая была продублирована в Интерфейсном Разработчике. К оригинальной кнопке был прикреплен обработчик, который также представлял модальный вид. Затем, когда я прикрепил обработчик касания к скопированной кнопке, я забыл удалить скопированный обработчик из оригинала, что вызвало проблему.