【问题标题】:cellForRowAtIndexPath: UILabel overlaps after scrollcellForRowAtIndexPath:滚动后UILabel重叠
【发布时间】:2013-08-28 04:02:24
【问题描述】:

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 属性中设置您的文本。
  • 我正在为 iPhone 使用 FPPopOver,它不允许 .detailLabel。我必须使用标签。

标签: ios objective-c uitableview cell-formatting


【解决方案1】:

这是我想出的,效果很好:

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

【讨论】:

  • 我花了很多时间来寻找像你一样的问题的解决方案。当 init 打印时一切正常,但是当开始滚动标签混合时,它们的位置是混合的。基本上你的解决方案对我帮助很大。谢谢
【解决方案2】:

dequeueReusableCellWithIdentifier:forIndexPath: 保证返回一个单元格(一个新单元格,或者来自重用队列的一个单元格),所以你的 if (cell == nil) 子句永远不会被执行——这就是为什么它不会是否删除视图的区别。标签重叠,因为这是您设置它的方式。默认标签位于单元格的左侧,lblDate 也在左侧(距左侧 10 个点)。即使您将 lblDate 移到右侧,它也可能不会显示,因为我认为默认标签会占据整个单元格的宽度。最好制作一个带有两个标签的自定义单元格,并将它们放置在您想要的位置。

您还需要在添加另一个标签之前测试该标签是否已经存在。您可以给标签一个唯一的标签,并使用该标签检查视图,或者,我认为更简单的方法是在情节提要或 xib 中创建一个自定义单元格,然后在其中添加标签。那么你只需要在代码中给它们添加内容即可。

【讨论】:

    【解决方案3】:

    试试这个

    - (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。
    • 真的吗?你是如何创造你的细胞的?在故事板中?在 xib 中?
    • @rdelmar 以编程方式创建
    • 那你注册课程了吗?我还没有看到 dequeueReusableCellWithIdentifier:forIndexPath: 之前没有返回非零单元格的情况。
    • @rdelmar:是的,我同意。但是当我们以编程方式完成时。第一次 Cell 只会得到 nil ,对吗?那个时候它只是从下一次开始为同一个单元格初始化,它将调用 Else 部分,这样它就不会通过重构它而重叠。它只是改变了它的内容。情况就像 TableView 的上下滚动
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      添加这一行:

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

      之前:

      [cell.contentView addSubview:lblDate];
      

      【讨论】:

        【解决方案6】:

        您在编写从单元格子视图中删除所有内容的代码是正确的。但是你写错地方了。 UITableView's dequeueReusableCellWithIdentifier 将在单元格分配和初始化一次后返回给您。因此,您为删除 cell.contentView.subViews 而编写的代码将永远不会运行,并且您会得到 Overlapped 视图。

        您可以在 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 语句之前声明单元格。
        • 嘿。我们正在印度寻找兼职 iOS 开发人员。兼职将是每周 10-20 小时。如果您或您可能认识的人有兴趣,请告诉我。我们是一个位于旧金山的小团队。
        【解决方案7】:

        试试这个代码。您的问题将得到解决。

        -(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 来自哪里?
        • 它是 TableView 数据源数组,其中包含要在 tableview 中显示的数据。您可以根据需要使用一些对象对其进行初始化并重新加载表。
        【解决方案8】:

        试试这个

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

        【讨论】:

          【解决方案9】:
          if ([cell.contentView viewWithTag:tagnumber]
              {
                  [[cell.contentView viewWithTag:tagnumber]removeFromSuperview];
          
              }
          lblDate.tag = tagnumber;
              [cell.contentView addSubview:lblDate];
          

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

          【讨论】:

            【解决方案10】:

            在我的情况下发生了同样的问题,在 2 个地方分配 tableviewcell,一个在 tableviewcell 自定义类中分配,并且必须分配 customview 控制器,在我更改分配后,一切都会正常工作。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-09-30
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多