UIAlertController不会立即显示 [英] UIAlertController does not show immediately

查看:85
本文介绍了UIAlertController不会立即显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Xcode版本:7.2.1,iOS版本:9.1 +

我正在尝试在iPad上显示UIAlertController警报消息,该消息显示"Loading ... Please Wait"消息,上面没有任何按钮.我在开始长时间操作之前先介绍UIAlertController,然后在长时间操作后关闭UIAlertController. 但是,正在发生的事情是UIAlertController不会立即显示.仅在较长的操作完成后才短暂闪烁,然后将其取消.

以下是常规代码结构:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Loading" message:@"Please wait...\n\n\n" preferredStyle:UIAlertControllerStyleAlert];
    [self presentViewController:alert animated:YES completion:nil];

    /// Perform long operation here...
    /// (Basically, a message is being sent to a server, a long operation happens on 
    /// the server, and then the server returns a response to the iPad client.)

    [alert dismissViewControllerAnimated:YES completion:nil];
}

我尝试了许多替代方法,例如使用dispatch_async,以便在进行长时间操作时可以同时显示警报消息:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Loading Dataset" message:@"Please wait...\n\n\n" preferredStyle:UIAlertControllerStyleAlert];
    [self presentViewController:alert animated:YES completion:nil];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{          

        /// Perform long operation here...

        dispatch_async(dispatch_get_main_queue(), ^{

            [alert dismissViewControllerAnimated:YES completion:nil];
        });
    });
}

我尝试单独使用UIAlertView(在iOS 8中已弃用)(但我知道它已不推荐使用),但这都不起作用.

我尝试将长操作代码包装在performSelector消息中,但无济于事.

过去,将UIAlertView与dispatch_queue结合使用可解决这种情况.

我们将为您提供任何帮助.

值得注意的一件事:在dispatch_async代码中,如果我在调用长操作代码之前立即添加usleep(250000),则大约80%的时间,UIAlertController警报消息将在正确的时间显示:BEFORE长时间的操作开始.但是,这不是100%的时间,也不是可持续的解决方案.用较小的数字呼叫usleep无效.

请注意,对于DISPATCH_QUEUE_PRIORITY_DEFAULT选项,我也尝试过: DISPATCH_QUEUE_PRIORITY_HIGH,DISPATCH_QUEUE_PRIORITY_LOW和DISPATCH_QUEUE_PRIORITY_BACKGROUND

而且,我也尝试了以下方法:

dispatch_queue_t myQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);

dispatch_async(myQueue, ^{
    /// Perform long operation here...
    dispatch_async(dispatch_get_main_queue(), ^{
        [alert dismissViewControllerAnimated:YES completion:nil];
    });
});

解决方案

在我标记为答案的原始帖子中(5月31日),在某些情况下AlertViewController消息只是挂起,因为dismissViewController方法无法获取叫. (也许不确定各个线程中的某些竞争条件.我不确定.)因此,我最终发现可以可靠工作并且似乎是一种更简洁的解决方案,是结合使用AlertViewController的完成块和dispatch_after调用.

有关

(这篇文章提供了帮助. )

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // Initialize the alert view controller.
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Loading Dataset" message:@"Please wait...\n\n\n" preferredStyle:UIAlertControllerStyleAlert];

    // Present the alert view controller.
    [self presentViewController:alert animated:YES completion:^{

        /// Perform long operation here...

        dispatch_after(0, dispatch_get_main_queue(), ^{

            // Dismiss the alert message.
            [loadAlertController dismissViewControllerAnimated:YES completion:nil];

            /// Execute rest of code INDSIDE the dispatch code block INSTEAD of after it...
        });
     }];
}

Xcode version: 7.2.1, iOS version: 9.1+

I am trying to display a UIAlertController alert message on the iPad that shows a "Loading...Please Wait" message without any buttons on it. I present the UIAlertController before starting a long operation, and then after the long operation, I dismiss the UIAlertController. However, what is happening is the UIAlertController DOES NOT show up immediately. It only flashes up briefly AFTER the longer operation is completed, and then it is dismissed.

Following is the general code structure:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Loading" message:@"Please wait...\n\n\n" preferredStyle:UIAlertControllerStyleAlert];
    [self presentViewController:alert animated:YES completion:nil];

    /// Perform long operation here...
    /// (Basically, a message is being sent to a server, a long operation happens on 
    /// the server, and then the server returns a response to the iPad client.)

    [alert dismissViewControllerAnimated:YES completion:nil];
}

I have tried a number of alternatives, like using dispatch_async so that the alert message can be displayed simultaneously while the long operation is occurring:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Loading Dataset" message:@"Please wait...\n\n\n" preferredStyle:UIAlertControllerStyleAlert];
    [self presentViewController:alert animated:YES completion:nil];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{          

        /// Perform long operation here...

        dispatch_async(dispatch_get_main_queue(), ^{

            [alert dismissViewControllerAnimated:YES completion:nil];
        });
    });
}

I've tried using UIAlertView (which I know is deprecated in iOS 8), both alone and with dispatch, but this is not working either.

I've tried wrapping the long operation code in a performSelector message, but to no avail.

In the past, using a UIAlertView with a dispatch_queue has worked seamlessly for this situation.

Any assistance is appreciated.

Edit:

One interesting thing to note: In the dispatch_async code, if I add a usleep(250000) right before calling the long operation code, about 80% of the time, the UIAlertController alert message WILL be displayed at the correct time: BEFORE the long operation begins. However, this is not 100% of the time, and is not a sustainable solution. Calling usleep with a smaller number does not work.

Note that for the DISPATCH_QUEUE_PRIORITY_DEFAULT option, I also tried: DISPATCH_QUEUE_PRIORITY_HIGH, DISPATCH_QUEUE_PRIORITY_LOW, and DISPATCH_QUEUE_PRIORITY_BACKGROUND

And, I tried the following too:

dispatch_queue_t myQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);

dispatch_async(myQueue, ^{
    /// Perform long operation here...
    dispatch_async(dispatch_get_main_queue(), ^{
        [alert dismissViewControllerAnimated:YES completion:nil];
    });
});

解决方案

In the original post I marked as the answer (May 31), there were a few cases where the AlertViewController message would just hang because the dismissViewController method would not get called. (Perhaps some race condition in the various threads...I'm unsure.) So what I finally found to work reliably and appears to be a cleaner solution is to use a combination of the AlertViewController's completion block and a dispatch_after call.

More on the completion call from the iOS reference: "The completion handler gets called after the viewDidAppear: method is called on the presented view controller."

(This post was of assistance.)

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // Initialize the alert view controller.
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Loading Dataset" message:@"Please wait...\n\n\n" preferredStyle:UIAlertControllerStyleAlert];

    // Present the alert view controller.
    [self presentViewController:alert animated:YES completion:^{

        /// Perform long operation here...

        dispatch_after(0, dispatch_get_main_queue(), ^{

            // Dismiss the alert message.
            [loadAlertController dismissViewControllerAnimated:YES completion:nil];

            /// Execute rest of code INDSIDE the dispatch code block INSTEAD of after it...
        });
     }];
}

这篇关于UIAlertController不会立即显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