Reputation: 8944
I have a created a custom cell in iOS.In custom cell there are many labels.For few labels the data of first & fourth custom cell is always same.There are total 5 records in my data source array.Now there are these issues i face.
Please tell me how can i resolve this issue.
CODE:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"cell for row called %d",(int)[arr_post count]);
//define variables here
NSMutableAttributedString *mutableAttributeStr;
NSAttributedString *attributeStr;
static NSString *CellIdentifier = @"homeCell";
float x_pos;
HomeCell *cell = [self.table_view
dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
//get the post data
Post *user_post=[arr_post objectAtIndex:indexPath.row];
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.label_name.text=user_post.post_title;
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [formatter dateFromString:user_post.modification_date];
if([user_post.post_image isEqualToString:@"none"] && [user_post.post_video isEqualToString:@"none"])
{
x_pos=cell.tv_post.frame.origin.x;
cell.tv_post_leading_space.constant=-(x_pos);
[cell.img_post setHidden:true];
}
//set the like count
NSString *first_like_user=user_post.recent_like_name;
int count=(int)[first_like_user length];
float like_count=[user_post.like_count intValue];
//chek if tehre are any likes on the post
NSLog(@"recent like name is %@",user_post.recent_like_name);
NSLog(@"like count is %f",like_count);
if(like_count>0)
{
NSLog(@"inside like count block");
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)
{
first_like_user=[first_like_user stringByAppendingString:@" and "];
str_like_count=[str_like_count stringByAppendingString:@" other like this post"];
first_like_user=[first_like_user stringByAppendingString:str_like_count];
}
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
{
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];
//set the like label dynamic height & width
cell.label_like_count.attributedText = mutableAttributeStr;
CGSize maximumLabelSize = CGSizeMake(187,9999);
CGSize requiredSize = [cell.label_like_count sizeThatFits:maximumLabelSize];
CGRect labelFrame = cell.label_like_count.frame;
labelFrame.size.height = requiredSize.height;
cell.label_like_count.frame = labelFrame;
// cell.label_like_count.lineBreakMode = NSLineBreakByWordWrapping;
cell.label_like_count.numberOfLines = 0;
[cell.label_like_count sizeToFit];
[cell.label_like_count setAttributedText:mutableAttributeStr];
}
//show dynamic comment
NSMutableArray *user_comments=user_post.comments;
float comment_count=[user_post.comment_count intValue];
NSLog(@"arr comments count is %lu",(unsigned long)comment_count);
if(comment_count>0)
{
NSLog(@"post id is %@",user_post.id);
NSMutableAttributedString *mutableAttributeStr;
NSAttributedString *attributeStr;
for(l=0;l<[user_comments count];l++)
{
NSLog(@"inside loop %d",l);
Comment *comment=[user_comments objectAtIndex:l];
if(l==0)
{
NSLog(@"l is zero");
NSString *comment_string=[comment.user_name stringByAppendingString:@" "];
comment_string=[comment_string stringByAppendingString:comment.comment];
int count=(int)[comment.user_name length];
mutableAttributeStr = [[NSMutableAttributedString alloc]initWithString:comment_string];
NSLog(@"comment string is %@",comment_string);
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.first_comment setAttributedText:mutableAttributeStr];
}
else if(l==1)
{
NSLog(@"l is 1");
NSString *comment_string=[comment.user_name stringByAppendingString:@" "];
comment_string=[comment_string stringByAppendingString:comment.comment];
int count=(int)[comment.user_name length];
mutableAttributeStr = [[NSMutableAttributedString alloc]initWithString:comment_string];
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)];
NSLog(@"comment string is %@",comment_string);
[mutableAttributeStr appendAttributedString:attributeStr];
[cell.second_cmment setAttributedText:mutableAttributeStr];
}
else if(l==2)
{
NSLog(@"l is 2");
NSString *comment_string=[comment.user_name stringByAppendingString:@" "];
comment_string=[comment_string stringByAppendingString:comment.comment];
int count=(int)[comment.user_name length];
mutableAttributeStr = [[NSMutableAttributedString alloc]initWithString:comment_string];
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.third_comment setAttributedText:mutableAttributeStr];
}
}
}
else
{
NSLog(@"not inside loop");
}
cell.label_time.text=[BaseController getTimestampForDate:date];
return cell;
}
EDIT: I have read somewhere that for performance reasons UITable resume the cell.Because i feel i get this issue when there are more than 3 rows.
EDIT:
I have found a strange situation here if i try don't use the condition if(like_count>0)
& simply set the text fo label with out this condition then it works fine for me.
Thanks in advance.
Upvotes: 2
Views: 284
Reputation: 407
Use methods prepareForReuse
in your custom cell .
// if the cell is reusable (has a reuse identifier), this is called just before the cell is returned from the table view method dequeueReusableCellWithIdentifier:. If you override, you MUST call super.
- (void) prepareForReuse {
// set empty or nil of your repeated element .
[super prepareForReuse];
}
hope it help you .
Upvotes: 0
Reputation: 130102
Cells are reused and the table always creates only the cells that are currently visible. When you show the screen, three cells will be visible. When you scroll and one cell becomes hidden and another one appears, it's actually the same cell instance.
The usual way to handle this behavior is to subclass UITableViewCell
and do all that setup there. The reset to a default state can be added to -prepareForReuse
method, e.g.
- (void)prepareForReuse {
[super prepareForReuse];
self.first_comment.text = nil;
self.second_comment.text = nil;
self.third_comment.text = nil;
}
To fix your code without having a specific cell subclass, let's first simplify by removing the repetitive patterns from your code:
for (NSUInteger i = 0; i < [user_comments count]; i++) { //i is the traditional variable name for iterating
Comment *comment = user_comments[i]; //updating to newer syntax
// start of the repetitive pattern
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 (i == 0) {
[cell.first_comment setAttributedText:mutableAttributeStr];
}
else if (i == 1) {
[cell.second_comment setAttributedText:mutableAttributeStr];
}
else if (i == 2) {
[cell.third_comment setAttributedText:mutableAttributeStr];
}
}
Now you can combine it with resetting the value:
NSArray *commentLabels = @[cell.first_comment, cell.second_comment, cell.third_comment];
for (NSUInteger i = 0; i < 3; i++) {
UILabel *label = commentLabels[i];
// reset if there is no comment
if (i >= [user_comments count]) {
label.text = nil;
continue;
}
Comment *comment = user_comments[i];
NSString *comment_string = [NSString stringWithFormat:@"%@ %@", comment.user_name, 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];
label.attributedText = mutableAttributeStr;
}
Upvotes: 1
Reputation: 2369
in HomeCell
override prepareForReuse:
. In that method, set the .text
(or .attributedText
) property to nil
on all of your labels. Then see what happens.
Upvotes: 1
Reputation: 1030
Cell are reused, so you have to cover all case in your execution path.
As you already found, if(like_count>0)
and if(comment_count>0)
imply that if there is no count, the text label is not changed and the old value will stay there.
You have to add } else { cell.label_like_count.attributedText = nil }
kind of code to cover all cases. Alternatively, you can add some cleanup code in - (void)prepareForReuse
in the cell class (don't forget [super prepareForReuse]
).
Upvotes: 5
Reputation: 8504
After you dequeue cell, write the below line:-
[cell.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
Upvotes: -1
Reputation: 3387
Check the number of elements in the table and be sure the number is correct in the delegate numberOfRowsInSection:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return the_correct_items_number;
}
If the count is correct, try with a local array (just for test). Note: if you update the source array using network requests, consider to use the dispatch_async calling to update you content.
Upvotes: 0
Reputation: 22
try replacing
if (cell==nil)
{
cell = [[HomeCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
with
//if (cell==nil)
//{
cell = [[HomeCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// }
Upvotes: -1