Индикатор UIActivity в пользовательской ячейке в раскадровке

Я добавил IBOutlet UIActivityIndicator в пользовательскую ячейку, но он не отображается в каждой ячейке, только в первых 2-3, а затем ничего. Другое дело, когда я прокручиваю таблицу и возвращаюсь к первым 3 ячейкам, UIActivityIndicator тоже исчезает из этих ячеек...

Код:

Ячейка.ч

@interface Cell : UITableViewCell

@property (strong, nonatomic) IBOutlet UIImageView *image;
@property (strong, nonatomic) IBOutlet UILabel *label;
@property (strong, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;

@end

Сот.м

@implementation Cell

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self)
    {
        // change to our custom selected background view
    }
    return self;
}

@end

В раскадровке UIactivityIndicator имеет значение: Поведение: - Анимация

в целях тестирования...

а также:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"CustomCell";
    Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // load the image for this cell
    Wallpaper *wallpaper = [xmlParser.wallpapers objectAtIndex:indexPath.row];

    cell.label.text = wallpaper.title;
    NSString *imageToLoad = wallpaper.thumbnail;

    [cell.image setImageWithURL:[NSURL URLWithString:imageToLoad] placeholderImage:nil options:SDWebImageProgressiveDownload progress:^(NSUInteger receivedSize, long long expectedSize)
     {

     }
                          completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)
     {
         //[cell.activityIndicator stopAnimating];
     }];

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
                                     initWithTarget:self action:@selector(tapped:)];
    [cell.image addGestureRecognizer:tap];
    [cell.image setTag:indexPath.row];

    CALayer * l = [cell.image layer];
    [l setMasksToBounds:YES];
    [l setCornerRadius:5.0];
    cell.layer.cornerRadius = 7.0;


    return cell;
}

person 1337code    schedule 10.12.2012    source источник
comment
Вы также можете создать UIIndicatorView из кода, а не из IB. Похоже, что повторное использование не работает должным образом или не назначено ячейке в IB. Здесь может произойти несколько вещей.   -  person Mark McCorkle    schedule 11.12.2012
comment
Да, я знаю о UITapGestureRecognizer, я пытался установить свойство (неатомарное, сильное) UITapGestureRecognizer *tap; в заголовочный файл и загрузить его в viewDidLoad, но это работает не очень хорошо, не работает для каждой ячейки. Роб, у тебя есть скайп? Мне действительно не помешала бы помощь с этим, я застрял на этом в течение 2 дней.   -  person 1337code    schedule 11.12.2012
comment
@MarkM, он назначен IBOutlet, но работает только с первыми 3 ячейками, я попытаюсь создать его в коде   -  person 1337code    schedule 11.12.2012


Ответы (3)


  1. Если вы закомментируете весь фрагмент кода, где вы выполняете setImageWithURL, успешно ли вы получите свой анимированный индикатор активности во всех строках вашей таблицы? Давайте сначала убедимся, что ваш UIActivityIndicatorView работает правильно. Если это работает, когда вы закомментируете setImageWithURL, то проблема явно в этом. Если это не работает, даже когда вы отключаете setImageWithURL, у вас есть более фундаментальная проблема. Давайте удостоверимся, что вы успешно запускаете индикатор активности. Насколько я понимаю, вы включаете его в IB, но я действительно предлагаю вручную включить его (когда это уместно) в cellForRowAtIndexPath и не полагаться на то, что он будет запущен для вас.

  2. В вашем завершенном блоке вы действительно должны проверить, чтобы убедиться, что рассматриваемая ячейка все еще находится на экране и не была удалена из очереди и повторно использована (например, вызов cell = [tableView cellForRowAtIndexPath:indexPath] и подтверждение значения, отличного от nil), потому что я предполагаю, что ваш setImageWithURL работает асинхронно. (Примечание: этот метод экземпляра UITableView, cellForRowAtIndexPath, не следует путать с методом UITableViewController с таким же названием.) Такая логика, предполагающая, что ячейка все еще находится на экране, может быть проблематичной, когда вы выполняете асинхронные операции с ячейками таблицы. Когда я слышу о том, что какое-то асинхронное обновление не обновляется должным образом, я беспокоюсь о ячейках, удаленных из очереди. (См. мой пункт № 3 в этом ответе на переполнение стека для пример того, как проверить, видна ли ячейка; это немного другой ответ, но он дает вам пример проблемы, о которой вам нужно подумать.)

  3. Не связано, но я бы не стал каждый раз добавлять UITapGestureRecognizer. Разве вы не рискуете ячейкой, которая была удалена из очереди и повторно использована дюжину раз, имея дюжину распознавателей жестов касания? Лучше сделать это в вашем подклассе UITableViewCell. Обычно я делаю это в layoutSubviews (не сработает, если вы попытаетесь сделать это в своих методах init, потому что изображения еще не будет).

person Rob    schedule 10.12.2012

Пытаться...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
     static NSString *CellIdentifier = @"CustomCell";
    Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    cell.activityIndicator.hidden = NO;
    [cell.activityIndicator startAnimating];
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:.1]];

    // load the image for this cell
    Wallpaper *wallpaper = [xmlParser.wallpapers objectAtIndex:indexPath.row];

    cell.label.text = wallpaper.title;
    NSString *imageToLoad = wallpaper.thumbnail;

    [cell.image setImageWithURL:[NSURL URLWithString:imageToLoad] placeholderImage:nil options:SDWebImageProgressiveDownload progress:^(NSUInteger receivedSize, long long expectedSize)
     {

     }
                      completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)
     {
         //[cell.activityIndicator stopAnimating];
     }];

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
                                 initWithTarget:self action:@selector(tapped:)];
    [cell.image addGestureRecognizer:tap];
    [cell.image setTag:indexPath.row];

    CALayer * l = [cell.image layer];
    [l setMasksToBounds:YES];
    [l setCornerRadius:5.0];
    cell.layer.cornerRadius = 7.0;


    return cell;
}
person Mark McCorkle    schedule 10.12.2012

NINetworkImageView *imageView=[[NINetworkImageView alloc]init];
imageView.delegate=self;
[imageView setPathToNetworkImage:[NSString stringWithStdString:imageUrl]];

Используйте сторонний класс для решения этой задачи.

person Manish Saini    schedule 29.04.2014