1

UIView从一个UIViewController. 这UIView包含一个 (big) UICollectionView。从第一个UIView到第二个的过渡UIView非常缓慢:似乎当所有集合单元格的渲染完成后,第二个视图就会出现。在第二个UIView中,我尝试了。

- (void)viewDidAppear:(BOOL)animated
{
    [activityView stopAnimating];
    NSLog(@"did appear %@",[NSDate date]);
}
- (void)viewWillAppear:(BOOL)animated
{
      [super viewWillAppear:animated];
      [activityView startAnimating];
      NSLog(@"will appear %@",[NSDate date]);
}

在 中NSLog,两个事件之间没有时间差,实际上第二UIView个在事件发生后大约 1 秒出现viewDidAppear。此时,我将启动一个UIActivityIndicator, 就像在代码中一样。但该指标从未显示。有什么提示吗?

4

1 回答 1

0

您的问题是您可能通过执行一些磁盘 IO 或网络活动或繁重的计算来阻塞主线程,这就是您遇到此延迟的原因。

我建议您在显示UIActivityIndicator. 完成后,您可以隐藏活动指示器并显示集合视图。

编辑:

注意可能有更好的方法,但我对集合视图不是很熟悉。

BOOL一个非常简单的解决方法是在加载集合视图的视图控制器中保留一个ivar。调用它shouldLoadData并将其设置为NO您的viewDidLoad方法。然后您需要做的就是将 0 返回到您的UICollectionViewDelegate方法numberOfSectionsInCollectionView:collectionView:numberOfItemsInSection:.

最后在您的viewDidAppear方法中,您设置shouldLoadData为 YES 并调用reloadData您的collectionView. 此时棘手的部分是找出一种方法来判断集合视图何时完成重新加载其数据,以便您可以停止活动指示器。

我发现它甚至没有那么棘手,reloadData只是在主线程上排队,所以你可以在调用后在主线程上排队另一个任务reloadData。做就是了:

[self.collectionView reloadData];
dispatch_async(dispatch_get_main_queue(), ^{        
    [self.activity stopAnimating];
});

你会得到想要的行为。但是,您应该知道,这仍然会阻塞主线程。 例如,如果您有一个后退按钮,则在数据完全加载之前无法按下它(实际上可以按下它,但在那之前它不会有任何可见的效果)。

于 2013-09-26T13:37:45.557 回答