Warning: Attempt to present <UIAlertController: 0x7facd3946920> on <...> which is already presenting (null)

MortalMan picture MortalMan · May 20, 2015 · Viewed 14.8k times · Source

I have a long press gesture set on a UITableView that presents a UIAlertController containing the cell's text. When the UIAlertController is presented I get this warning:

Attempt to present <UIAlertController: 0x7fd57384e8e0>  on <TaskAppV2.MainTaskView: 0x7fd571701150> which is already presenting (null)

From my understanding, MainTaskView (the UITableView) is already presenting a view, so it shouldn't present a second view, the UIAlertController. So I tried this solution from a similar question. It does not work as I get the same warning. What can I do to solve this warning? See below for code:

func longPressedView(gestureRecognizer: UIGestureRecognizer){

    /*Get cell info from where user tapped*/
    if (gestureRecognizer.state == UIGestureRecognizerState.Ended) {
        var tapLocation: CGPoint = gestureRecognizer.locationInView(self.tableView)

        var tappedIndexPath: NSIndexPath? = self.tableView.indexPathForRowAtPoint(tapLocation)
        if (tappedIndexPath != nil) {
            var tappedCell: UITableViewCell? = self.tableView.cellForRowAtIndexPath(tappedIndexPath!)
            println("the cell task name is \(tappedCell!.textLabel!.text!)")
        } else {
            println("You didn't tap on a cell")
        }
    }

    /*Long press alert*/
    let tapAlert = UIAlertController(title: "Long Pressed", message: "You just long pressed the long press view", preferredStyle: UIAlertControllerStyle.Alert)
    tapAlert.addAction(UIAlertAction(title: "OK", style: .Destructive, handler: nil))
    /*
    if (self.presentedViewController == nil) {
        self.presentViewController(tapAlert, animated: true, completion: nil)
    } else {
        println("already presenting a view")
    } */

    self.presentViewController(tapAlert, animated: true, completion: nil)
    println("presented")
}

Console output:

presented
You didn't tap on a cell
2015-05-19 22:46:35.692 TaskAppV2[60765:3235207] Warning: Attempt to present <UIAlertController: 0x7fc689e05d80>  on <TaskAppV2.MainTaskView: 0x7fc689fc33f0> which is already presenting (null)
presented

For some reason, both pieces of code are executing in the if statement when the long press gesture happens. The alert is presented and the text is printed to the console. Is this an issue?

Edit: As Matt said, I didn't have all my code in the scope of the gesture recognizer test. Moving that in fixed my problem. The code outside of the test was being executed twice, resulting in the UIAlertController being presented twice.

Answer

matt picture matt · May 20, 2015

For some reason, both pieces of code are executing in the if

That should have rung alarm bells for me. It is impossible that both the if and the else should run. This code must be running twice.

That is because you are not testing the state of the gesture recognizer. A long press g.r. sends its action message twice. You are running this code both on the long press and on the release. You need to test the state of the g.r. so that you don't do that. Example:

@IBAction func longPressedView(g: UIGestureRecognizer) {
    if g.state == .Began {
        // ... do it all here
    }
}