[ios] UIAlertController가 이미 표시되고 있는지 확인하는 가장 좋은 방법은 무엇입니까?

로드 될 때 각 셀이 UIAlertController에 표시하도록 선택한 NSError를 반환 할 수있는 tableview가 있습니다. 문제는 여러 오류가 반환되면 콘솔 에이 오류가 발생한다는 것입니다.

경고 : MessagesMasterVC에서 UIAlertController : 0x14e64cb00을 표시하려고합니다 : 이미 표시되고있는 0x14e53d800 (null)

이상적으로는 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
}

matt의 답변에 따라 확장을 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)
    }
}



답변

“이미 제공하는”UIAlertController가 아니라 MessagesMasterVC입니다. 뷰 컨트롤러는 한 번에 하나의 다른 뷰 컨트롤러 만 표시 할 수 있습니다. 따라서 오류 메시지입니다.

즉, 뷰 컨트롤러에에게 지시 한 presentViewController:...경우 제시된 뷰 컨트롤러가 해제 될 때까지 다시 할 수 없습니다.

당신은 MessagesMasterVC가 이미 뷰 컨트롤러를 제공하고 있는지 물어볼 수 있습니다 presentedViewController. 그렇지 않다면 nil말하지 마십시오 presentViewController:.... 이미 뷰 컨트롤러를 제공하고 있습니다.


답변

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

      // UIAlertController is presenting.Here

}


답변

위의 제안 된 솔루션에는 내 관점에서 볼 때 필수적인 문제가 있습니다.

ViewController에게 ‘presentedViewController’속성이 nil이고 대답이 거짓인지 물어 보면 UIAlertController가 이미 제시되어 있다는 결론에 도달 할 수 없습니다. 예를 들어 popOver와 같은 표시되는 ViewController 일 수 있습니다. 따라서 Alert가 이미 화면에 있는지 여부를 확실히 확인하는 제안은 다음과 같습니다 (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")
      }
  }

}


답변

다음은 Swift 3에서 사용하는 솔루션입니다. 사용자에게 경고를 표시하는 기능입니다. 사용자가 경고를 해제하기 전에 여러 번 호출하면 이미 표시되고있는 경고에 새 경고 텍스트를 추가합니다. . 다른보기가 표시되는 경우 경고가 표시되지 않습니다. 모든 사람이 그 행동에 동의하는 것은 아니지만 간단한 상황에서는 잘 작동합니다.

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


답변

뷰 컨트롤러가 있는지 간단히 확인할 수 있습니다.

표시되면 UIAlertController의 종류인지 확인하십시오.

    id alert = self.presentedViewController;

    if (alert && [alert isKindOfClass:[UIAlertController class]])
      {
           *// YES UIAlertController is already presented*
      }
    else
       {
        // UIAlertController is not presented OR visible.
       }


답변

경고가 이미 표시된 경우 한 줄로 테스트 할 수 있습니다.

if self.presentedViewController as? UIAlertController != nil {
    print ("alert already presented")
}


답변

이 범주는 UIAlertController를 포함하는 모든 모달 컨트롤러를 자동 관리 할 수 ​​있습니다.

UIViewController + JCPresentQueue.h