【问题标题】:Increase the main tableview row height according to the custom cell根据自定义单元格增加主tableview行高
【发布时间】:2014-10-06 06:15:11
【问题描述】:

我有一个应用程序,其中有一个 Tableview,并且在该 tableview 的每一行上,我正在动态创建一个自定义 tableview 单元格。

下面是代码。

NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"flowviewTableViewCell" owner:self options:nil];

cell2 = [nib objectAtIndex:0];

return cell2;

“FlowTableViewCell”是一个 UITableViewCell。 在这个自定义单元格中,我有一个表格视图。

我在我的自定义表格视图单元格中显示了一些来自数组的数据,这些数据的长度各不相同。它不是固定的。

我可以增加自定义单元格大小,但不能增加主 tableview 行高,具体取决于自定义 tableview 单元格的大小。

我想根据自定义表格视图单元格的大小动态增加主表格视图单元格大小的高度。

通过以下代码,自定义tableView单元格的高度增加了。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{

    NSString *str = [arrComments objectAtIndex:indexPath.row];
    CGSize size = [str sizeWithFont:[UIFont fontWithName:@"Helvetica" size:14] constrainedToSize:CGSizeMake(280, 999) lineBreakMode:NSLineBreakByWordWrapping];
    NSLog(@"%f",size.height);
    if (size.height<20)

    {
        size.height=20;
        //m= size.height;

    }

    NSLog(@"%f",size.height);

    return size.height +  30;


}

如何根据自定义tableviewcell的大小调整主tableview的行高?

在这里,我附上一些截图以便清楚理解。

以下是我自定义的TableViewCell:

以下是我的主要 TableView :

以下是我现在得到的输出:

您可以在上图中看到comment2 被剪切,并且同一帖子的comment3 会显示在下一个帖子中。

我想要如下图的输出。

那么,我的问题是如何根据自定义 tableview 单元格的大小动态增加主 tableview 单元格大小的高度?

请帮助我。任何帮助将不胜感激

