2

Прежде всего, примерное описание моего приложения - это приложение Magazine Library для конкретной организации.UICollectionView - экземпляр subview, дублированный в других ячейках

  1. У меня есть настроенный UICollectionViewCell, выполненный с прототипом раскадровки. В прототипе 3 вида - UIImageView, UILabel, UILabel.
  2. Кроме того, в collectionView:cellForItemAtIndexPath:, я создал экземпляр

    • UIButton(действие: @selector (downloadButtonTapped :))

    и

    • UIProgressView, где его tag=indexPath.item и hidden=YES. Затем я добавить UIProgressView в массив - self.progressViewArray на же индексом как клетки indexPath.item.
  3. Каждый раз, когда на кнопку «Скачать» для конкретной ячейки отводов и downloadButtonTapped: называется, я получаю клетку и indexPath из надтаблицы в Sender «s SuperView, который является cell. Затем я проверяю, [self.progressViewArray[indexPath.item] tag] == indexPath.item. Если условие выполнено, то выполняется [self.progressViewArray[indexPath.item] setHidden:NO].

У меня есть источник данных из 22 объектов, таким образом, у меня есть 22 ячейки. Все работает так, как я этого хочу. Даже когда я просматриваю вид ячейки (вычеркнутый) и обратно (переработанный), UIProgressView все еще остается.

Проблема:

progressView также появляясь в других клетках! Например. если я нажал кнопку «Загрузить» для ячейки 3, UIProgressView правильно отобразит в этой ячейке HOWEVER, ячейки 10 и 19 также показывают «дублированный» UIProgressView. Эта проблема также относится к другим ячейкам. Например. когда я нажимаю «Загрузить» для ячейки 20, я прокручиваю вверх, и я вижу ячейки 12 и 4 с одинаковыми загрузками UIProgressViews, как если бы эти журналы также загружались.

Почему я упомянул же потому, что у меня есть setDownloadProgressBlock, который обновляет ход UIProgressViews и прогресс клеток 3, 10 и 19 UIProgressViews развиваются вместе.

Я действительно надеюсь, что я могу найти здесь какую-то помощь, поскольку я много раз убивал свои мозги по этой проблеме.

P.S. Отредактированная попытка отладки ниже.


Вот етоды:

CollectionView: cellForItemAtIndexPath:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *identifier = @"Cell"; 
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; 

    // * ========== Configure Cell ========== * 
    // Initialisation of UIImageViews and UILabels here. 
    // ... 

    // CREATION OF CELL'S DOWNLOADBUTTON 
    UIButton *downloadButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    [downloadButton addTarget:self action:@selector(downloadButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; 
    [downloadButton setFrame:CGRectMake(178, 197, 140, 44)]; 
    [downloadButton setTitle:[self setDownloadButtonTitleAtIndexPath:indexPath.item] forState:UIControlStateNormal]; 
    [downloadButton setTitle:@"Downloading..." forState:UIControlStateDisabled]; 
    [downloadButton setEnabled:YES]; 
    [downloadButton setUserInteractionEnabled:YES]; 
    [downloadButton setTag:indexPath.item]; 
    [cell.contentView addSubview:downloadButton]; 


    // CREATION OF CELL'S UIPROGRESSVIEW 
    UIProgressView *progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; 
    [progressView setFrame:CGRectMake(20, 248, 150, 9)]; 
    [progressView setHidden:YES]; 
    [progressView setTag:indexPath.item]; 
    [self.progressViewArray addObject:progressView]; 

    // This chunk is to prevent creating new progress views when the cells are being recycled. 
    if ([self.progressViewArray[indexPath.item] tag] != progressView.tag) 
    { 
     [self.progressViewArray replaceObjectAtIndex:indexPath.item withObject:progressView]; 
    } 

    [cell.contentView addSubview:self.progressViewArray[indexPath.item]]; 
    // * ---------- Configure Cell ---------- * 

    return cell; 
} 

downloadButtonTapped:

- (IBAction)downloadButtonTapped:(id)sender 
{ 
    // Get the indexPath of tapped row. 
    UICollectionViewCell *cell = (UICollectionViewCell *)[[sender superview] superview]; 
    NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell]; 

    // If file does not exist. 
    if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) 
    { 
     // SHOW THE CELL'S HIDDEN UIPROGRESSVIEW 
     if ([self.progressViewArray[indexPath.item] tag] == indexPath.item) 
     { 
      [self.progressViewArray[indexPath.item] setHidden:NO]; 
     } 


     // AFHTTPRequestionOperation code here... 

     // Track download progress. 
     [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) 
     { 
      for (UIProgressView *progressView in self.progressViewArray) 
      { 
       if (progressView.tag == indexPath.item) 
       { 
        [progressView setProgress:(float) totalBytesRead/totalBytesExpectedToRead]; 
       } 
      } 
     }]; 

     // Post download codes etc ... 

     [operation start]; 
    } 
} 

