gpt4 book ai didi

Iphone UITableView、单元格和通知 - 通知后单元格未显示正确的图像

转载 作者:行者123 更新时间:2023-11-29 04:57:08 25 4
gpt4 key购买 nike

所以我对这个问题感到困惑,不确定最好的方法是什么。我需要从 api 下载,存储在核心数据中,然后显示 tableview 的一组单元格,其中只有标题、描述和图片(图片是一个 url,所以我也需要下载它)。表格 View 只有一个部分

我已经设置了一个结构,在 TableViewController 中我将 self.tableview 作为 NSNotification 的监听器(在 init 期间指定)。我创建了一个自定义单元格 View ,其中有一个名为firstLoad 的额外属性,该属性在初始化期间设置为YES。在我的 tableView cellForRowAtIndexPath 中,我正在检查 firSTLoad 属性,如果它设置为 yes,我将调用一个函数来从 url 下载图像。发生这种情况时,会发出一条通知,由 tableviewcontroller 中的函数捕获,我会获取 indexpathsforvisiblerows,如果通知中的行与 indexpathsforvisiblerows 数组之一中的行匹配,我会设置单元格的图像,然后重新加载数据

我遇到的麻烦是,当我开始滚动表格 View 时,看起来有时图像被设置为错误的单元格。这些电池也被重复利用。

我不知道如何准确处理这个问题。非常感谢您的帮助!!

这是 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];
});
}];
}

最佳答案

好吧,首先,您使用的 firstLoad 标志没有意义。您需要知道您的图像是否已加载,但由于可重复使用的单元格无法与特定图像连接,因此这不是执行此操作的方法。

您更新了帖子几次,到目前为止,尚不清楚您当前的问题是什么。因此,我将为您提供一个正确且干净的解决方案:首先,您需要一个存储图像的地方。 NSMutableDictionary 就可以了。使用键来存储您的 URL,使用值来存储图像。当您输入新单元格时,请查看该 URL 是否已在字典中。如果是,则填写即可。否则,开始加载过程。如果这样做,您还应该在字典中创建一个新条目,该条目存储图像的 URL 和 nil。这可以帮助您避免两次加载尚未准备好的图像。在“加载完成”方法中,将 nil 值替换为图像。应该是这样。当然,您需要根据您的具体需求定制这些步骤,但这应该不是什么大问题。希望这有帮助!

PS:此外,您应该检查代码以查找冗余或过于复杂的调用。在不知道您的具体设置的情况下,迭代 NSIndexPath 看起来很奇怪,您应该能够直接访问您的值。

关于Iphone UITableView、单元格和通知 - 通知后单元格未显示正确的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7726026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com