後的細胞無法顯示正確的圖像所以我難倒就這個問題和不知道該怎麼辦的最好方式,這是。我需要從api下載,存儲核心數據,然後顯示一組tableview的單元格,只有一個標題,描述和圖片(圖片是一個url,所以我也需要下載)。該tableview中只有一個部分iPhone的UITableView,細胞和通知 - 通知
我已經建立了這樣的結構:在我TableViewController我做self.tableview一個監聽到NSNotification(初始化期間指定)。我已經創建了一個自定義單元格視圖,其中一個名爲firstLoad的額外屬性在初始化期間被設置爲YES。在我的tableView cellForRowAtIndexPath中,我正在檢查firstload屬性,如果它設置爲yes,我調用一個函數從url下載圖像。當發生這種情況時,會發出一個通知,由tableviewcontroller中的函數捕獲,我得到indexpathsforvisiblerows,並且如果通知中的行與其中一個indexpathsforvisiblerows數組中的行匹配,那麼我會設置單元格的圖像,然後重新加載Data
我遇到的麻煩是,當我開始滾動tableview時,它看起來像有時圖像設置爲錯誤的單元格。細胞也被重複使用。
我不知道如何準確地處理這個問題。非常感謝您的幫助!
這是的cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"APCell";
APTableViewGenCell *cell = (APTableViewGenCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[APTableViewGenCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier useType:_useType] autorelease];
}
// Configure the cell...
if (APUseTypeGroupsWithEvents == _useType) {
APGroup *group = [_fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = group.name;
UIImage *logoImage = [UIImage imageNamed:@"groups.png"];
if (group.logo.imageURL && (cell.firstLoad == (BOOL *)YES)){
cell.imageView.image = [logoImage scaleToSize:CGSizeMake(kTableImageWidth, kTableImageHeight)];
APGroundControl *gc = [APGroundControl sharedGroundControl];
[gc retrieveImageWithURL:group.logo.imageURL indexPath:indexPath withDefaultImgName:@"groups" andDefaultImgType:@"png" sender:self];
}
cell.detailTextLabel.text = group.groupDescription;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
return cell;
}
代碼這是通知接收處理程序:
- (void)imageRetrieved:(NSNotification *)notification {
NSLog(@"%@", @"NOTIFICATION RECEIVED");
if ([[[notification userInfo] objectForKey:kNewImageDownloadedSenderKey] isEqual:self]) {
// If the cell is still visible show the image.
NSIndexPath *indexPath = [[notification userInfo] objectForKey:kNewImageDownloadedIndexPathKey];
if (indexPath) {
NSArray *indexPaths = [self.tableView indexPathsForVisibleRows];
for (NSIndexPath *path in indexPaths) {
if (indexPath.row == path.row) {
APTableViewGenCell *cell = (APTableViewGenCell *)[self.tableView cellForRowAtIndexPath:path];
NSData *imageData = [[notification userInfo] objectForKey:kNewImageDownloadedDataKey];
UIImage *logoImage = nil;
cell.firstLoad = (BOOL *)NO;
if ([imageData isKindOfClass:[UIImage class]]) {
logoImage = (UIImage *)imageData;
logoImage = [logoImage scaleToSize:CGSizeMake(kTableImageWidth, kTableImageHeight)];
cell.imageView.image = logoImage; // @todo: get rid of this temp check once all image gets moved over to the new retrieve function
}
else {
logoImage = [UIImage imageWithData:imageData];
logoImage = [logoImage scaleToSize:CGSizeMake(kTableImageWidth, kTableImageHeight)];
cell.imageView.image = logoImage;//[UIImage imageWithData:imageData];
}
break;
}
}
[self.tableView reloadData];
}
}
}
,代碼爲retrieveImageWithUrl:
- (void)retrieveImageWithURL:(NSString *)url indexPath:(NSIndexPath *)indexPathOrNil withDefaultImgName:(NSString *)defaultImgName andDefaultImgType:(NSString *) defaultImgType sender:(id)sender {
NSLog(@"%@", @"RETRIEVE IMAGE CALLED");
NSLog(@"%@", indexPathOrNil);
[self queueBlock:^{
NSData *imageData = nil;
// Get image locally
if ([url isEqualToString:kGetGroupDefaultLogoURL]){
NSString *filePath = [[NSBundle mainBundle] pathForResource:defaultImgName ofType:defaultImgType];
imageData = [NSData dataWithContentsOfFile:filePath];
}
// @todo: add a default user logo
else if (url == nil) {
NSLog(@"%@", @"Default Retrieve");
NSString *filePath = [[NSBundle mainBundle] pathForResource:defaultImgName ofType:defaultImgType];
imageData = [NSData dataWithContentsOfFile:filePath];
}
else {
NSLog(@"%@", @"Local Retrieve");
imageData = [_imageCache objectForKey:url];
}
// If local image does not exist get it from the internet
if (imageData == nil) {
NSLog(@"%@", @"Remote Retrieve");
NSLog(@"URL = %@", url);
imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
if (imageData == nil) {
NSString *filePath = [[NSBundle mainBundle] pathForResource:defaultImgName ofType:defaultImgType];
imageData = [NSData dataWithContentsOfFile:filePath];
}
[_imageCache setObject:imageData forKey:url];
}
// Send out notification
NSMutableArray *objects = [NSMutableArray array];
NSMutableArray *keys = [NSMutableArray array];
if (indexPathOrNil) {
[objects addObject:indexPathOrNil];
[keys addObject:kNewImageDownloadedIndexPathKey];
}
[objects addObject:sender];
[keys addObject:kNewImageDownloadedSenderKey];
[objects addObject:imageData];
[keys addObject:kNewImageDownloadedDataKey];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"%@", @"NOTIFICATION SENT");
[[NSNotificationCenter defaultCenter] postNotificationName:kNewImageDownloadedNotification object:self userInfo:userInfo];
});
}];
}
這聽起來好像填充重複使用的單元格有點怪異。但是,沒有任何代碼,它將很難幫助你。我猜,cellForRowAtIndexPath和屬於它的所有代碼都是最有幫助的。 – Phlibbo
@Phlibbo剛剛更新了代碼示例!謝謝參觀!! – MrMaksimize
坦率地說,你的代碼看起來有點混亂,但我試圖理解它。你知道如何重複使用細胞,不是嗎?即使您的表格中有100行,也可能只有6個單元格,這些單元格一次又一次地使用。所以,我認爲你的'firstUsed'屬性有問題。你用它來查看圖像是否已經加載,對嗎?但是如果你只有例如6個單元格(具有6個'firstUsed')屬性,但是有100個圖像,但某些內容會出錯:)我希望在這裏我是正確的,可能還有其他錯誤,但首先請看一下。 – Phlibbo