8

我正在使用SDWebImage和抓取与来自新闻 API 的新闻文章相关联的图像。

问题是,屏幕上单元格的图像直到我开始滚动UITableView. 一旦我滚动过一个单元格,它就会离开屏幕,一旦我回到它,图像最终会被加载。

这是我的(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath代码:

if ([feedLocal.images count] == 0) {
    [cell.imageView setImage:[UIImage imageNamed:@"e.png"]];
}
else {    
    Images *imageLocal = [feedLocal.images objectAtIndex:0];
    NSString *imageURL = [NSString stringWithFormat:@"%@", imageLocal.url];
    NSLog(@"img url: %@", imageURL);

    // Here we use the new provided setImageWithURL: method to load the web image
    __weak UITableViewCell *wcell = cell;
    [cell.imageView setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@", imageURL]]
                   placeholderImage:[UIImage imageNamed:@"115_64.png"]
                          completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
                              if(image == nil) {
                                  [wcell.imageView setImage:[UIImage imageNamed:@"115_64.png"]];
                                   //];
                              }
                          }
    ];
}

知道为什么会发生这种情况吗?似乎当 UITableView 加载时,图像没有被告知加载或其他什么,直到滚动开始?

任何建议都非常感谢,谢谢!

4

4 回答 4

5

这几乎不可能解决您的问题,但这太长了,无法放入评论中:

提示1:

如果您正在重用单元格,则不应[wcell.imageView setImage:]在回调中执行此操作。在执行回调代码时,有一个非空机会wcell指向表格视图中的不同单元格,而不是您想要更改图像的单元格。

相反,使用indexPath来引用您要修改的单元格:

completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
    if(image == nil) {
        UITableViewCell *actualCell = [tableView cellForRowAtIndexPath:indexPath];
        [actualCell.imageView setImage:[UIImage imageNamed:@"115_64.png"]];
    }
}

请注意,如果您要更改图像的单元格不再显示,cellForRowAtIndexPath:将返回nil,这绝对没问题:

返回值

表示表格单元格的对象,如果单元格不可见或 indexPath 超出范围,则为 nil。

提示2:

当您已经有一个字符串时,无需重新创建一个字符串;)

[NSURL URLWithString:[NSString stringWithFormat:@"%@", imageURL]]

[NSURL URLWithString:imageURL] // imageURL is already a string

你的问题

我有点疑惑,你展示的代码真的是SDWebImage“how-to”示例的简单应用,我刚刚用框架的 v3.3 进行了测试,我的单元格更新得很好。因此,请尝试将您的代码减少到最低限度以识别真正的问题。

我想说摆脱所有应用程序逻辑(feedLocal.images例如),然后找出问题是否真的来自SDWebImage

于 2013-07-04T20:32:53.810 回答
1

不确定您是否解决了问题,但我通过以下代码解决了我的问题。

基本思想是在块内设置可用的单元格引用,并在完成方法中手动设置单元格的图像。希望能帮助到你。

__block UITableViewCell *cell2 = cell;

id data = [[self itemArray] objectAtIndex:[indexPath item]];

if ([data isKindOfClass:[MyItems class]]) {

    MyItems *myData = (MyItems *)data;
    [[cell2 imageView] setImageWithURL:[myData url]
                      placeholderImage:[UIImage imageNamed:@"placeHolder.png"]
                             completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
                                 // do check that this is the right cell to put your image
                                 // your methods here

                                 if (image) {
                                     [[cell2 imageView] setImage:image];
                                 }
    }];
}

为了检查这是否是正确的单元格,我想它是这样的(我没有时间检查它)

__block UITableViewCell *cell2 = cell;

id data = [[self itemArray] objectAtIndex:[indexPath item]];

if ([data isKindOfClass:[MyItems class]]) {

    __block MyItems *myData = (MyItems *)data;
    [[cell2 imageView] setImageWithURL:[myData url]
                      placeholderImage:[UIImage imageNamed:@"placeHolder.png"]
                             completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
                                 // do check that this is the right cell to put your image
                                 // your methods here
                                 id currentData = [[self itemArray] objectAtIndex:[indexPath item]];
                                 if ([currentData isKindOfClass:[MyItems class]] && [ [[(MyItems *)currentData url] absoluteString] isEqualToString:[[myData url] absoluteString] ]) {
                                 // it is the right cell to put in :)
                                     if (image) {
                                         [[cell2 imageView] setImage:image];
                                     }
                                 }
    }];
}
于 2013-07-19T08:31:50.983 回答
0

我之前遇到过类似的问题,结果发现 tableview 中的图像下载正确。您面临的真正问题是刷新问题。下载每个图像时,必须刷新它才能在 tableview 中显示。在我的例子中,下载部分是在一个单独的文件中完成的,所以我使用 NSNotificationCenter 告诉 tableview 控制器类刷新它。以下是您可以使用代码执行的操作:

if ([feedLocal.images count] == 0) {
    [cell.imageView setImage:[UIImage imageNamed:@"e.png"]];
}
else {    
    Images *imageLocal = [feedLocal.images objectAtIndex:0];
    NSString *imageURL = [NSString stringWithFormat:@"%@", imageLocal.url];
    NSLog(@"img url: %@", imageURL);

    // Here we use the new provided setImageWithURL: method to load the web image
    __weak UITableViewCell *wcell = cell;
    [cell.imageView setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@", imageURL]]
                   placeholderImage:[UIImage imageNamed:@"115_64.png"]
                          completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
                              if(image == nil) {
                                  [wcell.imageView setImage:[UIImage imageNamed:@"115_64.png"]];
                                  [[NSNotificationCenter defaultCenter] postNotificationName:@"ImageDownloaded" object:nil];
                                   //];
                              }
                          }
    ];
}

然后您可以使用它调用重新加载数据,如下所示:

- (void) imageDownloaded:(NSNotification *)notification{

    [self.tableView reloadData];
}

这样,您无需滚动即可查看图像,而是在下载后立即显示。

希望这可以帮助!

于 2013-07-07T20:11:42.837 回答
0
NSString *mainimg=[NSString stringWithFormat:@"%@",[[xmlDataDictionary valueForKeyPath:@"eg.main.img1"]objectAtIndex:indexPath.row]];
NSURL *url = [NSURL URLWithString:mainimg];
NSData *imge = [[NSData alloc] initWithContentsOfURL:url];
cell.img.image=[UIImage imageWithData:imge];
于 2014-05-21T13:02:51.643 回答