根据自定义单元格增加主表视图行高

4

我有一个应用程序,其中我有一个表格视图,在该表格视图的每一行上,我动态创建一个自定义表格视图单元格。

以下是该代码。

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

cell2 = [nib objectAtIndex:0];

return cell2;

"FlowTableViewCell"是一个UITableViewCell。在这个自定义单元格中,我有一个tableview。
我正在从一个数组中显示一些数据在我的自定义tableview单元格上,这些数据的长度是不固定的。
我能够增加自定义单元格的大小,但不能根据自定义tableview单元格的大小来增加主tableview行高。
我希望根据自定义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:
(图片)
以下是我现在获得的输出:
(图片)
您可以看到上面的图像中,评论2被截断,而同一帖子的评论3显示在下一个帖子中。
我想要以下图像的输出:
(图片)
因此,我的问题是如何根据自定义TableViewCell的大小动态增加主TableView的单元格大小?
请帮帮我,任何帮助将不胜感激。
7个回答

5
您可以使用以下方法计算标签的高度:
- (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的一个方法。 - Alex Cio
它给我返回了这个错误:从一个返回类型不兼容的函数中返回 'CGRect'(又名 'struct CGRect')到 'CGFloat'(又名 'float') - Maulik shah
请帮帮我。我已经做了很多研究,但你的代码对我不起作用。 - Maulik shah
请问您能解释一下您面临的问题吗? - Satish Azad
有错误的代码。应用程序在 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 处崩溃。 - Rajesh Maurya
显示剩余6条评论

3
您可以使用以下代码动态调整高度。首先需要确定标签的高度,然后相应地调整单元格的高度。我在我的聊天应用程序中使用了这段代码,效果很好。
首先,在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 
    }

}

0

试试这个

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

在你的cellForRowAtIndexPath代理方法中,如果使用label,那么先将行数设置为0,然后设置label文本,最后添加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);

0

开始:

  1. 为视图中的所有单元格创建一个共同的UITableViewCell子类(例如FlowViewAbstractTableViewCell
  2. 在表视图单元格子类上创建一个类方法,例如+ (CGFloat)sizeForCellWithComment:(Comment *)comment。你要做的是设置一种方法来传递一个模型对象,每个表视图单元格子类都可以实现该方法。
  3. 创建所需数量的其他单元格子类,这些子类继承自FlowViewAbstractTableViewCell。在你的情况下,看起来你可以有叫做FlowViewTextCommentTableViewCellFlowViewPictureCommentTableViewCell的单元格。
  4. 对于这些子类中的每一个,实现那个+sizeForCellWithComment:方法。这将允许您根据传入的对象返回可变大小。
  5. 为您的UITableViewDelegate实现- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath。在这个方法中,你要想出你想使用哪个单元格类以及将哪个对象传递给那个大小方法。例如:

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

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


0

这个视频提供了一个很好的教程,介绍如何使用自动布局来动态调整UITableViewCells的大小。当我需要为应用程序实现此功能时,最终我选择了子类化UITableViewCell并以编程方式设置约束条件,效果非常好。


0

尝试自定义你的UITableViewCell,而不是使用预定义的。 - Yaman

0
- (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并检查该“str”值的size.height来进行检查。 - Ramya Yenduri

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