2013-07-04 72 views
6

我正在使用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加載時,圖像沒有被告知加載或直到滾動開始?

任何建議非常感謝,謝謝!

+0

其清新的問題。您必須進行NSNotification調用,並且每個圖像加載後,您必須調用tableview重新加載數據以便立即顯示圖像 – AJ112

+0

欣賞評論@ AJ112 ...您是否有代碼段,以便我可以看到什麼會看起來像我的代碼?這是有道理的,但我從來沒有做過,所以我想確保我跟着你。 – Realinstomp

+0

在我的情況下,下載過程發生在不同的文件這就是爲什麼我使用NSNotificationCenter,但我有完全相同的問題,即圖像開始出現時滾動下來。你可以先調用[self.tableView reloadData];在您下載圖像並將其設置到imageview的位置之後。 – AJ112

回答

1

我以前遇到過類似的問題,結果證明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]; 
} 

這樣,你不需要爲了看到滾動圖像,而不是它們在下載後立即顯示。

希望這會有所幫助!

+0

甜,今晚我會嘗試一下,看看! – Realinstomp

+0

如何在Swift中使用已完成的參數? – JCarlos

1

請與:

[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"]]; 
           } 
           else 
           { 
            dispatch_sync(dispatch_get_main_queue(), ^{ 
            [cell.imageView setImage:image]; 
            }); 
           } 
          }]; 
+0

感謝您的迴應!我只是將我的代碼更改爲您的建議,但在運行時不會改變任何內容。我應該檢查什麼?爲了確保我沒有錯過任何東西,它看起來像添加了一個我以前沒有的權利的「else」聲明? – Realinstomp

+0

只是在輸出日誌? – Realinstomp

+0

@Reez:檢查我編輯的答案 –

4

可能性很小,這將解決您的問題,但這是太長,無法在註釋:

提示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「怎麼樣」的例子,我只是用v 3.3的框架,我的細胞更新得很好。所以儘量減少你的代碼到最低限度,以確定真正的問題。

我會說擺脫所有的應用程序邏輯(例如feedLocal.images),並找出問題是否實際上來自SDWebImage或不。

+0

感謝您花時間給出答案,真的很感激!我已經在我的項目中更改了提示#2。部分問題是圖像在模擬器中完美顯示,但在我的設備上嘗試時沒有。所以我發佈的原始代碼在模擬器中工作,但不適用於我測試的實際iPhone。有關於此的任何想法? – Realinstomp

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]; 
            } 
           } 
    }]; 
} 
+0

非常好,這是爲SDWebImage專門或只是在一般情況下,這是你用它?再次感謝您的迴應! – Realinstomp

+0

我寫這個爲了使用SDWebImage。我絕對不會喜歡一般寫這個(如果你不從互聯網上下載圖片)。由於使用塊引用必須小心內存和泄漏,我寧願將圖像下載到模型(或某個文件系統),一旦完成,通知調用者(本例中爲UITableView),更新單元格圖像。當然,你必須使用協議和類似的東西,但是默認情況下使用ARC的機會較少。 – Ben

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]; 
+0

這個解決方案正在工作,但是當tableview被加載或滾動時,設備存在滯後 –

+0

我的表格單元格是動態的...如果您使用AFNetworking,NSData將消耗時間來加載通常會發生在後臺的圖像。所以延遲 –