ActivityIndicator не останавливает анимацию и не удаляется из супервизора в UICollectionViewCell.

Я пытаюсь реализовать UICollectionView и показывать изображения. Я использую SDWebimage, который отлично работает в tableviewcells, но когда я попытался использовать его в UICollectionviewCell, он не останавливается и не удаляет индикатор активности. Он размещает изображение-заполнитель, если загруженного изображения нет. Я не уверен, в чем разница между tableviewcell и collectionviewcell, которая может вызвать эту проблему.

Вот код:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"personImageCell";

    PersonCollectionViewCell *cell = (PersonCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
    Person *person = [self.fetchedResultsController objectAtIndexPath:indexPath];
    NSString *imgURL=[person.imageurl stringByAppendingString:@"?maxheight=300&maxwidth=400"];

    UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
    activityIndicator.hidesWhenStopped = YES;
    activityIndicator.hidden = NO;
    [activityIndicator startAnimating];
    activityIndicator.center = CGPointMake(cell.ivPersonImage.frame.size.width /2, cell.ivPersonImage.frame.size.height/2);
    [cell.ivPersonImage setImageWithURL:[NSURL URLWithString:imgURL] placeholderImage:nil options:SDWebImageProgressiveDownload success:^(UIImage *image, BOOL cached){
        [activityIndicator stopAnimating];[activityIndicator removeFromSuperview];
        NSLog(@"activity indicator should be removed");
    }failure:^(NSError *error){
        [activityIndicator stopAnimating];[activityIndicator removeFromSuperview];
        cell.ivPersonImage.image = [UIImage imageNamed:@"placeholder.png"];
    }];


    [cell.ivPersonImage addSubview:activityIndicator];
    return cell;
}

ОБНОВИТЬ:

Когда я делаю NSLog(@"activity indicator should be removed %@,activityIndicator);

Я получаю этот вывод:

 activity indicator should be removed <UIActivityIndicatorView: 0xa520ab0; frame = (65 90; 20 20); hidden = YES; layer = <CALayer: 0xa520b60>> 

Он показывает, что UIActivityindicator скрыт, но все еще отображается поверх изображения.


person Yan    schedule 12.10.2012    source источник
comment
Я хотел бы знать, почему голосование против? Спасибо!   -  person Yan    schedule 13.10.2012
comment
Итак, вы не видите загруженное изображение? Или изображение не скачивается и поэтому не убирается индикатор активности?   -  person Nekto    schedule 15.10.2012
comment
Спасибо за ответ! Я вижу изображение и получаю индикатор активности сверху в некоторых ячейках не во всех, а в некоторых ячейках индикатор активности заморожен   -  person Yan    schedule 15.10.2012
comment
Попробуйте разместить эту строку [cell.ivPersonImage addSubview:activityIndicator]; перед установкой изображения в setImageWithURL...   -  person Nekto    schedule 15.10.2012
comment
@Nekto Спасибо за ответ, но это не сработало. Странная часть заключается в том, что когда изображение кэшируется и помещается в ячейку, индикатор активности останавливается и скрывается только тогда, когда изображение загружается, тогда индикатор не скрывается.   -  person Yan    schedule 17.10.2012
comment
добавил некоторые обновления в вопрос.   -  person Yan    schedule 17.10.2012


Ответы (3)


Кажется, вы повторно используете ячейку, поэтому UIActivityIndicatorView больше одного.

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"personImageCell";

    PersonCollectionViewCell *cell = (PersonCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
    Person *person = [self.fetchedResultsController objectAtIndexPath:indexPath];
    NSString *imgURL=[person.imageurl stringByAppendingString:@"?maxheight=300&maxwidth=400"];

    UIActivityIndicatorView *activityIndicator = [cell.ivPersonImage viewWithTag:10];
    if (activityIndicator) [activityIndicator removeFromSuperview];
    activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
    activityIndicator.hidesWhenStopped = YES;
    activityIndicator.hidden = NO;
    [activityIndicator startAnimating];
    activityIndicator.center = cell.ivPersonImage.center;
    activityIndicator.tag = 10;

    [cell.ivPersonImage addSubview:activityIndicator];
    [cell.ivPersonImage setImageWithURL:[NSURL URLWithString:imgURL] placeholderImage:nil options:SDWebImageProgressiveDownload success:^(UIImage *image, BOOL cached){
        [activityIndicator stopAnimating];[activityIndicator removeFromSuperview];
        NSLog(@"activity indicator should be removed");
    }failure:^(NSError *error){
        [activityIndicator stopAnimating];[activityIndicator removeFromSuperview];
        cell.ivPersonImage.image = [UIImage imageNamed:@"placeholder.png"];
    }];

    return cell;
}
person Nekto    schedule 17.10.2012
comment
Вы попали прямо в деньги! Большое спасибо! Я бы никогда не подумал, что это проблема. Я делал nslog, но не в тех местах. Когда я поставил nslog прямо перед ячейкой возврата, он показал несколько ячеек с двумя индикаторами активности. Единственное, что мне нужно было сделать, это привести UIActivityIndicatorView, когда я делал [cell.ivPersonImage viewWithTag:10]. Странно, что с tableview он работает отлично. Я думаю, что у collectionview немного другой механизм. Еще раз огромное спасибо! - person Yan; 18.10.2012

Хм.... это странно... можете ли вы попытаться убедиться, что индикатор активности работает в основном потоке -

[cell.ivPersonImage setImageWithURL:[NSURL URLWithString:imgURL] placeholderImage:nil options:SDWebImageProgressiveDownload success:^(UIImage *image, BOOL cached){
        dispatch_async(dispatch_get_main_queue(), ^(void){
            [activityIndicator stopAnimating];
            [activityIndicator removeFromSuperview];
        }
        NSLog(@"activity indicator should be removed");
    }failure:^(NSError *error){
        dispatch_async(dispatch_get_main_queue(), ^(void){
            [activityIndicator stopAnimating];
            [activityIndicator removeFromSuperview];
        }
        cell.ivPersonImage.image = [UIImage imageNamed:@"placeholder.png"];
    }];

Я подозреваю, что это не так, поэтому он не останавливает свою анимацию.

person yeesterbunny    schedule 15.10.2012
comment
Спасибо за ответ. Я только что смог попробовать, и все та же проблема. Это что-то в реализации uicollectionview, потому что с uitableview он отлично работает. - person Yan; 16.10.2012
comment
Можете ли вы также поместить объявление activityIndicator и startAnimating в основной поток с помощью dispatch_async. У меня была аналогичная проблема, когда индикатор активности просто не исчезал. Я решил это, убедившись, что все UIKit обрабатываются в основном потоке. - person yeesterbunny; 17.10.2012

Создайте индикатор активности в ViewDidLoad текущего контроллера представления.

UIActivityIndicatorView *spinner = [[UIActivityIndicatorView      alloc]initWithFrame:CGRectMake(150, 225, 20, 30)];
[spinner setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
spinner.color = [UIColor blueColor];
[self.view addSubview:spinner];

Используйте приведенный ниже код прямо в начале функции, которая ведет к действию

[NSThread detachNewThreadSelector:@selector(threadStartAnimating:) toTarget:selfwithObject:nil];

Объявите эти два метода запуска и остановки анимации.

-(void)threadStartAnimating:(id)data
{
[spinner startAnimating];
}


-(void)threadStopAnimating:(id)data
{
[spinner stopAnimating];
}

Пожалуйста, дайте отзыв, так как этот код отлично работает в моем собственном проекте.

person Varun    schedule 22.01.2014