Спасибо вы для своего времени люди. Я ценю это ...

Edit:

В очередной попытке отладки, я сделал NSLog(@"%@ at indexPath #%d", self.progressViewArray[indexPath.item], indexPath.item); непосредственно перед return cell; только, чтобы подтвердить, что UIProgressView только выжатой ячейки влияет (setHidden = NO) и на самом деле это является.

I похлопал ячейка 3 закачек кнопку, прокручивается на дно и назад к началу в CollectionView, , как обычно, видя, как если ячейка 10 и 19 в progressViews активны слишком, и это то, что Я зарегистрировался. Как вы можете видеть, в то время как загрузка активна, журнал показывает, что ТОЛЬКО ПРОСМОТР ячейки 3 (тег = 3) является (setHidden = NO). Ячейки 10 и 19 все еще скрыты/не затронуты. Но я не понимаю, почему я вижу активный progressView.

Вот лог:

2013-08-17 10:59:33.179 SFCCA[22885:907] <UIProgressView: 0x1c5bca00; frame = (20 248; 150 9); hidden = YES; opaque = NO; layer = <CALayer: 0x1c5d1000>> at indexPath #0 
2013-08-17 10:59:33.187 SFCCA[22885:907] <UIProgressView: 0x1c59c7c0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 1; layer = <CALayer: 0x1c5bb310>> at indexPath #1 
2013-08-17 10:59:33.193 SFCCA[22885:907] <UIProgressView: 0x1c5aa1f0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 2; layer = <CALayer: 0x1c5aa270>> at indexPath #2 
2013-08-17 10:59:33.201 SFCCA[22885:907] <UIProgressView: 0x1c5b9860; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 3; layer = <CALayer: 0x1c5b9a30>> at indexPath #3 
2013-08-17 10:59:33.207 SFCCA[22885:907] <UIProgressView: 0x1c5aa670; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 4; layer = <CALayer: 0x1c5b8d60>> at indexPath #4 
2013-08-17 10:59:33.214 SFCCA[22885:907] <UIProgressView: 0x1c5b51d0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 5; layer = <CALayer: 0x1c5b5270>> at indexPath #5 

