0

我们在 iOS 上的 tableView 上方显示视图时遇到问题。我们的方法是创建一个 UIView,它是 UIViewController 的子类的子视图,将其发送到后面,然后在 didSelectRowAtIndexPath 上将其带到前面。我们使用 XIB 来创建用户界面。视图层次结构是这样的:

视图
-- UIView ("loading..." 视图)
-- -- UILabel ("loading...")
-- -- UIActivityIndi​​catorView
-- UITableView
-- UILabel

下面是我们尝试显示“正在加载”视图的方法:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Create a request to the server based on the user's selection in the table view
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    NSError *err;

    // Show the "loading..." message in front of all the other views.
    [self.view bringViewToFront:self.loadingView];
    [self.loadingWheel startAnimating];

    // Make the request
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&err];

    // Stop animating the activity indicator.
    [loadingWheel stopAnimating];

    // other stuff...
}

每当我们将“正在加载”视图放在 XIB 中所有其他视图的前面时,我们可以看到它看起来像我们想要的那样。但是,当我们将加载视图留在后面(根据上面的视图层次结构)然后尝试将其带到前面时,视图永远不会显示。打印出来self.view.subviews表明我们的加载视图实际上是在视图层次结构中。有趣的是,如果我们尝试在 didSelectRowAtIndexPath 中更改视图中的其他内容(例如,更改已在视图中显示的标签的背景颜色),则更改永远不会显示在模拟器上。

4

1 回答 1

3

问题是同步请求。它阻塞了主线程,因此活动指示器没有机会显示。

一个简单的解决方案是异步加载全局队列中的数据,当所有内容都加载完毕后,回调主队列。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Make the request
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&err];

    dispatch_async(dispatch_get_main_queue(), ^{
        // Stop animating the activity indicator.
        [loadingWheel stopAnimating];

        // other stuff...
    });
});

虽然上述解决方案有效,但它会阻塞全局队列,因此并不理想。看看通过NSURLConnection. 在 Apple 的“URL 加载系统编程指南”中有详细的解释。

于 2012-07-17T20:06:49.730 回答