在iOS中创建了重复的单元格?

时间:2015-10-13 10:17:34

标签: ios objective-c uitableview

我在iOS中创建了一个自定义单元格。在自定义单元格中有许多标签。对于少数标签,第一个和第一个数据的数据。第四个自定义单元格总是一样的。我的数据源数组总共有5条记录。现在我遇到这些问题。

  1. 当数组中有4条记录时,为什么索引行的单元格只被调用两次。
  2. 第一个和第一个数据第四行总是一样的。
  3. 请告诉我如何解决此问题。

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

    修改 我已经阅读了某些地方,出于性能原因,UITable恢复了单元格。因为我觉得当有超过3行时我会遇到这个问题。

    修改 如果我尝试不使用if(like_count>0)&amp;条件,我在这里发现了一个奇怪的情况。只需在不符合条件的情况下设置文本标签,然后它就可以正常使用。

    提前致谢。

7 个答案:

答案 0 :(得分:5)

单元格被重用,因此您必须覆盖执行路径中的所有情况。

正如您已经发现的那样,if(like_count>0)if(comment_count>0)意味着如果没有计数,则文本标签不会更改,旧值将保留在那里。

您必须添加} else { cell.label_like_count.attributedText = nil }种代码才能涵盖所有情况。或者,您可以在单元类中的- (void)prepareForReuse中添加一些清理代码(不要忘记[super prepareForReuse])。

答案 1 :(得分:1)

HomeCell覆盖prepareForReuse:。在该方法中,在所有标签上将.text(或.attributedText)属性设置为nil。然后看看会发生什么。

答案 2 :(得分:1)

重复使用单元格,表格始终只创建当前可见的单元格。显示屏幕时,将显示三个单元格。当您滚动并且一个单元格被隐藏而另一个单元格出现时,它实际上是相同的单元格实例。

处理此行为的常用方法是子类UITableViewCell并在那里进行所有设置。可以将重置为默认状态添加到-prepareForReuse方法,例如

- (void)prepareForReuse {
   [super prepareForReuse];

   self.first_comment.text = nil;
   self.second_comment.text = nil;
   self.third_comment.text = nil;
}

要修复代码而不使用特定的单元子类,让我们首先通过从代码中删除重复模式来简化:

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

现在您可以将其与重置值结合使用:

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

答案 3 :(得分:0)

检查表格中的元素数量,并确保代理 numberOfRowsInSection 中的数字正确无误:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return the_correct_items_number;
}

如果计数正确,请尝试使用本地数组(仅用于测试)。注意:如果使用网络请求更新源阵列,请考虑使用dispatch_async调用来更新内容。

答案 4 :(得分:0)

在自定义单元格中使用方法prepareForReuse

//如果单元格是可重用的(具有重用标识符),则在从表视图方法dequeueReusableCellWithIdentifier:返回单元格之前调用它。如果你覆盖,你必须调用super。

- (void) prepareForReuse {

 // set empty or nil of your repeated element .

 [super prepareForReuse];
}

希望对你有所帮助。

答案 5 :(得分:-1)

尝试替换

if (cell==nil)
{
    cell = [[HomeCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

//if (cell==nil)
//{
    cell = [[HomeCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// }

答案 6 :(得分:-1)

将单元格出列后,请写下以下行: -

[cell.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];