显示来自 viewDidLoad 的警报消息

Posted

技术标签:

【中文标题】显示来自 viewDidLoad 的警报消息【英文标题】:Display Alert Message from viewDidLoad 【发布时间】:2016-01-09 10:10:02 【问题描述】:

我想显示来自ViewController.mviewDidLoad() 方法而不是viewDidAppear() 方法的警报消息。

这是我的代码:

- (void)viewDidLoad 
    [super viewDidLoad];

    //A SIMPLE ALERT DIALOG
    UIAlertController *alert =   [UIAlertController
                              alertControllerWithTitle:@"My Title"
                              message:@"Enter User Credentials"
                              preferredStyle:UIAlertControllerStyleAlert];


    UIAlertAction *cancelAction = [UIAlertAction
                               actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel action")
                               style:UIAlertActionStyleCancel
                               handler:^(UIAlertAction *action)
                               
                                   NSLog(@"Cancel action");
                               ];

    UIAlertAction *okAction = [UIAlertAction
                           actionWithTitle:NSLocalizedString(@"OK", @"OK action")
                           style:UIAlertActionStyleDefault
                           handler:^(UIAlertAction *action)
                           
                               NSLog(@"OK action");
                           ];

    [alert addAction:cancelAction];
    [alert addAction:okAction];
    [self presentViewController:alert animated:YES completion:nil];

我收到此错误:

警告:尝试在视图不在窗口层次结构中的<ViewController: 0x7fbc585a09d0> 上显示<UIAlertController: 0x7fbc58448960>

【问题讨论】:

whose view is not in the window hierarchy的可能重复 @Woodstock 我的问题不同... 【参考方案1】:

好的,不是错误,问题是viewDidLoad 中的视图层次结构没有完全设置。如果使用viewDidAppear,则设置层次结构。

如果你真的想在viewDidLoad 中调用这个警报,你可以通过将你的演示调用包装在这个 GCD 块中来导致轻微的延迟,等待下一个运行循环,但是我建议你不要' t(很丑)。

dispatch_async(dispatch_get_main_queue(), ^ 
    [self presentViewController:alert animated:YES completion:nil];
);

【讨论】:

我很高兴,请注意,尽管上述方法有效,但我猜 Apple 并没有打算在 viewDidLoad 中显示警报,因为它处于 viewController 生命周期的早期阶段。 伍德斯托克的好答案!感谢您的反馈挽救了我的一天:)【参考方案2】:

将此调用移至 viewDidAppear: 方法。

【讨论】:

你是对的,我认为这应该可以从 viewDidLoad 调用。 但我想调用表单 viewDidLoad : 方法【参考方案3】:

你必须嵌入一个导航控制器并展示控制器

- (void)viewDidLoad 
  [super viewDidLoad];

  //A SIMPLE ALERT DIALOG


   UIAlertController *alert =   [UIAlertController
                          alertControllerWithTitle:@"My Title"
                          message:@"Enter User Credentials"
                          preferredStyle:UIAlertControllerStyleAlert];


   UIAlertAction *cancelAction = [UIAlertAction
                           actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel action")
                           style:UIAlertActionStyleCancel
                           handler:^(UIAlertAction *action)
                           
                               NSLog(@"Cancel action");
                           ];

   UIAlertAction *okAction = [UIAlertAction
                       actionWithTitle:NSLocalizedString(@"OK", @"OK action")
                       style:UIAlertActionStyleDefault
                       handler:^(UIAlertAction *action)
                       
                           NSLog(@"OK action");
                       ];

   [alert addAction:cancelAction];
   [alert addAction:okAction];

   [self.navigationController presentViewController:alert animated:NO completion:nil];
   //    [self presentViewController:cameraView animated:NO completion:nil]; //this will cause view is not in the window hierarchy error


  [self.view addSubview:alert.view];
  [self addChildViewController:alert];
  [alert didMoveToParentViewController:self];

【讨论】:

我试试你建议的代码。但是当我点击任何按钮时应用程序崩溃了,即 OK , Cancel .. 并且 Alert Box 显示在左上角 @ShivaniArorra 我已经更新了我的答案,检查一下你需要做的[self.navigationController presentViewController:alert animated:NO completion:nil];【参考方案4】:

Swift 3 ios 10,我使用操作队列将更新 UI 的代码块放到主线程上。

import UIKit

class ViewController2: UIViewController 

var opQueue = OperationQueue()

override func viewDidLoad() 
    super.viewDidLoad()
        let alert = UIAlertController(title: "MESSAGE", message: "HELLO WORLD!", preferredStyle: UIAlertControllerStyle.alert)
        // add an action (button, we can add more than 1 buttons)
        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
        // show the alert
        self.opQueue.addOperation 
            // Put queue to the main thread which will update the UI
            OperationQueue.main.addOperation(
                self.present(alert, animated: true, completion: nil)
            )
        
    

简而言之,我们使用的是异步。这允许警报消息按预期显示(即使我们在 viewDidLoad() 中)。

【讨论】:

这实际上是将一个块添加到本地操作队列中,然后将另一个块添加到主操作队列中,然后呈现警报。为此使用调度队列更为正常:DispatchQueue.main.async ...

以上是关于显示来自 viewDidLoad 的警报消息的主要内容,如果未能解决你的问题,请参考以下文章

如何在 blazor 组件中显示来自后端的自定义引导警报

Swift 使用关闭警报消息 [重复]

IOS 在字符串中设置错误消息以显示在警报中

如何根据 Firebase Auth 错误消息在 Flutter 中显示自定义警报对话框?

Swift UIAlertController 显示自定义消息

如何为 SimplePing 显示警报?