我有一个自定义单元格,加载在我的集合视图的底部。它唯一的工作就是显示一个活动指示器视图 - 当应用程序正在进行新的工作调用时会发生这种情况。
所以我把它添加到单元格中,如下所示:
BBLoaderCell *loaderCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"LoaderCell" forIndexPath:indexPath];
UIActivityIndicatorView * activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityIndicator.hidesWhenStopped = YES;
activityIndicator.hidden = NO;
activityIndicator.center = loaderCell.imageView.center;
activityIndicator.tag = 10;
[loaderCell.imageView addSubview:activityIndicator];
[activityIndicator startAnimating];
return loaderCell;
这会在我视图的最后一个单元格中显示一个活动指示器 - 但它不会旋转。有任何想法吗?
找到解决方案
根据评论 - 这是一个线程问题。我还建议将代码移动到单元格的自定义nib文件中。
这是重构的代码:
BBLoaderCell *loaderCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"LoaderCell" forIndexPath:indexPath];
loaderCell.backgroundColor = [UIColor clearColor];
if (self.loadingMore == NO){
dispatch_async(dispatch_get_main_queue(), ^{
activityIndicator.hidden = YES;
[loaderCell.spinner stopAnimating];
});
}
else if (self.loadingMore == YES){
dispatch_async(dispatch_get_main_queue(), ^{
activityIndicator.hidden = NO;
[loaderCell.spinner startAnimating];
});
}
return loaderCell;
这是我需要它的工作。
多谢你们!
我认为这可能与线程有关(例如,主线程上的UI没有准备好为指标设置动画)。您可以尝试以下内容:
[activityIndicator performSelector:@selector(startAnimating:) withObject:nil afterDelay:1];
这只是一个可能的建议,你应该尝试不同的变化,并检查哪一个强制动画正确和及时的动画。另一种变化:
dispatch_async(dispatch_get_main_queue(), ^{
[activityIndicator startAnimating];
});
一个更简洁的解决方案是在willDisplay
委托方法中启动动画:
public func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
(cell as? BBLoaderCell)?.activityIndicatorView.startAnimating()
}
因为在iOS 10或更高版本上,默认情况下启用预取,即使单元格多次滚动进出屏幕,也只能进行1次cellForItemAt调用。当单元格滚出屏幕时,似乎stopAnimating()
被调用(isAnimating
也变成false
)。因此,在单元格第二次进入屏幕后,在cellForItemAt
中使用异步延迟可能会失败。在iOS 11上仍然如此
由于每当单元格进入屏幕时都会调用willDisplay
,我们可以可靠地重新启动动画