2

我是子类化UICollectionViewCell,因为我想将 aUIImageView和 a添加UIProgressView到单元格中:

- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {

        // ImageView
        _imageView = [[UIImageView alloc] initWithFrame:self.bounds];
        _imageView.layer.borderColor = [UIColor whiteColor].CGColor;
        _imageView.layer.borderWidth = 0.7;
        [self.contentView addSubview:_imageView];

        // Progress View
        _progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
        _progressView.frame = CGRectMake(5, self.bounds.size.height - 20, self.bounds.size.width - 10, 10);
        _progressView.hidden = YES;
        [self.contentView addSubview:_progressView];

    }
    return self;
}

当我触摸一个单元格并调用它时,collectionView:didSelectItemAtIndexPath:我设置cell.progressView.hidden = NO;并开始下载和更新progressView.

但是,当我滚动该单元格时,该单元格被重用并且progressView显示在其他单元格上。我尝试了许多不同的方法,只在正确的单元格上显示它,但我尝试过的没有任何效果。

有没有更好的方法来做到这一点,比如做某事prepareForReuse

编辑:根据要求的完整方法

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    PUCViewpointItem *item = [self.items objectAtIndex:indexPath.row];
    PUCImageGridCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CollectionViewCellIdentifier forIndexPath:indexPath];
    [cell.imageView setImageWithURL:[NSURL URLWithString:item.imageURLHigh] placeholderImage:[UIImage imageNamed:@"PUCDefaultBackground.png"]];

    // See if we have the file already
    if (![self.itemPaths objectForKey:item.name]) {
        cell.imageView.alpha = 0.4;
    } else {
        cell.imageView.alpha = 1.0;
    }

    // See if we are downloading
    if (![self.progressItems objectForKey:item.name]) {
        cell.progressView.hidden = YES;
    } else {
        cell.progressView.hidden = NO;
    }

    return cell;
}


- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {

    PUCViewpointItem *item = [self.items objectAtIndex:indexPath.row];
    PUCImageGridCell *cell = (PUCImageGridCell *)[collectionView cellForItemAtIndexPath:indexPath];

    // File Path
    NSString *path = [self itemPath:item];
    if (!path) {

        // Set the indexPath we are downloading
        [self.progressItems setObject:indexPath forKey:item.name];

        Utility *utility = [[Utility alloc] init];
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:item.url]];
        AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

        NSString *localPath = [[utility localDirectory] stringByAppendingFormat:@"/%@.pdf", item.name];
        operation.outputStream = [NSOutputStream outputStreamToFileAtPath:localPath append:NO];

        [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {

            float totalProgress = (float)totalBytesRead/(float)totalBytesExpectedToRead;
            if ([[collectionView indexPathForCell:cell] isEqual:indexPath]) {
                cell.progressView.alpha = 1.0;
                cell.progressView.progress = totalProgress;
            }

        }];
        [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

            // This section seems to not get called or updated correctly when the cell 
            // that is showing the activityView is offscreen
            if ([[collectionView indexPathForCell:cell] isEqual:indexPath]) {
                [self.itemPaths setObject:localPath forKey:item.name];
                [self.progressItems removeObjectForKey:item.name];
                cell.imageView.alpha = 1.0;
                cell.progressView.alpha = 0.0;
            }

        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Error: %@", error);
            [self.progressItems removeObjectForKey:item.name];
            cell.progressView.alpha = 0.0;
        }];

        [operation start];

    } else {

        [self readIssueAtPath:path];

    }

}//end
4

3 回答 3

4

某个项目的下载是否正在进行的信息应该存储在某个数据源(或模型)中,而不是存储在单元格(视图)中。

然后,您可以根据该索引路径中项目的状态在数据源委托方法中更新单元格的外观,collectionView:cellForItemAtIndexPath:并显示或隐藏单元格的进度视图。

添加:进度、完成和失败块都捕获当前单元格。因此,即使已将其用于不同的索引路径,他们也会修改此单元格。为了解决这个问题,您可以检查单元格的(当前)索引路径是否仍然等于原始(捕获的)索引路径:

[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {

    float totalProgress = (float)totalBytesRead/(float)totalBytesExpectedToRead;
    if ([[collectionView indexPathForCell:cell] isEqual:indexPath]) {
       cell.progressView.alpha = 1.0;
       cell.progressView.progress = totalProgress;
    }
}];

和类似的完成和失败块:

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    [self.itemPaths setObject:localPath forKey:item.name];
    [self.progressItems removeObjectForKey:item.name];
    if ([[collectionView indexPathForCell:cell] isEqual:indexPath]) {
        cell.imageView.alpha = 1.0;
        cell.progressView.alpha = 0.0;
    }

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
    [self.progressItems removeObjectForKey:item.name];
    if ([[collectionView indexPathForCell:cell] isEqual:indexPath]) {
        cell.progressView.alpha = 0.0;
    }
}];
于 2013-06-04T17:36:13.153 回答
0

我认为您需要做的只是在您的 didSelectRowAtIndexPath 方法的开头引用一次单元格,并创建一个属性来跟踪选定的 indexPath 和进度指示器的值。下面的方法有效,但我必须创建一个虚拟的慢速方法来测试它,所以我希望你能看到如何适应你的问题。

@interface TableController ()
@property (strong,nonatomic) NSArray *theData;
@property (strong,nonatomic) NSIndexPath *downloadingCellPath;
@property (nonatomic) float progValue;
@end

@implementation TableController

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    RDCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    cell.label.text = self.theData[indexPath.row];
    if ([self.downloadingCellPath isEqual:indexPath]) {
        cell.progView.hidden = NO;
    }else{
        cell.progView.hidden = YES;
    }
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    self.downloadingCellPath = indexPath;
    [self.tableView reloadData];
    [self longMethod:indexPath];
}


-(void)longMethod:(NSIndexPath *) indexPath {
    UIProgressView *activeProgressView = [(RDCell *)[self.tableView cellForRowAtIndexPath:indexPath] progView];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        float x = 0;
        for (int i=0; i < 40000000; i++) {
            x = i * 3.14;
        }

        dispatch_async(dispatch_get_main_queue(), ^{
            self.progValue +=.01;
            activeProgressView.progress = self.progValue;
            if (self.progValue < .99){
                [self longMethod:indexPath];
            }else{
                NSLog(@"done");
                self.downloadingCellPath = nil;
                [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
            }
        });
    });
}
于 2013-06-05T00:07:02.670 回答
-1
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {

    float totalProgress = (float)totalBytesRead/(float)totalBytesExpectedToRead;
    if ([[collectionView indexPathForCell:cell] isEqual:indexPath]) {
       cell.progressView.alpha = 1.0;
       cell.progressView.progress = totalProgress;
    }
}];
于 2016-09-15T10:03:36.727 回答