Is the image added automatically to the UItableView Cell?

Helo all,

I have a very strange situation. I have a table view in which I have custom cells. Therefore, I developed my own custom cell. In a custom cell, I display an image as well as text. The table data comes from the server. If any image in json is then displayed differently, only text will be displayed. So the cell will be dynamic. I used the bezier path to wrap text around the image. Not if there is an image, so the text will be wrapped. When I add a new message from the server with the image and update the table, it will automatically display the image for another message. will display the same image, which is the same image for last. I don’t know why the new cell adds an image to it, even the code works fine, I tricked it with breakpoints. Please tell us what could be the problem.

Here is the code for cellForRowAtIndexPath

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //define variables here static NSString *CellIdentifier = @"homeCell"; HomeCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; if([arr_post count]>0) { NSMutableAttributedString *mutableAttributeStr; NSAttributedString *attributeStr; [cell layoutIfNeeded]; //get the post data Post *user_post=[arr_post objectAtIndex:indexPath.row]; //set the button tags cell.btn_like.tag=indexPath.row; cell.btn_comment.tag=indexPath.row; cell.btn_fav.tag=indexPath.row; cell.btn_con.tag=indexPath.row; cell.btn_book.tag=indexPath.row; //add info to buttons cell.btn_like.selected=user_post.isPostLiked; cell.btn_comment.selected=user_post.isPostCommented; cell.btn_fav.selected=user_post.isPostFavourite; cell.btn_con.selected=user_post.isPostCondolence; cell.btn_book.selected=user_post.isPostBookmarked; //add user info cell.label_name.text=user_post.username; cell.img_profile.layer.cornerRadius = 25; cell.img_profile.clipsToBounds = YES; [cell.img_profile setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.user_profileImage]]placeholderImage:[UIImage imageNamed:@"post_placeholder.png"]]; //add location if([user_post.location isEqualToString:@"Not Available"]) { [cell.img_icon_location setHidden:true]; [cell.label_location setHidden:true]; } else { [cell.img_icon_location setHidden:false]; [cell.label_location setHidden:false]; cell.label_location.text=user_post.location; } //ad post info cell.tv_post.text=user_post.post_description; cell.tv_post.font = [UIFont fontWithName:user_post.font_family size:[user_post.font_size floatValue]]; [cell.tv_post setTextColor:[self colorFromHexString:user_post.font_color]]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; NSDate *date = [formatter dateFromString:user_post.modification_date]; NSLog(@"user post image is %@",user_post.post_image); if([user_post.post_image isEqualToString:@"none"] && [user_post.post_video isEqualToString:@"none"]) { NSLog(@"NOT INSIDE THE CONDITION"); } else { NSLog(@"INSIDE BEIZER PATH CONDITION"); UIBezierPath * imgRect = [UIBezierPath bezierPathWithRect:CGRectMake(0, 10, 100, 100)]; cell.tv_post.textContainer.exclusionPaths = @[imgRect]; UIImageView *tv_image =[[UIImageView alloc]initWithFrame:CGRectMake(0, 10, 100, 100)]; if(![user_post.post_image isEqualToString:@"none"]) { [tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_image]]placeholderImage:[UIImage imageNamed:@"post_placeholder.png"]]; } if(![user_post.post_video isEqualToString:@"none"]) { [tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_video_thumbnail]]placeholderImage:[UIImage imageNamed:@"post_placeholder.png"]]; } [cell.tv_post addSubview:tv_image]; } //make textview height dynamic cell.tv_post.scrollEnabled=NO; if([user_post.post_image isEqualToString:@"none"] && [user_post.post_video isEqualToString:@"none"]) { CGFloat fixedWidth = cell.tv_post.frame.size.width; CGSize newSize = [cell.tv_post sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)]; CGRect newFrame = cell.tv_post.frame; newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height); cell.tv_post.frame = newFrame; cell.tv_height.constant=cell.tv_post.frame.size.height; [cell.view_tvContainer layoutIfNeeded]; } //set the border of uiview cell.view_tvContainer.layer.borderColor = [UIColor blackColor].CGColor; cell.view_tvContainer.layer.borderWidth = 2.0f; //set the like count NSString *first_like_user=recent_like_name=user_post.recent_like_name; NSLog(@"FIRST LIEK USER IS %@",first_like_user); NSString *str_recent_like_name; int count=(int)[first_like_user length]; int like_count=[user_post.like_count intValue]; if(like_count>0) { cell.label_like_count.lineBreakMode=NSLineBreakByWordWrapping; [cell.label_like_count sizeToFit]; [cell.label_like_count setHidden:false]; NSString *str_like_count=[NSString stringWithFormat:@"%lu",(unsigned long)like_count-1]; if(like_count==1) { if([myUsername isEqualToString:first_like_user]) { first_like_user=@ "You like this post "; count=3; } else { first_like_user=[first_like_user stringByAppendingString:@" like this post"]; } } else if(like_count==2) { if([first_like_user isEqualToString:myUsername]) { first_like_user=@ "You"; } Post *temp_user_post=[copy_arr_user_post objectAtIndex:indexPath.row]; first_like_user=[first_like_user stringByAppendingString:@" and "]; if(temp_user_post.recent_like_name==nil) { temp_user_post.recent_like_name=@ ""; } str_recent_like_name=[temp_user_post.recent_like_name_two stringByAppendingString:@" like this post"]; first_like_user=[first_like_user stringByAppendingString:str_recent_like_name]; } else { if(like_count>1000) { like_count=like_count/1000; str_like_count=[NSString stringWithFormat:@"%lu",(unsigned long)like_count]; str_like_count=[str_like_count stringByAppendingString:@"k"]; first_like_user=[first_like_user stringByAppendingString:@" and "]; str_like_count=[str_like_count stringByAppendingString:@" others like this post"]; first_like_user=[first_like_user stringByAppendingString:str_like_count]; } else { if([first_like_user isEqualToString:myUsername]) { first_like_user=@ "You"; } first_like_user=[first_like_user stringByAppendingString:@" and "]; str_like_count=[str_like_count stringByAppendingString:@" others like this post"]; first_like_user=[first_like_user stringByAppendingString:str_like_count]; } } mutableAttributeStr = [[NSMutableAttributedString alloc]initWithString:first_like_user]; attributeStr = [[NSAttributedString alloc]initWithString:@"\n" attributes:@{NSFontAttributeName : [UIFont fontWithName:@"HelveticaNeue-Bold" size:8]}]; [mutableAttributeStr addAttribute:NSFontAttributeName value: [UIFont fontWithName:@"Helvetica-Bold" size:14.0] range:NSMakeRange(0, count)]; [mutableAttributeStr addAttribute:NSForegroundColorAttributeName value:[self colorFromHexString:@"#48a0dd"] range:NSMakeRange(0, count)]; [mutableAttributeStr appendAttributedString:attributeStr]; [cell.label_like_count setAttributedText:mutableAttributeStr]; } else { [cell.label_like_count setHidden:true]; } // show dynamic comment NSMutableArray *user_comments=user_post.comments; float comment_count=[user_post.comment_count intValue]; NSLog(@"ID IS %@",user_post.id); if(comment_count>0) { //make label multiline cell.first_comment.lineBreakMode=NSLineBreakByWordWrapping; [cell.first_comment sizeToFit]; cell.second_cmment.lineBreakMode=NSLineBreakByWordWrapping; [cell.second_cmment sizeToFit]; cell.third_comment.lineBreakMode=NSLineBreakByWordWrapping; [cell.third_comment sizeToFit]; if(comment_count==1) { [cell.first_comment setHidden:false]; [cell.second_cmment setHidden:true]; [cell.third_comment setHidden:true]; } else if(comment_count==2) { [cell.first_comment setHidden:false]; [cell.second_cmment setHidden:false]; [cell.third_comment setHidden:true]; } else { [cell.first_comment setHidden:false]; [cell.second_cmment setHidden:false]; [cell.third_comment setHidden:false]; [cell.btn_more_comments setHidden:false]; } for(l=0;l<[user_comments count];l++) { Comment *comment=[user_comments objectAtIndex:l]; NSString *comment_string=[comment.user_name stringByAppendingString:@" "]; comment_string=[comment_string stringByAppendingString:comment.comment]; int count=(int)[comment.user_name length]; NSMutableAttributedString* mutableAttributeStr = [[NSMutableAttributedString alloc]initWithString:comment_string]; NSAttributedString *attributeStr = [[NSAttributedString alloc]initWithString:@"\n" attributes:@{NSFontAttributeName : [UIFont fontWithName:@"HelveticaNeue-Bold" size:8]}]; [mutableAttributeStr addAttribute:NSFontAttributeName value: [UIFont fontWithName:@"Helvetica-Bold" size:14.0] range:NSMakeRange(0, count)]; [mutableAttributeStr addAttribute:NSForegroundColorAttributeName value:[self colorFromHexString:@"#48a0dd"] range:NSMakeRange(0, count)]; [mutableAttributeStr appendAttributedString:attributeStr]; // end of the repetitive pattern if (l == 0) { [cell.first_comment setAttributedText:mutableAttributeStr]; } else if (l == 1) { [cell.second_cmment setAttributedText:mutableAttributeStr]; } else if (l == 2) { [cell.third_comment setAttributedText:mutableAttributeStr]; } } } else { [cell.first_comment setHidden:true]; [cell.second_cmment setHidden:true]; [cell.third_comment setHidden:true]; [cell.btn_more_comments removeFromSuperview]; } cell.label_time.text=[BaseController timeAgoStringFromDate:date]; [arr_indexpath addObject:indexPath]; } return cell; } 
+7
ios objective-c iphone uitableview ipad
source share
8 answers

