Warning: Attempt to present * on * which is alread

2019-04-03 01:40发布

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

8条回答
2楼-- · 2019-04-03 01:48

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)
}
查看更多
不美不萌又怎样
3楼-- · 2019-04-03 01:53

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)
}
查看更多
戒情不戒烟
4楼-- · 2019-04-03 01:57

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.

查看更多
太酷不给撩
5楼-- · 2019-04-03 01:57

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()
}
查看更多
别忘想泡老子
6楼-- · 2019-04-03 01:59

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.

查看更多
迷人小祖宗
7楼-- · 2019-04-03 02:01

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)
    }
查看更多
登录 后发表回答