কোনও ইউআইএআরএলআর্ট কন্ট্রোলার ইতিমধ্যে উপস্থাপন করছে কিনা তা যাচাই করার সর্বোত্তম উপায় কী?


109

আমার একটি টেবিলভিউ রয়েছে যা লোড হয়ে গেলে, প্রতিটি কক্ষ সম্ভবত একটি এনএসইররার ফিরিয়ে দিতে পারে, যা আমি একটি ইউআইএলার্টকন্ট্রোলারে প্রদর্শন করার জন্য বেছে নিয়েছি। সমস্যাটি হ'ল একাধিক ত্রুটি যদি ফিরে আসে তবে কনসোলে আমি এই ত্রুটিটি পেয়েছি।

সতর্কতা: ইউএআইএলআরএল্ট কন্ট্রোলার উপস্থাপনের চেষ্টা: বার্তা মাস্টারভিসি তে 0x14e64cb00: 0x14e53d800 যা ইতিমধ্যে উপস্থাপন করছে (নাল)

আদর্শভাবে, আমি আদর্শভাবে এটি আমার ইউআইএআরএলআরটি নিয়ন্ত্রণকারী এক্সটেনশন পদ্ধতিতে পরিচালনা করতে চাই।

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
}

ম্যাট এর উত্তরের ভিত্তিতে, আমি এক্সটেনশনটিকে একটি ইউআইভিউকন্ট্রোলার এক্সটেনশনে পরিবর্তন করেছি, এটির অনেক ক্লিনার এবং প্রচুর উপস্থিত ভিউকন্ট্রোলার কোড সংরক্ষণ করে।

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

আপনার আপডেট কোড পোস্ট করার জন্য ধন্যবাদ।
djbp

আমি বাকী কোডটি (ইউআইএলআরলেট কনট্রোলার সেটআপের জন্য তিনটি লাইন) ইফ স্টেটমেন্টেও স্থানান্তরিত করেছিলাম, কারণ এটি এখনও নিম্নলিখিত ত্রুটিটি দিচ্ছিল (কোনও ভিউ কন্ট্রোলারের দৃষ্টিভঙ্গিটি লোড করার চেষ্টা করা হচ্ছে না যখন এটি অপসারণের অনুমতি নেই এবং ফলাফল হতে পারে অপরিবর্তিত আচরণ)
কিটসন

আমি নীচের লিঙ্কটি উপর সমাধান পড়ুন চাই, চেক করুন stackoverflow.com/a/39994115/1872233
iDevAmit

উত্তর:


119

এটি "ইতিমধ্যে উপস্থাপন করা" যে ইউআইএএলআর্টকন্ট্রোলার নয়, এটি মেসেজমাস্টারভিসি। একটি ভিউ কন্ট্রোলার একবারে কেবলমাত্র অন্য একটি ভিউ কন্ট্রোলার উপস্থাপন করতে পারে। সুতরাং ত্রুটি বার্তা।

অন্য কথায়, আপনি যদি কোনও ভিউ কন্ট্রোলারকে বলে presentViewController:...থাকেন তবে উপস্থাপিত ভিউ কন্ট্রোলারকে বরখাস্ত না করা পর্যন্ত আপনি তা আর করতে পারবেন না।

আপনি বার্তাগুলি মাস্টারভিসি জিজ্ঞাসা করতে পারেন এটি ইতিমধ্যে এটির দ্বারা কোনও ভিউ কন্ট্রোলার উপস্থাপন করছে কিনা presentedViewController। যদি তা nilনা হয় তবে তা বলবেন না presentViewController:...- এটি ইতিমধ্যে একটি দর্শন নিয়ামক উপস্থাপন করছে।


2
যদি কন্ট্রোলার এ উপস্থাপক বি উপস্থাপন করে এবং তারপরে বি ইউআইএলার্টকন্ট্রোলার উপস্থাপন করতে চায়, তা কি কাজ করবে? আমার একই ত্রুটি হচ্ছে এবং আমি বুঝতে পারি না যে বি ইতিমধ্যে এমন কিছু উপস্থাপন করছে যা আমি জানি না, বা সমস্যাটি কারণ বি এর দ্বারা উপস্থাপিত হচ্ছে
ক্রিস্টোফার ফ্রান্সিসকো

