cellForRowAtIndexPath:滚动后UILabel重叠

7

cellForRowAtIndexPath:

cell.textLabel.text正常工作。

滚动后UILabel会重叠。以下是代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    if (cell==nil)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

        // I have tried it by removing views and without.  No difference.   
        NSArray *viewsToRemove = [self.tableView subviews];
        for (UITableView *table in viewsToRemove)
        {
            [table removeFromSuperview];
        }
    }


    NSManagedObject *managedObject = [newClass objectAtIndex:indexPath.row];
    NSString  *entityName= [[managedObject entity]name];
    cell.textLabel.text = [NSString stringWithFormat:@"%@   %i", entityName, [indexPath row]];
    cell.textLabel.font=[UIFont systemFontOfSize:14.0];


    NSDate *date = [managedObject valueForKey:@"lastmoddate"];
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:@"EEE, MMM d, YYYY  h:mm a"];
    NSString *dateString = [formatter stringFromDate:date];

    UILabel *lblDate = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 215, 10)];
    lblDate.text = dateString;
    lblDate.textColor = [UIColor grayColor];
    lblDate.font = [UIFont systemFontOfSize:10.0];

    [lblDate setBackgroundColor:[UIColor clearColor]];
    [cell.contentView addSubview:lblDate];
    return cell;
}

这是图片: 在这里输入图片描述

每次都在单元格中添加新标签。尝试将文本设置为“ .detailLabel”属性。 - msgambel
我正在使用FPPopOver为iPhone,它不允许使用.detailLabel。我必须使用Label。 - user1107173
10个回答

6
这是我想到的一个方法,它可以很好地工作:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

    NSManagedObject *managedObject = [newClass objectAtIndex:indexPath.row];
    NSString  *entityName= [[managedObject entity]name];

    NSDate *date = [managedObject valueForKey:@"lastmoddate"];
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:@"EEE h:mm a MMM d, yy'''"];
    NSString *dateString = [formatter stringFromDate:date];

    UILabel *lblUser = [[UILabel alloc] initWithFrame:CGRectMake(30, 8, 215, 14)];
    lblUser.text = [NSString stringWithFormat:@"%@   %i", entityName, [indexPath row]];
    lblUser.textColor = [UIColor blackColor];
    lblUser.font = [UIFont systemFontOfSize:16.0];
    lblUser.tag = 1;
    [lblUser setBackgroundColor:[UIColor clearColor]];

    UILabel *lblDate = [[UILabel alloc] initWithFrame:CGRectMake(30, 21, 215, 20)];
    lblDate.text = dateString;
    lblDate.textColor = [UIColor grayColor];
    lblDate.font = [UIFont systemFontOfSize:12.0];
    lblDate.tag = 2;
    [lblDate setBackgroundColor:[UIColor clearColor]];

    if ((([cell.contentView viewWithTag:1]) && ([cell.contentView viewWithTag:2])))
    {
        [[cell.contentView viewWithTag:1]removeFromSuperview];
        [[cell.contentView viewWithTag:2]removeFromSuperview];
    }

    [cell.contentView addSubview:lblDate];
    [cell.contentView addSubview:lblUser];


    return cell;
}

1
我花了太多时间寻找类似于你的问题的解决方案。当初始化时,一切都很好,但是当开始滚动标签时,它们的位置混乱了。基本上,你的解决方案帮了我很大的忙。谢谢。 - iWizard

2

添加这行代码:

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

之前:

[cell.contentView addSubview:lblDate];

2

这是一个重新创建单元格内容的问题。请尝试以下代码片段。

for(UIView *view in cell.contentView.subviews){  
        if ([view isKindOfClass:[UIView class]]) {  
            [view removeFromSuperview];   
        }
    }

2

试试这个

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    if (cell==nil)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

    UILabel *lblDate = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 215, 10)];

    [cell.contentView addSubview:lblDate];
    }


    NSManagedObject *managedObject = [newClass objectAtIndex:indexPath.row];
    NSString  *entityName= [[managedObject entity]name];
    cell.textLabel.text = [NSString stringWithFormat:@"%@   %i", entityName, [indexPath row]];
    cell.textLabel.font=[UIFont systemFontOfSize:14.0];
lblDate.text = dateString;
    lblDate.textColor = [UIColor grayColor];
    lblDate.font = [UIFont systemFontOfSize:10.0];

    [lblDate setBackgroundColor:[UIColor clearColor]];

    NSDate *date = [managedObject valueForKey:@"lastmoddate"];
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:@"EEE, MMM d, YYYY  h:mm a"];
    NSString *dateString = [formatter stringFromDate:date];
    return cell;
}

@KumarKl,不会的。dequeueReusableCellWithIdentifier:forIndexPath:总是返回一个单元格,因此if(cell == nil)子句永远不会执行,lblDate也永远不会被添加。 - rdelmar
@KumarKl,不,它不应该。根据苹果的文档,dequeueReusableCellWithIdentifier:forIndexPath:始终返回一个有效的单元格 - 如果重用队列中没有,则从故事板、xib或注册的类中创建它。我不确定你或iAppDeveloper在说什么,当你说你通过编程方式创建单元格时。在iAppDevelopers代码中,他说他正在创建UITableViewCell,而不是某个自定义类。 - rdelmar
@rdelmar,那么为什么我们需要检查单元格是否为空,如果应该返回单元格的话。如果(cell == Nil)..这是个愚蠢的问题,请不要介意... - Kumar KL
你不需要这样做。这就是重点。但是iAppDeveloper说这段代码可以工作,我正在尝试弄清楚为什么。在使用dequeueReusableCellWithIdentifier:forIndexPath:时,我还没有看到过会执行那个子句的情况。 - rdelmar
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/36373/discussion-between-rdelmar-and-kumar-kl - rdelmar
显示剩余6条评论

