直到 pushViewController 才应用外观更改

Posted

技术标签:

【中文标题】直到 pushViewController 才应用外观更改【英文标题】:Changes in appearance is not applying until pushViewController 【发布时间】:2012-07-02 19:42:44 【问题描述】:

我想构建对象,然后用它打开一个控制器。构建最多可能需要 5 秒钟,我想在它处理时显示一条消息。 我有以下didSelectRowAtIndexPath 的实现:

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

    messageView.hidden = NO;

    // Some methods

    Controller *ctrl = [Controller new];
    [self.navigationController pushViewController:ctrl animated:YES];

一切都很好,但有一个问题:messageView 仅在推送动画开始时出现。我能做些什么来解决这个问题?

【问题讨论】:

【参考方案1】:

类似于乔纳森的回答,稍微延迟推送,让 messageView 有时间出现。

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

    messageView.hidden = NO;

    int64_t oneMillisecond = NSEC_PER_MSEC;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, oneMillisecond), dispatch_get_main_queue(), ^(void)
        // Some methods

        Controller *ctrl = [Controller new];
        [self.navigationController pushViewController:ctrl animated:YES];
    );

【讨论】:

【参考方案2】:

它没有显示,因为您在构建对象时阻塞了主线程。

在您将控制权返回给运行循环之前,用户界面不会更新。

解决方案是在后台线程上构建对象,最简单的方法是使用 libdispatch,如下所示:

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

    messageView.hidden = NO;

    // you may want to disable user interaction while background operations happen

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^

        // Perform your lengthy operations here

        Controller *ctrl = [[Controller alloc] init];

        dispatch_async(dispatch_get_main_queue(), ^
            [self.navigationController pushViewController:ctrl animated:YES];
        
    );

【讨论】:

【参考方案3】:

如果你想要UIAlertView,你可以使用这个代码:

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title..." message:@"More?" delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
    [alert show];

完成后,您可以调用它来关闭:

[alert dismissWithClickedButtonIndex:0 animated:YES];

【讨论】:

这不是UIAlertView,这是我自己的看法。但不幸的是UIAlertView 也仅在推送动画开始后出现:)【参考方案4】:

你可以试试这个吗:

[UIView animateWithDuration:0.5f delay:0.0f options:UIViewAnimationCurveLinear animations:^(void)

    messageView.hidden = NO;

completion:^(BOOL finished)

    Controller *ctrl = [Controller new];
    [self.navigationController pushViewController:ctrl animated:YES];
];

【讨论】:

【参考方案5】:

在您的 didSelectRowAtIndexPath 调用期间,视图可能不会重绘。

所以...我会尝试在一个块中运行长时间运行的方法。然后用你的 messageView 动画阻止主线程,并让你的块发布通知或关闭它。

您可能希望为 messageView 在特定时间后自行关闭设置某种条件。

【讨论】:

以上是关于直到 pushViewController 才应用外观更改的主要内容,如果未能解决你的问题,请参考以下文章

iOS解决使用模态视图 导致无法pushViewController

iOS解决使用模态视图 导致无法pushViewController

UITabBarController 应用程序和 pushViewController 失败

pushViewController 在多个标签应用程序中啥都不做?

PushViewController 显示黑屏

直到刷新才应用 CSS 样式