1
ক্রিস্টোফারফ্রান্সিসকো এটি নতুন প্রশ্ন হিসাবে জিজ্ঞাসা করুন!
ম্যাট

ক্রিস্টোফারফ্রান্সিসকো হাই, আমার এখন একই সমস্যা আছে, আপনি কি এটির জন্য একটি নতুন প্রশ্ন তৈরি করেছেন? বা কোথায় আপনি এটি সমাধান করতে সক্ষম? যদি হ্যাঁ, কিভাবে?
আবেদ নাসেরি

দুর্দান্ত উত্তর, এটি একটি সূক্ষ্ম পার্থক্য।
স্কটিবিলেডস

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

      // UIAlertController is presenting.Here

}

22
আপনি কী করছেন তা ব্যাখ্যা করার জন্য আপনার উত্তরে কিছু পাঠ্য রাখা সর্বদা ভাল ধারণা। একটি ভাল উত্তর লিখতে কিভাবে পড়ুন ।
জর্জেন আর

1
ব্যাখ্যার অভাবে কোনও দুর্দান্ত উত্তর নয়, তবে পদ্ধতিটি আমাকে অনেক সহায়তা করেছিল - সমস্যাটি হ'ল আমার একাধিক ইভেন্ট আমার UIAlertControllerকোডকে সংক্ষিপ্তভাবে একটি গুলি চালানোর জন্য ডেকেছিল। আপনার যদি অনুরূপ সমস্যা হয় তবে এটি পরীক্ষা করে দেখুন।
চিডজি

10

ঠিক আছে, উপরোক্ত প্রস্তাবিত সমাধানগুলি আমার দৃষ্টিকোণ থেকে একটি প্রয়োজনীয় সমস্যা রয়েছে:

যদি আপনি আপনার ভিউকন্ট্রোলারকে জিজ্ঞাসা করেন, 'উপস্থাপনা ভিউ কন্ট্রোলার' গুণটি শূন্য কিনা এবং উত্তরটি মিথ্যা, আপনি এই সিদ্ধান্তে আসতে পারবেন না যে আপনার ইউআইএলআরএল্ট কন্ট্রোলার ইতিমধ্যে উপস্থাপিত হয়েছে। এটি যে কোনও উপস্থাপিত ভিউকন্ট্রোলার হতে পারে, যেমন একটি পপওভার। সুতরাং অবশ্যই যাচাই করার জন্য আমার পরামর্শটি, সতর্কতাটি ইতিমধ্যে পর্দায় রয়েছে কিনা তা নিম্নলিখিত (উপস্থাপিত ভিউকন্ট্রোলারটিকে ইউআইএএলআরটি কনট্রোলার হিসাবে কাস্ট করুন):

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

}


5

আমি সুইফট 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)
    }
}

ঠিক আছে, এটি আমার দরকার ছিল। এটি আইওএস 13 এও কাজ করে।
জোল্টন ভিনক্লার

3

কোনও ভিউ কন্ট্রোলার উপস্থাপন করা হয়েছে কিনা তা আমরা কেবল খতিয়ে দেখতে পারি।

যদি উপস্থাপন করা হয় তবে এটি ইউআইএলার্টকন্ট্রোলার জাতীয় কিনা তা পরীক্ষা করে দেখুন।

    id alert = self.presentedViewController;

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

1

আপনি পরীক্ষা করতে পারেন - একটি একক লাইনে - যদি একটি সতর্কতা ইতিমধ্যে উপস্থাপিত হয়:

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

আপনি আপনার উত্তরে কোডটি ব্যাখ্যা করতে পারেন। অথবা ইতিমধ্যে যখন কোনও গৃহীত বা উচ্চ রেট দেওয়া উত্তর থাকে তখন এটি কীভাবে প্রাসঙ্গিক তথ্য যুক্ত করে একটি ভাল উত্তর কীভাবে লিখতে হয় তা
লায়া গ্রিস

0

এই বিভাগটি সমস্ত মডেল কন্ট্রোলারগুলিতে ইউআইআইএলআর্টকন্ট্রোলার অন্তর্ভুক্ত করে স্বয়ংক্রিয়ভাবে পরিচালনা করতে পারে।

UIViewController + + JCPresentQueue.h


0