// Here, I have tapped cell 3's "Download" button. 
// Notice that at the bottom of the log, when I have scrolled off cell 3 and back, the log shows that the progressView (tag=3) in cell 3 is hidden=NO 
2013-08-17 10:59:43.389 SFCCA[22885:907] {downloadButtonTapped} - File does not exist. Download then read PDF. 
2013-08-17 10:59:43.929 SFCCA[22885:907] <UIProgressView: 0x1c5d5a10; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 6; layer = <CALayer: 0x1c5b4420>> at indexPath #6 
2013-08-17 10:59:43.938 SFCCA[22885:907] <UIProgressView: 0x1c5cd8e0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 7; layer = <CALayer: 0x1c5b68d0>> at indexPath #7 
2013-08-17 10:59:44.216 SFCCA[22885:907] <UIProgressView: 0x1d8c3b90; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 8; layer = <CALayer: 0x1d8c3c30>> at indexPath #8 
2013-08-17 10:59:44.223 SFCCA[22885:907] <UIProgressView: 0x1c5e08d0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 9; layer = <CALayer: 0x1c5b9330>> at indexPath #9 
2013-08-17 10:59:44.600 SFCCA[22885:907] <UIProgressView: 0x1d8c9aa0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 10; layer = <CALayer: 0x1d8c9480>> at indexPath #10 
2013-08-17 10:59:44.607 SFCCA[22885:907] <UIProgressView: 0x1d8cb590; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 11; layer = <CALayer: 0x1d8cb4b0>> at indexPath #11 
2013-08-17 10:59:45.160 SFCCA[22885:907] <UIProgressView: 0x1d8b9e20; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 12; layer = <CALayer: 0x1d8a6140>> at indexPath #12 
2013-08-17 10:59:45.171 SFCCA[22885:907] <UIProgressView: 0x1d8cc060; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 13; layer = <CALayer: 0x1d8ca870>> at indexPath #13 
2013-08-17 10:59:45.813 SFCCA[22885:907] <UIProgressView: 0x1d88dc10; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 14; layer = <CALayer: 0x1d88dc90>> at indexPath #14 
2013-08-17 10:59:45.822 SFCCA[22885:907] <UIProgressView: 0x1d8cc9e0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 15; layer = <CALayer: 0x1d872110>> at indexPath #15 
2013-08-17 10:59:46.154 SFCCA[22885:907] <UIProgressView: 0x1c5ed300; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 16; layer = <CALayer: 0x1c5ed280>> at indexPath #16 
2013-08-17 10:59:46.162 SFCCA[22885:907] <UIProgressView: 0x1c5eeae0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 17; layer = <CALayer: 0x1c5eea00>> at indexPath #17 
2013-08-17 10:59:46.652 SFCCA[22885:907] <UIProgressView: 0x1c5ee0f0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 18; layer = <CALayer: 0x1c5e35f0>> at indexPath #18 
2013-08-17 10:59:46.660 SFCCA[22885:907] <UIProgressView: 0x1c5efc70; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 19; layer = <CALayer: 0x1c5ee320>> at indexPath #19 
2013-08-17 10:59:46.903 SFCCA[22885:907] <UIProgressView: 0x1c5e8b30; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 20; layer = <CALayer: 0x1c5e4aa0>> at indexPath #20 
2013-08-17 10:59:46.914 SFCCA[22885:907] <UIProgressView: 0x1c5e8fd0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 21; layer = <CALayer: 0x1c5e7e50>> at indexPath #21 
2013-08-17 10:59:48.583 SFCCA[22885:907] <UIProgressView: 0x1d88dc10; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 14; layer = <CALayer: 0x1d88dc90>> at indexPath #14 
2013-08-17 10:59:48.590 SFCCA[22885:907] <UIProgressView: 0x1d8cc9e0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 15; layer = <CALayer: 0x1d872110>> at indexPath #15 
2013-08-17 10:59:49.118 SFCCA[22885:907] <UIProgressView: 0x1d8b9e20; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 12; layer = <CALayer: 0x1d8a6140>> at indexPath #12 
2013-08-17 10:59:49.127 SFCCA[22885:907] <UIProgressView: 0x1d8cc060; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 13; layer = <CALayer: 0x1d8ca870>> at indexPath #13 
2013-08-17 10:59:49.730 SFCCA[22885:907] <UIProgressView: 0x1d8c9aa0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 10; layer = <CALayer: 0x1d8c9480>> at indexPath #10 
2013-08-17 10:59:49.736 SFCCA[22885:907] <UIProgressView: 0x1d8cb590; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 11; layer = <CALayer: 0x1d8cb4b0>> at indexPath #11 
2013-08-17 10:59:50.106 SFCCA[22885:907] <UIProgressView: 0x1d8c3b90; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 8; layer = <CALayer: 0x1d8c3c30>> at indexPath #8 
2013-08-17 10:59:50.113 SFCCA[22885:907] <UIProgressView: 0x1c5e08d0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 9; layer = <CALayer: 0x1c5b9330>> at indexPath #9 
2013-08-17 10:59:50.643 SFCCA[22885:907] <UIProgressView: 0x1c5d5a10; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 6; layer = <CALayer: 0x1c5b4420>> at indexPath #6 
2013-08-17 10:59:50.649 SFCCA[22885:907] <UIProgressView: 0x1c5cd8e0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 7; layer = <CALayer: 0x1c5b68d0>> at indexPath #7 
2013-08-17 10:59:50.967 SFCCA[22885:907] <UIProgressView: 0x1c5aa670; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 4; layer = <CALayer: 0x1c5b8d60>> at indexPath #4 
2013-08-17 10:59:50.973 SFCCA[22885:907] <UIProgressView: 0x1c5b51d0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 5; layer = <CALayer: 0x1c5b5270>> at indexPath #5 
2013-08-17 10:59:51.593 SFCCA[22885:907] <UIProgressView: 0x1c5aa1f0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 2; layer = <CALayer: 0x1c5aa270>> at indexPath #2 
2013-08-17 10:59:51.598 SFCCA[22885:907] <UIProgressView: 0x1c5b9860; frame = (20 248; 150 9); opaque = NO; tag = 3; layer = <CALayer: 0x1c5b9a30>> at indexPath #3 
2013-08-17 10:59:51.983 SFCCA[22885:907] <UIProgressView: 0x1c5bca00; frame = (20 248; 150 9); hidden = YES; opaque = NO; layer = <CALayer: 0x1c5d1000>> at indexPath #0 
2013-08-17 10:59:51.995 SFCCA[22885:907] <UIProgressView: 0x1c59c7c0; frame = (20 248; 150 9); hidden = YES; opaque = NO; tag = 1; layer = <CALayer: 0x1c5bb310>> at indexPath #1 

ответ

3

