Предупреждение: попытка представить ‹UIAlertController: 0x7facd3946920› на ‹›, который уже представлен (нулевой)

У меня есть жест длительного нажатия, установленный на UITableView, который представляет UIAlertController, содержащий текст ячейки. Когда представлен UIAlertController, я получаю это предупреждение:

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

Насколько я понимаю, MainTaskView (UITableView) уже представляет представление, поэтому он не должен представлять второе представление, UIAlertController. Поэтому я попробовал это решение из аналогичного вопроса. Это не работает, так как я получаю то же предупреждение. Что я могу сделать, чтобы решить это предупреждение? См. ниже код:

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

Вывод консоли:

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

По какой-то причине обе части кода выполняются в операторе if, когда происходит жест длительного нажатия. Представлено предупреждение, и текст выводится на консоль. Это проблема?

Правка. Как сказал Мэтт, мой код не был включен в объем теста распознавателя жестов. Перемещение этого исправило мою проблему. Код вне теста выполнялся дважды, в результате чего UIAlertController отображалось дважды.


person MortalMan    schedule 20.05.2015    source источник
comment
Можем ли мы увидеть соответствующий код? Представление controllers представляет другие контроллеры, поэтому ваш UITableView не должен быть проблемой. Кажется, вы немного смешиваете представления и контроллеры.   -  person Connor Neville    schedule 20.05.2015
comment
Принятый ответ на вопрос, на который вы ссылаетесь, кажется довольно ясным. Можете ли вы добавить соответствующий код к вашему вопросу?   -  person Daniel Storm    schedule 20.05.2015
comment
Конечно, дай мне пару минут.   -  person MortalMan    schedule 20.05.2015
comment
Эта строка кода заглушает предупреждение, потому что это совершенно другое. Вместо того, чтобы отклонить существующий представленный v.c. и представляя новый, теперь у вас есть два представленных контроллера представления один поверх другого. Если это то, чего ты хочешь, хорошо. Но убедитесь, что это так.   -  person matt    schedule 20.05.2015
comment
@matt, тогда есть ли правильный способ сделать это?   -  person MortalMan    schedule 20.05.2015
comment
Какой контроллер представления уже представлен? Сообщение which is already presenting (null) кажется очень странным. Это то, что нужно попытаться отследить в первую очередь.   -  person matt    schedule 20.05.2015
comment
Подожди, у меня есть хитрый план...   -  person matt    schedule 20.05.2015
comment
@matt println("\(presentedViewController)") дает ноль. Что, я думаю, имеет смысл. Что я могу сделать, чтобы отследить это?   -  person MortalMan    schedule 20.05.2015
comment
У меня есть теория, что это связано с тем, что длительное нажатие на ячейку таблицы вызывает меню. Вы находитесь в конфликте с этим. Мой ответ ниже может вывести нас из этого.   -  person matt    schedule 20.05.2015
comment
@matt, это не сработало :( что еще мы можем попробовать?   -  person MortalMan    schedule 20.05.2015
comment
Мы в поповере? Опишите всю ситуацию как можно лучше, пожалуйста.   -  person matt    schedule 20.05.2015
comment
Блестящая теория, Мэтт! (Я проголосовал за это, потому что большинство из нас не подумали бы об этом!) Но метки должны иметь userInteractionEnabled, верно? (У меня нет меню в моих пользовательских ячейках.)   -  person    schedule 20.05.2015
comment
Хорошо, у меня есть новая теория! Держись, это действительно доставит тебя.   -  person matt    schedule 20.05.2015
comment
Табличное представление занимает большую часть окна. gestureRecognizer настроен в MainTaskView (контроллер таблицы) viewDidLoad. При длительном нажатии на ячейку или пустой вид таблицы вызывается функция, которую я сделал для этого жеста. Я обновлю вопрос.   -  person MortalMan    schedule 20.05.2015


Ответы (4)


По какой-то причине обе части кода выполняются в if

Это должно было насторожить меня. Невозможно, чтобы одновременно запускались if и else. Этот код должен быть запущен дважды.

Это потому, что вы не проверяете состояние распознавателя жестов. Длительное нажатие g.r. отправляет сообщение о действии дважды. Вы запускаете этот код как при длительном нажатии, так и при отпускании. Вам нужно проверить состояние г.р. чтобы вы этого не делали. Пример:

@IBAction func longPressedView(g: UIGestureRecognizer) {
    if g.state == .Began {
        // ... do it all here
    }
}
person matt    schedule 20.05.2015
comment
Единственное другое presentViewController, которое у меня есть в этом классе, возможно, только когда таблица находится в режиме редактирования. - person MortalMan; 20.05.2015
comment
Гений! Я помещаю println() под presentViewController, и он выполняется дважды при долгом нажатии. - person MortalMan; 20.05.2015
comment
Я понял. Это потому, что вы не проверяете состояние длительного нажатия. Пересмотрел мой ответ (думаю, в последний раз). - person matt; 20.05.2015
comment
Но есть твоя проблема. Ваши оповещения не в тесте! Переместите его внутрь. В противном случае это произойдет дважды. - person matt; 20.05.2015
comment
Боже мой, мне так жаль тратить ваше время... Я купил две ваши книги по программированию iOS 8 пару дней назад и с удовольствием прочитал их. Я надеюсь, что они помогут мне узнать все это. - person MortalMan; 20.05.2015
comment
Не зря, абсолютно увлекательно. Я совсем забыл про проблему с множественными вызовами метода действия, надо было подумать об этом раньше. - person matt; 20.05.2015

У меня была такая же проблема. Я смог исправить это с помощью этого кода:

        if self.presentedViewController == nil {
            self.present(Alert, animated: true, completion: nil)
        }
        else {
            self.dismiss(animated: false, completion: nil)
            self.present(Alert, animated: true, completion: nil)
        }
person Dmitry Senashenko    schedule 13.03.2017
comment
Поместите второй подарок во второй обработчик завершения отклонения. - person Luke Stanyer; 15.08.2017
comment
это действительно хорошее решение для меня :) - person lecover; 16.03.2020

Вы должны различать состояние жеста, а затем выполнять нужный код, если не селектор, который вы добавляете к цели, будет выполняться в первый раз, когда состояние жеста равно UIGestureRecognizerStateBegan, и во второй раз, когда состояние жеста равно UIGestureRecognizerStateCancelled, вторая производительность, показ alertController, поэтому Xcode будет регистрировать предупреждение.

person Immanito    schedule 28.12.2017

0

Отклоните текущий контроллер и представьте контроллер предупреждений, например

func alert(_ message:String) {
let alert = UIAlertController(title: "Error!", message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Dismiss", style: .default, handler: nil))
self.dismiss(animated: false, completion: nil)
self.present(alert, animated: true,completion: nil)
}
person Faiz Ul Hassan    schedule 12.07.2019