2
dequeueReusableCellWithIdentifier:forIndexPath:保证返回一个单元格(可以是新的,也可以是从重用队列中获取的),所以你的if (cell == nil)语句永远不会被执行——这就是为什么删除视图或不删除视图没有区别的原因。标签重叠是因为你设置的方式如此。默认标签在单元格的左侧,而lblDate也在左侧(距离左侧10个点)。即使你将lblDate移到右侧,它可能也不会显示,因为我认为默认标签占据了整个单元格的宽度。最好制作一个自定义单元格,其中包含两个标签,您可以将它们放置在想要的位置。
在添加另一个标签之前,您还需要测试标签是否已经存在。您可以为标签分配一个唯一的标记,并检查是否存在具有该标记的视图,或者更简单的方法是,在Storyboard或XIB中制作自定义单元格,并在那里添加标签。然后,您只需要在代码中向它们添加内容。

0
if ([cell.contentView viewWithTag:tagnumber]
    {
        [[cell.contentView viewWithTag:tagnumber]removeFromSuperview];

    }
lblDate.tag = tagnumber;
    [cell.contentView addSubview:lblDate];

这一行就足够了,只需删除之前的子视图标签,并添加带有标签的新子视图。谢谢您的回答。


0

试一下

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{


static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];

NSManagedObject *managedObject = [newClass objectAtIndex:indexPath.row];
NSString  *entityName= [[managedObject entity]name];

NSDate *date = [managedObject valueForKey:@"lastmoddate"];
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"EEE h:mm a MMM d, yy'''"];
NSString *dateString = [formatter stringFromDate:date];

UILabel *lblUser = [[UILabel alloc] initWithFrame:CGRectMake(30, 8, 215, 14)];
lblUser.text = [NSString stringWithFormat:@"%@   %i", entityName, [indexPath row]];
lblUser.textColor = [UIColor blackColor];
lblUser.font = [UIFont systemFontOfSize:16.0];
lblUser.tag = 1;
[lblUser setBackgroundColor:[UIColor clearColor]];

UILabel *lblDate = [[UILabel alloc] initWithFrame:CGRectMake(30, 21, 215, 20)];
lblDate.text = dateString;
lblDate.textColor = [UIColor grayColor];
lblDate.font = [UIFont systemFontOfSize:12.0];
lblDate.tag = 2;
[lblDate setBackgroundColor:[UIColor clearColor]];



[cell.contentView addSubview:lblDate];
[cell.contentView addSubview:lblUser];


return cell;
}

0

你在编写删除单元格子视图中所有内容的代码方面是正确的。但是你把它写在了错误的位置。 UITableViewdequeueReusableCellWithIdentifier 会在分配和初始化一次后返回单元格。因此,你编写的用于删除 cell.contentView.subViews 的代码将永远不会运行,从而导致重叠的视图。

你可以将该代码放在 else 语句中,但我不喜欢这种方式。为什么每次 UITableView 需要单元格时都要分配和初始化所有的 contentView 呢?相反,我会创建一个 UILabel 并给它一个标签以便以后访问。像这样:

 UILabel *lblDate = nil;
  if (cell == nil)
  {
    cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    lblDate = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 215, 10)];
    lblDate.textColor = [UIColor grayColor];
    lblDate.font = [UIFont systemFontOfSize:10.0];
    lblDate.tag = 1;
    [lblDate setBackgroundColor:[UIColor clearColor]];
    [cell.contentView addSubview:lblDate];
  }
  else
  {
    //get a reference to the label in the recycled view
    lblDate = (UILabel *)[cell.contentView viewWithTag:1];
  }

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 这行代码总是返回一个单元格。在if语句之前,我必须先声明cell变量。 - user1107173
嗨,我们正在寻找一名兼职iOS开发人员在印度合作。兼职工作每周10-20小时。如果您或您认识的人有兴趣,请告诉我。我们是一个总部位于旧金山的小团队。 - user1107173

0

尝试这段代码。你的问题会被解决。

-(NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section     
{

    return [arrTableData count];

}


-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"Cell";

UILabel *lblName;

UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                   reuseIdentifier:CellIdentifier] autorelease];

    lblName = [[[UILabel alloc] initWithFrame:CGRectMake(10, 20, 300, 20.0)] autorelease];
    lblName.tag = LBLNAME;
    lblName.numberOfLines=1;
    lblName.textAlignment=UITextAlignmentLeft;
    lblName.font = [UIFont systemFontOfSize:16.0];
    lblName.textColor = [UIColor blackColor];
    lblName.backgroundColor = [UIColor clearColor];
    lblName.autoresizingMask = UIViewAutoresizingFlexibleRightMargin  ;
    [cell.contentView addSubview:lblName];

}else{

    lblName = (UILabel *)[cell.contentView viewWithTag:LBLNAME];
}
if (arrTableData.count>0) { lblName.text=[NSString stringWithFormat:@"%@",[arrTableData objectAtIndex:indexPath.row]];

}

return cell;}

arrTableData来自哪里? - user1107173
它是TableView数据源数组,其中包含要在TableView中显示的数据。您可以根据需要使用一些对象对其进行初始化并重新加载表格。 - Mahesh

0
在我的情况下,发生了同样的问题,在两个地方分配tableviewcell,一个是在tableviewcell自定义类中分配,另一个是在自定义视图控制器中分配。在我改变了所有分配之后,一切都正常工作了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接