【问题讨论】:

    标签: ios objective-c iphone uitableview custom-cell


    【解决方案1】:

    您可以使用以下方法计算标签的高度:

    - (CGRect)heightOfLabel:(UILabel*)resizableLable
     {
        CGSize constrainedSize = CGSizeMake(resizableLable.frame.size.width  , 9999);
    
            NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                                  [UIFont fontWithName:@"HelveticaNeue" size:11.0], NSFontAttributeName,
                                                  nil];
    
            NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"textToShow" attributes:attributesDictionary];
    
            CGRect requiredHeight = [string boundingRectWithSize:constrainedSize options:NSStringDrawingUsesLineFragmentOrigin context:nil
    
            ];
    
    
            if (requiredHeight.size.width > self.resizableLable.frame.size.width) {
                requiredHeight = CGRectMake(0,0, self.resizableLable.frame.size.width, requiredHeight.size.height);
            }
    
          return requiredHeight;
        }
    

    从 TableView 委托方法调用此方法:

    - (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {
       UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    
       return [self heightOfLabel:cell.textLabel];
    
    } 
    

    【讨论】:

    • 我应该用什么方法写这个&我应该返回什么?
    • 这两种方法都必须插入到您的 UITableViewController 类中。第一个是计算CGRect的普通方法,第二个是UITableViewDelegate的方法
    • 它给了我这个错误Returning 'CGRect' (aka 'struct CGRect') from a function with incompatible result type 'CGFloat' (aka 'float')
    • 请帮助我。这方面的研究太多。你的编码不​​适合我。
    • 你能解释一下你面临的问题吗
    【解决方案2】:

    您可以使用以下代码动态调整高度。首先,您需要确定标签的高度,然后相应地调整单元格的高度。我一直在我的聊天应用程序中使用此代码并且工作正常。

    首先,在cellForRowAtIndexPath:中创建标签和图片视图

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
                /// Set Text Label
    
                UILabel *lbl_myText = [[UILabel alloc]initWithFrame:CGRectZero];
                [lbl_myText setLineBreakMode:NSLineBreakByWordWrapping];
                lbl_myText.minimumScaleFactor = FONT_SIZE;
                [lbl_myText setNumberOfLines:0];
                lbl_myText.textAlignment = NSTextAlignmentLeft;
                [lbl_myText setFont:[UIFont systemFontOfSize:FONT_SIZE]];
    
                NSString *text = [arr_text objectAtIndex:indexPath.row];
    
                CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE]];
    
                // Checks if text is multi-line
                if (size.width > lbl_myText.bounds.size.width)
                {
                    CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f); //// Here Width = Width you want to define for the label in its frame. The height of the label will be adjusted according to this.
    
                    //CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
    
                    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    
                    paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
    
    
                    CGRect textRect = [text boundingRectWithSize:constraint
                                                         options:NSStringDrawingUsesLineFragmentOrigin
                                                      attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:FONT_SIZE], NSParagraphStyleAttributeName: paragraphStyle.copy}
                                                         context:nil];
    
                    CGSize size = textRect.size;
    
                    [lbl_myText setText:text];
                    [lbl_myText setFrame:CGRectMake(cell.imgv_someoneImage.frame.size.width+8, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - cell.imgv_someoneImage.frame.size.width -(CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
                }
    
                else
                {
                    lbl_myText.frame = CGRectMake(10, 0, cell.frame.size.width - cell.imgv_someoneImage.frame.size.width - 18,18);
                    lbl_myText.textAlignment = NSTextAlignmentLeft;
                    [lbl_myText setText:text];
                }
    
                //lbl_myText.backgroundColor = [UIColor greenColor];
    
                [cell.contentView addSubview:lbl_myText];
    
                /// Set Date Label
    
                NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                [formatter setDateFormat:@"yyyy-MM-dd HH:mm"];
                NSString *stringFromDate = [formatter stringFromDate:[arr_date objectAtIndex:indexPath.row]];
    
                UILabel *lbl_myDate = [[UILabel alloc]initWithFrame:CGRectMake(cell.imgv_someoneImage.frame.size.width+8, lbl_myText.frame.size.height+10, cell.frame.size.width - cell.imgv_someoneImage.frame.size.width - 10 ,18)];
                lbl_myDate.text = stringFromDate;
                lbl_myDate.font = [UIFont fontWithName:@"Helvetica Neue" size:13.0];
                lbl_myDate.textColor = [UIColor lightGrayColor];
                lbl_myDate.textAlignment = NSTextAlignmentLeft;
                [cell.contentView addSubview:lbl_myDate];
    
                /// Set User Image
    
                UIImageView *imgv_myImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, lbl_myText.frame.origin.y, 63, 63)];
                imgv_myImage.image = selectedUserUploadedImage;
    
                [cell.contentView addSubview:imgv_myImage];
    }
    

    这里定义一些常量:

    #define FONT_SIZE 15.0f
    #define CELL_CONTENT_WIDTH 320.0f /// change this according to your screen size. This is just an example
    #define CELL_CONTENT_MARGIN 10.0f
    

    现在,创建标签后,您必须确定heightForRowAtIndexPath: 中单元格的高度

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSString *cellText = [arr_text objectAtIndex:indexPath.row];
    
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"yyyy-MM-dd HH:mm"];
        NSString *cellDate = [formatter stringFromDate:[arr_date objectAtIndex:indexPath.row]];
    
       // NSString *text = [items objectAtIndex:[indexPath row]];
    
        CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
    
        //CGSize labelsize = [cellText sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
    
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    
        paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
    
        ////for message label
        CGRect textRect = [cellText boundingRectWithSize:constraint
                                             options:NSStringDrawingUsesLineFragmentOrigin
                                          attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:FONT_SIZE], NSParagraphStyleAttributeName: paragraphStyle.copy}
                                             context:nil];
    
        CGSize labelsize = textRect.size;
    
        ////for date label
        CGRect datetextRect = [cellDate boundingRectWithSize:constraint
                                                 options:NSStringDrawingUsesLineFragmentOrigin
                                              attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:FONT_SIZE], NSParagraphStyleAttributeName: paragraphStyle.copy}
                                                 context:nil];
    
        CGSize datelabelsize = datetextRect.size;
    
    
        //CGSize datelabelsize = [cellDate sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
    
        ///combine the height
        CGFloat height = MAX(labelsize.height + datelabelsize.height, 64.0f);
    
        if(height == 64.0f)
        {
           return 74; /// label is of one line, return original/ static height of the cell
        }
    
        else
        {
            return height + 10; /// label is of multi-line, return calculated height of the cell + some buffer height 
        }
    
    }
    

    【讨论】:

      【解决方案3】:
      - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
      {
      
      NSString *str = [arrComments objectAtIndex:indexPath.row];
      UIFont *font = [UIFont fontWithName:@"Helvetica" size:14];
      CGRect new = [str boundingRectWithSize:CGSizeMake(280, 999) options:NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName: font} context:nil];
      CGSize size= new.size;
      NSLog(@"%f",size.height);
      if (size.height<20)
      
      {
          size.height=20;
          //m= size.height;
      
      }
      
      NSLog(@"%f",size.height);
      
      return size.height +  30;
      
      
      }
      

      【讨论】:

      • 如果行中有两个标签,则必须添加两个标签高度并检查是否获得正确的字符串值 NSString *str = [arrComments objectAtIndex:indexPath.row];通过放置 NSLog 并在 NSLog 中检查该“str”值的 size.height
      【解决方案4】:

      我们开始吧:

      1. 为视图中的所有单元格创建一个通用的UITableViewCell 子类(例如FlowViewAbstractTableViewCell
      2. 在表格视图单元格子类上创建类方法,例如+ (CGFloat)sizeForCellWithComment:(Comment *)comment。您正在做的是设置一个方法来将模型对象传递给每个表格视图单元子类可以实现的方法。
      3. 创建您需要的许多其他从FlowViewAbstractTableViewCell 继承的单元子类。在您的情况下,您似乎可以拥有名为 FlowViewTextCommentTableViewCellFlowViewPictureCommentTableViewCell 的名称。
      4. 对于每个子类,实现+sizeForCellWithComment: 方法。这将允许您根据传递给方法的对象返回可变大小。
      5. 为您的UITableViewDelegate 实现- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath。在此方法中,您将确定要使用哪个单元格类以及将哪个对象传递给该 size 方法。例如:

      - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { Comment *commentForCell = [self.comments objectAtIndex:indexPath.row]; return [CommentTableViewCell sizeForComment:commentForCell].height; }

      这将允许您根据对象返回可变的单元格高度。我一直使用可变大小的表格视图单元格并喜欢这种模式,因为我认为它在隐藏实现和遵循 MVC 方面做得最好。

      【讨论】:

        【解决方案5】:

        This video 提供了关于使用自动布局来动态调整 UITableViewCells 大小的精彩教程。当我需要为应用程序执行此操作时,我最终将 UITableViewCell 子类化并以编程方式设置我的约束,它就像一个魅力。

        【讨论】:

          【解决方案6】:

          比上面的solution简单很多

          【讨论】:

          • 尝试自定义你的 UITableViewCell 而不是使用预定义的
          【解决方案7】:

          试试这个

          -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
          {
           return [self.tableName.dataSource tableView:self.tableName cellForRowAtIndexPath:indexPath].contentView.frame.size.height;
          }
          

          如果您使用标签,则在您的 cellForRowAtIndexPath 委托中 然后首先将要标记的行数设置为 0,然后设置标签文本,然后添加它的 sizeTofit 属性。像这样

           [cell.yourLabelName setNumberOfLines:0];
           cell.yourLabelName.text = @"Your long or short text";
           [cell.yourLabelName sizeToFit];
          

          这将根据其中的文本扩展您的标签高度。

          之后,您可以像这样设置单元格 contentView 的大小。

           cell.contentView.frame = CGRectMake(cell.contentView.frame.origin.x, cell.contentView.frame.origin.y, cell.contentView.frame.size.width,"Height of label" + cell.contentView.frame.size.height);
          

          【讨论】:

            猜你喜欢
            • 2017-04-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多