Image does not load right away in table format

I use SDWebImage and grab images related to a news article from the news API.

The problem is that the images for the cells on the screen do not load until I start scrolling to the UITableView . As soon as I scroll through the cell and it turns off, as soon as I get back to it, the image will finally be loaded.

Here is my code (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"]]; //]; } } ]; } 

Any idea why this will happen? It looks like when a UITableView loads, the images don't load the images or something else before scrolling starts?

Any suggestion is much appreciated, thanks!

+6
source share
5 answers

Earlier, I encountered a similar problem, and it turned out that the images in the table view were loaded correctly. The real problem you are facing is the update problem. When each image is loaded, it must be updated to be displayed in the table view. In my case, the download part was done in a separate file, so I used NSNotificationCenter to tell the Tableview controller class to update it. Here is what you can do with the code:

 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]; //]; } } ]; } 

and then you can call the reboot data using this as shown below:

 - (void) imageDownloaded:(NSNotification *)notification{ [self.tableView reloadData]; } 

This way, you don’t have to scroll to see the image, instead they will be shown right after they are downloaded.

Hope this helps!

+1
source

There is little chance that this will solve your problem, but it is too long to fit into the comment:

Tip 1:

If you reuse cells, you should not do [wcell.imageView setImage:] in the callback. During the execution of the callback code, there is a non-zero probability that wcell will point to a different cell in the table view than the one you would like to change.

Instead, use indexPath to refer to the cell you want to change:

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

Note that if the cell you want to change the image is no longer displayed, cellForRowAtIndexPath: will return nil , which is absolutely normal:

Return value

An object representing a table cell, or nil if the cell is not visible, or indexPath is out of range.

Tip 2:

No need to re-create the string when you already have;)

 [NSURL URLWithString:[NSString stringWithFormat:@"%@", imageURL]] [NSURL URLWithString:imageURL] // imageURL is already a string 

Your problem :

I am a little puzzled, the code you showed is actually a simple SDWebImage "how-to" example application, and I just tested it with v3.3. So try reducing your code to a minimum to determine the real problem.

I would say get rid of all your application logic (e.g. feedLocal.images ) and just find out if the problem really arises from SDWebImage or not.

+4
source

Note:

 [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]; }); } }]; 
+1
source

Not sure if you solved your problem, but I solve my problem with the following code.

The main idea is to establish a link to the cell used inside the block and manually set the cell image in the completed method. Hope this helps.

 __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]; } }]; } 

To check if this is a right cell, I think it is something like this (I don't have time to check this)

 __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]; } } }]; } 
+1
source
 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
source

Source: https://habr.com/ru/post/948737/


All Articles