简体   繁体   中英

UITableViewCell image load

I have the following code that loads an image from a web service, I want to check if the image is loaded and then populate a button with an image (button is already in place)

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    FeedTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kTableViewCellIdentifier forIndexPath:indexPath];

    if (!cell) {
        cell = [[FeedTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kTableViewCellIdentifier];
    }

    // Configure the cell...
    cell.post_time.font = [UIFont fontWithName:@"ProximaNova-Bold" size:12];
    cell.post_price.font = [UIFont fontWithName:@"ProximaNova-Semibold" size:13];
    cell.post_address.font = [UIFont fontWithName:@"ProximaNova-Regular" size:13];
    cell.post_attributes.font = [UIFont fontWithName:@"ProximaNova-Regular" size:11];
    House * house = [Posts objectAtIndex:indexPath.row];

    //cell.post_image.clipsToBounds = YES;
    //cell.post_image.contentMode = UIViewContentModeScaleAspectFill;
    //cell.post_image.contentMode = UIViewContentModeScaleAspectFit;
    cell.post_time.text = house.house_ts;
//  [cell.post_image setImageWithURL:[NSURL URLWithString:house.house_aws_image_id]];
    [cell.post_image setImageWithURL:[NSURL URLWithString:house.house_aws_image_id] placeholderImage:[UIImage imageNamed:@"splash_image_gray"]];


   cell.post_attributes.text = [self decodeAttributes:house.house_bed_rms :house.house_bath_rms :house.house_house_siz];


    [cell.post_playButton addTarget:self action:@selector(showVideo:) forControlEvents:UIControlEventTouchUpInside];
    cell.post_share.tag = indexPath.row;
    [cell.post_share addTarget:self action:@selector(shareoptions:) forControlEvents:UIControlEventTouchUpInside];

    //[cell.post_playButton setImage:[UIImage imageNamed:@"feed_play_but_pink.png"] forState:UIControlStateHighlighted];
    //[cell.post_playButton setBackgroundImage:[UIImage imageNamed:@"heart_btn"] forState:UIControlStateNormal];

    [cell.post_playButton setTag:indexPath.row];
    [cell.post_playButton setBackgroundImage:[UIImage imageNamed:@"feed_play_but"] forState:UIControlStateNormal];

    return cell;
}

Any ideas how to achieve this? Thanks in advance.

Assuming your getting your data form the web service as array, you should parse the array and copy it mutable (or parse it as mutable array directly).

Then you can do this:

id imageObject = [[[self dataArray] objectAtIndex:[indexPath row]] objectForKey:@"imageURL"];

if ([imageObject isKindOfClass:[NSString class]]) {
    NSURLConnection *connection = [NSURLConnection ...];

    // replace image url in array so that you don't start connections too often.
    [[[self dataArray] objectAtIndex:[indexPath class]] setObject:connection forKey:@"imageURL"];

    // when connection finishes, replace the connection by the instance of UIImage and reload the corresponding cell
}
else if ([imageObject isKindOfClass:[UIImage class]]) {
    [[cell imageView] setImage:imageObject];
}

You can use the JWURLConnection class for easy block programming. If you do so, you can easily use this code (which is from one of my apps and works just fine):

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier forIndexPath:indexPath];
    NSMutableDictionary *post = [[self dataSource] objectAtIndex:[indexPath row]];

    id memberCloseup = [post objectForKey:@"image"];

    if ([memberCloseup isKindOfClass:[NSString class]]) {
        JWURLConnection *connection = [JWURLConnection connectionWithGETRequestToURL:[NSURL URLWithString:memberCloseup] delegate:nil startImmediately:NO];
        [connection setFinished:^(NSData *data, NSStringEncoding encoding) {
            [post setObject:[UIImage imageWithData:data] forKey:@"image"];
            [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        }];

        [teamMemberMeta setObject:connection forKey:@"so_team_member-image_close"];
        [post setObject:connection forKey:@"image"];

        [connection start];
    }
    else if ([memberCloseup isKindOfClass:[UIImage class]]) {
        [[cell imageView] setImage:memberCloseup];
    }

    return cell;
}

EDIT

You would have to move your loading logic to the view controller. Letting the cell loading itself is wrong, because your cells are getting reused, so one cell represents various data objects and / or images. My solution saves a lot of memory and data usage.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM