adnan
adnan

Reputation: 21

cell images changing on scrolling UITableView

hi my problem is when i scroll UITableView cell images changing actually these images are on webserver and i and downloading it using asyncdownloading . i had added a UIImageView on UITableViewCell. images display succesfully on UITableViewCell but when i scroll tableview images changes this is the code

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"DefaultCell"];
       searchobjectval =[self.arrSearchResult objectAtIndex:indexPath.row];
    if(cell == nil)
    {
        cell =[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"DefaultCell"];



    }

    UILabel *areaLbl = (UILabel *)[cell viewWithTag:1];
    UILabel *postTitle = (UILabel *)[cell viewWithTag:2];
    UILabel *roomCost = (UILabel *)[cell viewWithTag:3];
    UILabel *description = (UILabel *)[cell viewWithTag:4];
    areaLbl.text =searchobjectval.location;
    postTitle.text = searchobjectval.title;
    roomCost.text = searchobjectval.roomCost;
    description.text =searchobjectval.description;

    [tableView setSeparatorColor:[UIColor blueColor]];

    UIView *myView = [[UIView alloc] init];
    if (indexPath.row % 2)
    {
        UIColor* clr = [UIColor colorWithRed:0.4f green:0.6f blue:0.8f alpha:1];
        myView.backgroundColor = clr;
    }
    else
    {
        myView.backgroundColor = [UIColor whiteColor];
    }
    cell.backgroundView = myView;

    NSLog(@" search object image %@",searchobjectval.imgLink);


    // Pass along the URL to the image (or change it if you are loading there locally)
    [AsyncImagesDownloading processImageDataWithURLString:[NSString stringWithFormat: @"http://192.95.48.72/bedspace/new_arrivals_img/%@",searchobjectval.idVal ] andBlock:^(NSData *imageData)
     {
         if (self.view.window)
         {
             UIImage *image = [UIImage imageWithData:imageData];
             UIImageView *imgVw = (UIImageView *)[cell viewWithTag:10];
             imgVw.image = image;
         }
     }];




    return cell;
}

Upvotes: 2

Views: 2066

Answers (6)

Sumit
Sumit

Reputation: 176

This basically happens when a request hasn't completed but you have scrolled to a different cell. The UITableView, on account of reusing the cells would consider it the same cell and would render the image on the cell being shown.

Here's the article https://medium.com/@bipolarbear/uitableview-with-images-from-api-8902ba507bff

Disclaimer: I wrote this blog

Upvotes: 0

RTasche
RTasche

Reputation: 2644

dequeueReusableCellWithIdentifier takes a UITableViewCell object from the queue. the cell's content is not cleared when taken from the queue so this cell might display a "wrong" image until your download has finished and your UIImageView's image is overwritten. try setting the image property to nil after dequeing the cell so that nothing's being displayed until new data has been loaded.

((UIImageView *)[cell viewWithTag:10]).image = nil;

Upvotes: 0

hellboy1738
hellboy1738

Reputation: 144

For memory management purposes UITableView reusing its cells UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"DefaultCell"]; and it load cell content when scrolling up or down. If you dont fetch data to an element of the cell then you will have the last value fetched in the last use of the cell when you scroll back to it.

In your case :

// Pass along the URL to the image (or change it if you are loading there locally)
    [AsyncImagesDownloading processImageDataWithURLString:[NSString stringWithFormat: @"http://192.95.48.72/bedspace/new_arrivals_img/%@",searchobjectval.idVal ] andBlock:^(NSData *imageData)
     {
         if (self.view.window)
         {
             UIImage *image = [UIImage imageWithData:imageData];
             UIImageView *imgVw = (UIImageView *)[cell viewWithTag:10];
             imgVw.image = image;
         }
     }];

So when !self.view.window you will have the image of th last use of the cell (if clause returns TRUE) and it will be changing while scrolling. What you need to do is :

// Pass along the URL to the image (or change it if you are loading there locally)
    [AsyncImagesDownloading processImageDataWithURLString:[NSString stringWithFormat: @"http://192.95.48.72/bedspace/new_arrivals_img/%@",searchobjectval.idVal ] andBlock:^(NSData *imageData)
     {
         if (self.view.window)
         {
             UIImage *image = [UIImage imageWithData:imageData];
             UIImageView *imgVw = (UIImageView *)[cell viewWithTag:10];
             imgVw.image = image;

         } else {

             UIImage *image = [UIImage imageNamed:@"placeHolder.png"];
             UIImageView *imgVw = (UIImageView *)[cell viewWithTag:10];
             imgVw.image = image;

        }

     }];

Hope this was clear an useful :)

Upvotes: 2

Pavan
Pavan

Reputation: 443

You can try one better approach given by apple for image loader and text loader which will make tableview scrolling faster link is below

http://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html

Upvotes: 0

TomCobo
TomCobo

Reputation: 2916

Why don't use the cell and the IB doing this cell.yourImageView=[UIImage imageWithData:imageData];? I think this answer is useful https://stackoverflow.com/a/3634414/2000162

Upvotes: 0

jszumski
jszumski

Reputation: 7416

You should store the image as a property on searchobjectval and set it on the image view in cellForRowAtIndexPath. When your async loading completes, check if the destination cell for the image is visible, if so reload it. If the cell isn't visible, you can simply wait for it to become visible again and then cellForRowAtIndexPath will take of setting it for you.

Remember, if these images are big and self.arrSearchResult exists for a long time, you should also put some logic in there to clear the images from memory if it begins to run low.

Upvotes: 0

Related Questions