4

我有一个 UICollectionView,其中 UIActivityIndi​​cator 在加载图像之前显示在单元格中,然后无论 UIImageView+AFNetworking 块中的成功还是失败都会将其关闭。但是,有时我会得到似乎没有隐藏或停止动画的剩余活动指示器。

这是我的 cellForItemAtIndexPath 的一部分:

- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
...
NSURL *imageURL = [NSURL URLWithString:[tmpcamera objectForKey:@"url"]];
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:imageURL cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10];

UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityIndicator.hidesWhenStopped = YES;
activityIndicator.hidden = NO;
activityIndicator.frame = CGRectMake(0, 0, 130, 110);
activityIndicator.tag = 10;

[cell.imageView addSubview:activityIndicator];
[activityIndicator startAnimating];

__weak typeof(FavouriteCell) *weakImage = cell;
[cell.imageView setImageWithURLRequest:imageRequest
                      placeholderImage:[UIImage imageNamed:@"trans50.png"]
                               success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *i)
 {
     [activityIndicator stopAnimating];
     activityIndicator.hidden = YES;
     [activityIndicator removeFromSuperview];
     [weakImage.imageView setImage:i];

 }
                               failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error)
 {
     [activityIndicator stopAnimating];
     activityIndicator.hidden = YES;
     [activityIndicator removeFromSuperview];
     [weakImage.imageView setImage:[UIImage imageNamed:@"errorimage.png"]];
 }];
...
}

我不确定这段代码是否足以调试问题所在,但任何想法都会受到赞赏。

我正在谈论的示例屏幕截图如下:

样本

4

1 回答 1

3

由于您的单元格可能会在图像请求有机会成功或失败(例如通过滚动)之前被回收/重用,因此您最终可能会在单元格中出现“孤立”活动指示器。

事件顺序:

  1. 单元格加载,尝试加​​载图像并启动活动指示器
  2. 用户在图像加载之前滚动。电池被回收。
  3. 该单元被重复使用。添加了一个新的活动指示器,并且之前的图像加载被中止(因此之前的成功/失败块永远不会被调用)。新旧活动指示器现在都在单元格上,旧的活动指示器仍在运行。

避免此问题的一些建议:

  1. 创建一个包含活动指示器的自定义单元格。
  2. 创建活动指示器时,为指示器的 tag 属性分配一个数字,然后在重用单元格时通过 viewWithTag: 查找是否已经存在活动指示器。如果它已经存在,则使用现有的,否则,创建一个新的。
于 2013-10-27T03:31:55.247 回答