Keep in mind that cells are reused. If you have, say, 10,000 rows in your table data source, the table view will not create as many rows. It will only create a few lines that will be displayed on the screen, and several others that will be preloaded.
Each time you scroll through the table, the tableview will use those cells that become invisible to load new cells that only become visible to create the illusion of an infinite number of rows. This is why these new cells have old data. So basically you will need to set the UIImageView nil image to cellForRowAtIndexpath: if the image is not available.

 if([user_post.post_image isEqualToString:@"none"] && [user_post.post_video isEqualToString:@"none"]) { NSLog(@"NOT INSIDE THE CONDITION"); } 

In the above code, you just print the log, and what you also need to do is set UIImageView's image to nil .

So this is my suggestion:

 //if([user_post.post_image isEqualToString:@"none"] && [user_post.post_video isEqualToString:@"none"]) //{ // NSLog(@"NOT INSIDE THE CONDITION"); //} //else { NSLog(@"INSIDE BEIZER PATH CONDITION"); UIBezierPath * imgRect = [UIBezierPath bezierPathWithRect:CGRectMake(0, 10, 100, 100)]; cell.tv_post.textContainer.exclusionPaths = @[imgRect]; UIImageView *tv_image =[[UIImageView alloc]initWithFrame:CGRectMake(0, 10, 100, 100)]; if(![user_post.post_image isEqualToString:@"none"]) { [tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_image]]placeholderImage:[UIImage imageNamed:@"post_placeholder.png"]]; } else{ [tv_image setImage:nil]; //Prevent the old data to be shown } if(![user_post.post_video isEqualToString:@"none"]) { [tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_video_thumbnail]]placeholderImage:[UIImage imageNamed:@"post_placeholder.png"]]; } else{ [tv_image setImage:nil];//Prevent the old data to be shown } [cell.tv_post addSubview:tv_image]; } 

