This is my first application for iOS.
So I have a UIVIewController
with a UITableView
where I have integrated a UISearchBar
and a UISearchController
in order to filter TableCells to display
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()
}
I am using also a modal segue in order to open the element's ViewController
where I will display details of the element.
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!]
}
}
}
That works fine until I try to display the ItemDetailViewController
for a filtered element (through the UISearchController
).
I have the following message :
Warning: Attempt to present <ItemDetailViewController: *> on <HomeViewController: *> which is already presenting (null)
At every time I am going to the ItemDetailViewController.viewDidLoad()
function but after that when the search is activated I have the previous error.
Any idea ? I have tried to use the following async dispatch but without success
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.index = indexPath.row
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.performSegueWithIdentifier("ItemDetailFromHome", sender: self)
})
}
I have found out a solution.
I have add the following code in HomeViewController.viewDidLoad
and that works !
definesPresentationContext = true
In my case, I found my code to present the new viewController (a UIAlertController
) was being called twice.
Check this before messing about with definesPresentationContext
.
In my case, I tried too early to show the new UIViewController before closing the previous one. The problem was solved through a call with a slight delay:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.callMethod()
}
This happened with me on our project. I was presenting our log in/log out ViewController
as a pop-over. But whenever I tried to log back out again and display the pop-over again, I was getting this logged out in my console:
Warning: Attempt to present UIViewController on <MY_HOME_VIEW_CONTROLLER> which is already presenting (null)
My guess is that the pop-over was still being held by my ViewController
even though it was not visible.
However you are attempting to display the new ViewController
, the following code I used to solve the issue should work for you:
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)
}
I faced the same kind of problem What I did is from Interface builder selected my segue Its kind was "Present Modally" and its presentation was "Over current context"
i changed the presentation to "Default", and then it worked for me.
In my case I was trying to present a UIAlertController
at some point in the app's lifetime after using a UISearchController
in the same UINavigationController
.
I wasn't using the UISearchController
correctly and forgot to set searchController.isActive = false
before dismissing. Later on in the app I tried to present the alert but the search controller, though not visible at the time, was still controlling the presentation context.
I got the same issue when i tried to present a VC which called inside the SideMenu(jonkykong).
first i tried inside the SideMenu and i called it from the delegate to the MainVC both had the same issue.
Solution: dismiss the SideMenu first and present the new VC after will works perfectly!.
This is what finally worked for me, as my project didn't exactly have a NavigationVC but instead, individual detached VC's. as xib files
This code produced the bug:
present(alertVC, animated: true, completion: nil)
This code fixed the bug:
if presentedViewController == nil{
navigationController?.present(alertVC, animated: true, completion: nil)
}
For me it was an alert that was interfering with the new VC that I was about to present.
So I moved the new VC present code into the OK part of my alert, Like this :
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)
}
The problem for me is that I was presenting two modals and I have to dismiss both and then execute some code in the parent window ... and then I have this error... I solved it seting this code in the dismiss o the last modal presented:
self.dismiss(animated: true, completion: {
self.delegate?.callingDelegate()
})
in other words instead of just dismiss two times .. in the completion block of the first dismiss call delegate that will execute the second dismiss.
My issue was that I was trying to present an alert from a view that wasn't on top. Make sure you present from the top-most viewController.
In my case this was an issue of a button which was duplicated in Interface Builder. The original button had a touch-up handler attached, which also presented a modal view. When I then attached a touch-up handler on the copied button, I forgot to remove the copied handler from the original, causing both handlers to be fired and thus creating the warning.
来源:https://stackoverflow.com/questions/32696615/warning-attempt-to-present-on-which-is-already-presenting-null