2015-02-02 2 views
76

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

Предупреждение: Попытка представить UIAlertController: 0x14e64cb00 на MessagesMasterVC: 0x14e53d800 который уже представляя (нуль)

В идеале, я бы в идеале хотел бы справиться с этим в моем методе расширения UIAlertController.

class func simpleAlertWithMessage(message: String!) -> UIAlertController { 

    let alertController = UIAlertController(title: nil, message: message, preferredStyle: UIAlertControllerStyle.Alert) 
    let cancel = UIAlertAction(title: "Ok", style: .Cancel, handler: nil) 

    alertController.addAction(cancel) 
    return alertController 
} 

На основании ответа Мэтта, я изменил расширение на расширение UIViewController, его гораздо чище и экономит много presentViewController кода.

func showSimpleAlertWithMessage(message: String!) { 

    let alertController = UIAlertController(title: nil, message: message, preferredStyle: UIAlertControllerStyle.Alert) 
    let cancel = UIAlertAction(title: "Ok", style: .Cancel, handler: nil) 

    alertController.addAction(cancel) 

    if self.presentedViewController == nil { 
     self.presentViewController(alertController, animated: true, completion: nil) 
    } 
} 
+0

Благодарим за отправку обновленного кода. – djbp

+0

Я также переместил остальную часть кода (три строки для настройки UIAlertController) в оператор If, потому что он все еще выдавал следующую ошибку. (Попытка загрузить представление контроллера представления при его освобождении не разрешена и может привести к в неопределенном поведении) – Kitson

+0

Я хотел бы обратиться к решению по ссылке ниже: http://stackoverflow.com/a/39994115/1872233 – iDevAmit

ответ

86

Это не UIAlertController, что "уже представляя", это MessagesMasterVC. Контроллер вида может одновременно отображать только один контроллер просмотра. Отсюда сообщение об ошибке.

Другими словами, если вы сказали контроллеру вида presentViewController:..., вы не сможете сделать это до тех пор, пока представленный контроллер представления не будет уволен.

Вы можете запросить MessageMasterVC, будет ли он уже представлять контроллер просмотра, изучив его presentedViewController. Если не nil, не сообщайте об этом presentViewController:... - он уже представляет контроллер вида.

+2

Если контроллер A представляет контроллер B, а затем B хочет представить UIAlertController, та работа? У меня такая же ошибка, и я не могу понять, если B уже представляет что-то, о чем я не знаю, или проблема связана с тем, что B представлен A –

+0

@ChristopherFrancisco. Задайте это как новый вопрос! – matt

22
if ([self.navigationController.visibleViewController isKindOfClass:[UIAlertController class]]) { 

     // UIAlertController is presenting.Here 

} 
+15

Всегда полезно добавить текст в свой ответ, чтобы объяснить, что вы делаете. Прочитайте [как написать хороший ответ] (http://stackoverflow.com/help/how-to-answer). – jurgemaister

+0

Фантастический, спасибо! – Septronic

+0

Не очень хороший ответ из-за отсутствия объяснений, но метод мне очень помог - проблема заключалась в том, что у меня было несколько событий, вызывающих мой код, чтобы коротко пресечь стрельбу 'UIAlertController'. Проверьте это, если у вас есть аналогичная проблема. – ChidG

7

Ну, предложенные выше решения имеет существенную проблему с моей точки зрения:

Если вы спросите ваш ViewController, является ли ноль атрибут «presentedViewController» и ответ является ложным, вы можете» t пришли к выводу, что ваш UIAlertController уже представлен. Это может быть любой представленный ViewController, например. popOver. Поэтому мое предложение, конечно, проверить, является ли оповещения уже на экране следующее (бросить presentedViewController как UIAlertController):

if self.presentedViewController == nil { 
    // do your presentation of the UIAlertController 
    // ... 
} else { 
    // either the Alert is already presented, or any other view controller 
    // is active (e.g. a PopOver) 
    // ... 

    let thePresentedVC : UIViewController? = self.presentedViewController as UIViewController? 

    if thePresentedVC != nil { 
     if let thePresentedVCAsAlertController : UIAlertController = thePresentedVC as? UIAlertController { 
     // nothing to do , AlertController already active 
     // ... 
     print("Alert not necessary, already on the screen !") 

     } else { 
     // there is another ViewController presented 
     // but it is not an UIAlertController, so do 
     // your UIAlertController-Presentation with 
     // this (presented) ViewController 
     // ... 
     thePresentedVC!.presentViewController(...) 

     print("Alert comes up via another presented VC, e.g. a PopOver") 
     } 
    } 

}

-1

Просто отклонить текущий контроллер и представить тот, который вы хотите т.е.

self.dismiss(animated: false, completion: nil)

self.displayAlertController()

1

Вот решение, я использую в Swift 3. Это функция, показывает предупреждение пользователю, и если вы вызываете его несколько раз до того, как пользователь отклонит предупреждение, он добавит новый текст предупреждения в файл al Это уже представлено. Если появится какое-то другое представление, предупреждение не появится. Не все согласятся с этим поведением, но оно работает хорошо для простых ситуаций.

extension UIViewController { 
    func showAlert(_ msg: String, title: String = "") { 
     if let currentAlert = self.presentedViewController as? UIAlertController { 
      currentAlert.message = (currentAlert.message ?? "") + "\n\nUpdate:\(title): \(msg)" 
      return 
     } 

     // create the alert 
     let alert = UIAlertController(title: title, message: msg, preferredStyle: UIAlertControllerStyle.alert) 
     alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) 

     // show the alert 
     self.present(alert, animated: true, completion: nil) 
    } 
} 
-1

Это случилось со мной, когда я пытался справиться с UI elements в другом потоке, чем Main Thread. У меня была такая же проблема, когда я показал предупреждение в блоке массива фильтров. Когда я вытащил из блока фильтра предупреждающий сигнал, предупреждение с консоли исчезло.