Удалось решить эту проблему после 2 недель борьбы. Простое решение, но я не думал об этом раньше.

У меня есть свойство следующим образом: @property (strong, nonatomic) NSMutableArray *progressViewsArray;. Не забудьте выделить и инициализировать его. Я сделал это в viewDidLoad.

В collectionView:cellForItemAtIndexPath: я использовал следующую логику перед возвратом ячейки.

for (UIProgressView *progressView in cell.contentView.subviews) 
{ 
    if ([progressView isKindOfClass:[UIProgressView class]]) 
    { 
     [progressView removeFromSuperview]; 
    } 
} 
for (UIProgressView *progressView in self.progressViewsArray) 
{ 
    if (progressView.tag == indexPath.item) 
    { 
     [cell.contentView addSubview:progressView]; 
    } 
} 

В downloadButtonTapped:, это то, как я создал экземпляр UIProgressView:

UIProgressView *progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault]; 
progressView.frame = CGRectMake(178, 180, 170, 9); 
[progressView setTag:indexPath.item]; 
[cell.contentView addSubview:progressView]; 
[self.progressViewsArray addObject:progressView]; 

В setDownloadProgressBlock AFNetworking (в downloadButtonTapped:):

float progress = (float) totalBytesRead/totalBytesExpectedToRead; 
[progressView setProgress:progress]; 

И, наконец, в setCompletionBlock AFNetworking (в downloadButtonTapped:):

NSMutableArray *progressViewsToDelete = [[NSMutableArray alloc] init]; 
for (UIProgressView *pv in self.progressViewsArray) 
{ 
    if (pv.tag == indexPath.item) 
    { 
     [progressViewsToDelete addObject:pv]; 
    } 
} 
if (progressViewsToDelete.count > 0) 
{ 
    [self.progressViewsArray removeObjectsInArray:progressViewsToDelete]; 
} 
[self.collectionView reloadItemsAtIndexPaths:@[indexPath]]; // To reflect changes. 

Надеется, что это помогает кто-то в будущем, Ура!

+0

gr8 человек .. работал .. –

+0

вы действительно должны просто делать это в prepareForReuse в своем подклассе ячейки. – Lance

0

Вы должны добавить все представления в ячейку прототипа и просто установить некоторые из них должны быть скрыты. В частности, хотя в collectionView:cellForItemAtIndexPath: вы должны установить атрибут hidden всех видов, которые вы настраиваете, чтобы сделать их видимыми при необходимости и скрыть их, когда это не требуется. Тогда не имеет значения, является ли ячейка новой или используется повторно, вы всегда гарантируете, что будут видны правильные виды.

В вашем текущем решении у вас есть некоторая логика, чтобы предотвратить создание новых представлений прогресса, если у вас уже есть. Но вы никогда не удаляете какие-либо представления прогресса из ячеек. Поэтому, когда вы повторно используете ячейку, у нее все еще может быть представление прогресса в качестве подчиненного. Использование метода скрытия представления или его отображения (и установка значения прогресса) позволит избежать этого.

+0

Hi @Wain благодарит за ваш ответ. Я не включил UIProgressView в ячейку прототипа, потому что я понимаю, что мне нужно назначить каждый тег UIProgressView * indexPath.item *, чтобы я мог идентифицировать, какой UIProgressView должен отображать **. В логике, чтобы предотвратить создание новых UIProgressViews, он делает то, что я хочу - когда ячейка, которую я набрала, получает свитки от просмотра и обратно, тот же UIProgressView по-прежнему существует и загружается. Проблема в том, что тот же UIProgressView также появляется в других ячейках, когда я даже не указывал indexPath этих ячеек. Что я здесь делаю неправильно? Благодарю. –

0

У меня есть аналогичная проблема. И я решил это. Вы изменили subviews ячейки в этом методе: - (IBAction)downloadButtonTapped:(id)sender, и вы не обновили этот подсмотр до метода: collectionView:cellForItemAtIndexPath:. Когда ячейки повторного использования работали, он просто извлекает представления из этого метода: collectionView:cellForItemAtIndexPath: и которые не включают в себя подпункты, измененные вне этого метода, поэтому вы должны что-то сделать в методе collectionView:cellForItemAtIndexPath:, чтобы обновить свои изменения в подзонах ячейки. Я надеюсь, что это все равно поможет вам.

+0

Извините, я не понимаю, о чем вы говорите, я не обновлял подзаголовок ячейки в 'collectionView: cellForItemAtIndexPath:'. Я думал, что уже сделал, когда '[cell.contentView addSubview: self.progressViewArray [indexPath.item]];'? –

Смежные вопросы