This code may not meet your requirements for how the data will be displayed, but I hope this helps you get the idea!

+1
source share

When you need to display a tableview cell, you either create a new one or reuse the one that was created earlier but is no longer visible on the screen. Since you created the UIImageView and added it to the cell, there is still an image when reusing it.

To stop this, you need to save the link to the image, so the next time you can delete it. Since you add them dynamically and don't have an IBOutlet , your fastest option is to assign an image a tag

 UIImageView *tv_image =[[UIImageView alloc]initWithFrame:CGRectMake(0, 10, 100, 100)]; tv_image.tag = 21; // arbitrary number but must be unique to the image 

By tagging the image, next time you can access it:

 UIImageView *tv_image = (UIImageView*)[cell viewWithTag:21]; if (tv_image != nil) { tv_image.image = nil; // remove the image (or remove the image view from the cell etc) } 

Just remember to edit the code accordingly so that if you find an image from a tag, you don’t need to recreate it, etc.

0
source share

Your img_profile is img_profile repeated because you are reusing a cell.

Replace bottom line of code

 [cell.img_profile setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.user_profileImage]]placeholderImage:[UIImage imageNamed:@"post_placeholder.png"]]; 

with code below: -

  if (user_post.user_profileImage.length == 0) { cell.img_profile.hidden = true; }else{ [cell.img_profile setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.user_profileImage]]placeholderImage:[UIImage imageNamed:@"post_placeholder.png"]]; } 

Explanation: - Make sure your json contains a user profile image, then set the image, otherwise hide the profile image view.

0
source share