আমি এটি সনাক্ত করতে এবং অপসারণ ও সতর্ক করতে ব্যবহার করেছি।

প্রথমে আমরা নিম্নলিখিত ফাংশন সহ একটি সতর্কতা তৈরি করি।

 var yourAlert :UIAlertController!

 func useYouAlert (header: String, info:String){


    yourAlert = UIAlertController(title:header as String, message: info as String, preferredStyle: UIAlertControllerStyle.alert)



    let okAction = UIAlertAction(title: self.langText[62]as String, style: UIAlertActionStyle.default) { (result : UIAlertAction) -> Void in
        print("OK") 

    }


    yourAlert.addAction(okAction)
    self.present(yourAlert.addAction, animated: true, completion: nil)

}

এবং আপনার কোডের অন্য কোনও অংশে

    if yourAlert != nil {

      yourAlert.dismiss(animated: true, completion: nil)

    }

0

সর্বশেষতম সুইফট ভাষার জন্য আপনি নিম্নলিখিত ব্যবহার করতে পারেন:

var alert = presentedViewController

if alert != nil && (alert is UIAlertController) {
    // YES UIAlertController is already presented*
} else {
    // UIAlertController is not presented OR visible.
}

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

0

উত্তর 4.2+ উত্তর

if UIApplication.topViewController()!.isKind(of: UIAlertController.self) { 
            print("UIAlertController is presented")}

যারা শীর্ষ সর্বাধিক ভিউকন্ট্রোলার পাবেন তা জানেন না

extension UIApplication {


public class func topViewController(_ base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
    if let nav = base as? UINavigationController {
        return topViewController(nav.visibleViewController)
    }
    if let tab = base as? UITabBarController {
        if let selected = tab.selectedViewController {
            return topViewController(selected)
        }
    }
    if let presented = base?.presentedViewController {
        return topViewController(presented)
    }
    return base
}}

আইওএস 13.0 এ প্রস্তাবিত সম্পাদনাটিতে সুইফ্ট 5+ উত্তর 'কী উইন্ডো' অবমূল্যায়ন করা হয়েছিল

if UIApplication.topViewController()!.isKind(of: UIAlertController.self) { 
            print("UIAlertController is presented")}

যারা শীর্ষ সর্বাধিক ভিউকন্ট্রোলার পাবেন তা জানেন না

extension UIApplication {


public class func topViewController(_ base: UIViewController? = UIApplication.shared.windows.first?.rootViewController) -> UIViewController? {
    if let nav = base as? UINavigationController {
        return topViewController(nav.visibleViewController)
    }
    if let tab = base as? UITabBarController {
        if let selected = tab.selectedViewController {
            return topViewController(selected)
        }
    }
    if let presented = base?.presentedViewController {
        return topViewController(presented)
    }
    return base
}}

0

আমি খুঁজে পেয়েছি যে ইউআইএআরএলআর্ট কন্ট্রোলার অনুরোধগুলি স্ট্যাক করার জন্য আমার একটি সারি তৈরি করা দরকার।

NSMutableArray *errorMessagesToShow; // in @interface
errorMessagesToShow=[[NSMutableArray alloc] init];  // in init

-(void)showError:(NSString *)theErrorMessage{
    if(theErrorMessage.length>0){
        [errorMessagesToShow addObject:theErrorMessage];
        [self showError1];
    }
}
-(void)showError1{
    NSString *theErrorMessage;
    if([errorMessagesToShow count]==0)return; // queue finished

    UIViewController* parentController =[[UIApplication sharedApplication]keyWindow].rootViewController;
    while( parentController.presentedViewController &&
      parentController != parentController.presentedViewController ){
        parentController = parentController.presentedViewController;
    }
    if([parentController isKindOfClass:[UIAlertController class]])return;  // busy

    // construct the alert using [errorMessagesToShow objectAtIndex:0]
    //  add to each UIAlertAction completionHandler [self showError1];
    //   then

    [errorMessagesToShow removeObjectAtIndex:0];
    [parentController presentViewController:alert animated:YES completion:nil]; 
}

-3

কেবলমাত্র বর্তমান নিয়ামককে বরখাস্ত করুন এবং আপনি যা চান তা উপস্থাপন করুন

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

self.displayAlertController()

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.