警告: 试图显示已经显示的 * on * (空)

这是我的第一个 iOS 应用程序。

因此,我有一个 UIVIewController和一个 UITableView,其中我已经集成了一个 UISearchBar和一个 UISearchController,以便过滤 TableCell 来显示

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()
}

为了打开元素的 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()函数,但之后,当搜索被激活,我有以前的错误。

我尝试使用下面的异步分派,但是没有成功

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.index = indexPath.row
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.performSegueWithIdentifier("ItemDetailFromHome", sender: self)
})
}
65872 次浏览

我已经找到了解决办法。

我已经添加了以下代码在 HomeViewController.viewDidLoad和工程!

definesPresentationContext = true

我也遇到过同样的问题 我所做的是从 Interface Builder 选择了我的话题 它的类型是“现在模态” 它的演讲是“在当前背景下”

我把演示文稿改成了“默认”然后我就成功了。

在我的例子中,我发现我的代码显示新的 viewController (一个 UIAlertController)被调用了两次。

在使用 definesPresentationContext之前检查一下这个。

这是我在我们的项目中发生的。我把我们的登录/注销 ViewController作为一个弹出窗口。但是,每当我试图重新登出并再次显示弹出窗口时,我都会在控制台中注销:

Warning: Attempt to present UIViewController on <MY_HOME_VIEW_CONTROLLER> which is already presenting (null)

我的猜测是,弹出仍然是由我的 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)
}

在我的案例中,我在同一个 UINavigationController中使用了 UISearchController之后,试图在应用程序的生命周期中的某个时刻显示一个 UIAlertController

我没有正确地使用 UISearchController,并且在解散之前忘记设置 searchController.isActive = false。后来在应用程序中,我试图呈现警报,但搜索控制器,虽然当时不可见,仍然控制着呈现上下文。

这是最终为我工作,因为我的项目确切地说没有导航 VC,而是个人独立的 VC。作为 XIB 档案

这段代码产生了 bug:

present(alertVC, animated: true, completion: nil)

这段代码修复了 bug:

 if presentedViewController == nil{
navigationController?.present(alertVC, animated: true, completion: nil)
}

在我的例子中,在关闭前一个控制器之前,我试图显示新的 UIViewController 为时过早。这个问题通过一个稍稍延迟的电话得到了解决:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.callMethod()
}

对我来说,这是一个警报,干扰了我即将呈现的新越共。

所以我把新的 VC 现在的代码移到我的警告的 OK 部分,像这样:

    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)
}

我得到了同样的问题时,我试图提出一个风险投资者呼吁内部的 侧菜单(jonkykong)。

首先我在 SideMenu 里面尝试,我从 MainVC 的代表那里调用它,两者都有同样的问题。

解决方案: < strong > 先关闭侧边菜单,然后展示新的 VC,这样就可以完美工作了。

对我来说,问题是,我提出了两个模态,我必须解散两个,然后执行一些代码在父窗口... 然后我有这个错误... 我解决了它设置这个代码在解散 o 最后一个模态提出:

self.dismiss(animated: true, completion: {
self.delegate?.callingDelegate()
})

换句话说,而不是仅仅驳回两次。.在将执行第二次解散的第一个解散调用委托的完成块中。

我的问题是,我试图提出一个警告,从一个视图,不是在上面。确保您从最上面的视图控制器显示。

在我的案例中,这是一个按钮的问题,它被复制在 Interface Builder 上。原来的按钮有一个修补处理程序附加,这也提出了一个模态视图。然后,当我在复制的按钮上附加一个修补处理程序时,我忘记从原始按钮中删除复制的处理程序,导致两个处理程序都被激活,从而产生警告。

对我来说,有效的方法是将警报的表示添加到主线程中。

DispatchQueue.main.async {
self.present(alert, animated: true)
}

当前 viewController 的表示不完整。通过将警报添加到主线程,它可以等待 viewController 的表示完成后再尝试显示。

我的问题是(在我的协调器中)我在 VC上展示了一个 VC,然后当我想展示下一个 VC (第三个)时,展示了第一个 VC 中的第三个 VC,这显然造成了问题 which is already presenting。 请确保您提出的第三个从第二个 VC

secondVC.present(thirdVC, animated: true, completion: nil)

很有可能您将您的 Search 按钮直接连接到另一个视图控制器,并使用一个调用 PerformSegueWithIdentifier 的 segue 还有。所以您要打开它两次,这会产生一个错误,告诉您“已经呈现”

因此,不要调用 PerformSegueWithIdentifier,这应该可以解决问题。

基于 梅赫达德的回答: 我必须首先检查搜索控制器是否处于活动状态(如果用户当前正在搜索) :

if self.searchController.isActive {
self.searchController.present(alert, animated: true, completion: nil)
} else {
self.present(alert, animated: true, completion: nil)
}

其中 alert是模态显示的视图控制器。

在展示新作品之前,请确保先将前一个作品删除!