The table reuses cells . This means that if you add a subview to the cell, as in the line [cell.tv_post addSubview:tv_image] , then this subview will still be in the cell when reused .

Basically, if you add subviews to a custom cell in tableView:cellForRowAtIndexPath: you are probably wrong.

Just create a tv_image in HomeCell first. HomeView should have an output named tv_image connected to the image view in your storyboard or XIB. When you need tv_image , show it. Otherwise, hide it.

  if([user_post.post_image isEqualToString:@"none"] && [user_post.post_video isEqualToString:@"none"]) { NSLog(@"NOT INSIDE THE CONDITION"); cell.tv_image.image = nil; cell.tv_image.hidden = YES; cell.tv_post.textContainer.exclusionPaths = @[]; } else { NSLog(@"INSIDE BEIZER PATH CONDITION"); UIBezierPath * imgRect = [UIBezierPath bezierPathWithRect:CGRectMake(0, 10, 100, 100)]; cell.tv_post.textContainer.exclusionPaths = @[imgRect]; if(![user_post.post_image isEqualToString:@"none"]) { [cell.tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_image]]placeholderImage:[UIImage imageNamed:@"post_placeholder.png"]]; } if(![user_post.post_video isEqualToString:@"none"]) { [cell.tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_video_thumbnail]]placeholderImage:[UIImage imageNamed:@"post_placeholder.png"]]; } cell.tv_image.hidden = NO; } 

Also, make sure that setImageWithURL:placeholderImage: does not set the hidden = NO image when loading the image.

0
source share

I wonder where you select the custom cell. You should not create a cell only if it is not created. Something like that:

 static NSString *CellIdentifier = @"homeCell"; HomeCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; if(!cell) { cell = [[[HomeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]]; } 

And then upgrade the user interface components.

  if([user_post.post_image isEqualToString:@"none"] && [user_post.post_video isEqualToString:@"none"]) { NSLog(@"NOT INSIDE THE CONDITION"); } else { NSLog(@"INSIDE BEIZER PATH CONDITION"); UIBezierPath * imgRect = [UIBezierPath bezierPathWithRect:CGRectMake(0, 10, 100, 100)]; cell.tv_post.textContainer.exclusionPaths = @[imgRect]; UIImageView *tv_image =[[UIImageView alloc]initWithFrame:CGRectMake(0, 10, 100, 100)]; if(![user_post.post_image isEqualToString:@"none"]) { [tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_image]]placeholderImage:[UIImage imageNamed:@"post_placeholder.png"]]; } if(![user_post.post_video isEqualToString:@"none"]) { [tv_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_video_thumbnail]]placeholderImage:[UIImage imageNamed:@"post_placeholder.png"]]; } [cell.tv_post addSubview:tv_image]; } 

perhaps you should write an "update method" inside your "HomeCell" class. Updating user interface components.

0
source share

I recommend using [SDWebImage] [1] https://github.com/rs/SDWebImage , where you can update your cell in the completion block or cache, if necessary

0
source share

The problem consists of two layers:

  • cells are reused, this is the usual place to miss, but not in your case.
  • Your string [cell.img_profile setImageWithURL:...]; asynchronous , which means that by the time the image is loaded, your cell can be reused, so clearing the View image during reuse will not help.

To properly use asynchronous image loading in a reusable cell, you need to double-check the image is correct on successful upload.

add property to cell class:

 @property (weak) NSURL *targetImageUrl; 

then change the download to add validation:

 NSURL *targetImageUrl = [NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.user_profileImage]]; cell.targetImageUrl = targetImageUrl; // <!> replace latest target [cell.img_profile setImageWithURLRequest: [NSMutableURLRequest requestWithURL:targetImageUrl] placeholderImage: [UIImage imageNamed:@"post_placeholder.png"] success: ^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) { if (cell.targetImageUrl != targetImageUrl) return; // <!> this is the trick cell.img_profile.image = image; } failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) { }]; 
0
source share

Since cellForRowAtIndexPath is called whenever a cell becomes visible, I always use the following strategy to display images that need to be downloaded from the Internet: I either connect the image (when loading) with the objc_setAssociatedObject object with an object that contains data for the table row or create some hashMap, where I put images with some identifier for the key. Then in cellForRowAtIndexPath I check if the associated object is nil (or if the image for the key exists in hashmap). If it is zero or does not exist (which means that it is still loading), I set the placeholder image for the imageView image, otherwise I set the loaded image. And after loading you reload the table (or just the necessary cell)

0
source share

All Articles