我正在对UICollectionViewCell
进行子类化,因为我想在单元格中添加UIImageView
和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
答案 0 :(得分: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;
}
}];
答案 1 :(得分: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];
}
});
});
}
答案 2 :(得分:-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;
}
}];