首页 文章

设置自定义UITableViewCells高度

提问于
浏览
216

我正在使用自定义UITableViewCell,它有一些标签,按钮和图像视图可供显示 . 单元格中有一个标签,其文本为 NSString 对象,字符串的长度可以是可变的 . 因此,我无法在 UITableViewheightForCellAtIndex 方法中为单元格设置恒定高度 . 单元格's height depends on the label'的高度可以使用 NSStringsizeWithFont 方法确定 . 我试过用它,但看起来我在某个地方出错了 . 怎么修好?

这是用于初始化单元格的代码 .

if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier])
{
    self.selectionStyle = UITableViewCellSelectionStyleNone;
    UIImage *image = [UIImage imageNamed:@"dot.png"];
    imageView = [[UIImageView alloc] initWithImage:image];
    imageView.frame = CGRectMake(45.0,10.0,10,10);

    headingTxt = [[UILabel alloc] initWithFrame:   CGRectMake(60.0,0.0,150.0,post_hdg_ht)];
    [headingTxt setContentMode: UIViewContentModeCenter];
    headingTxt.text = postData.user_f_name;
    headingTxt.font = [UIFont boldSystemFontOfSize:13];
    headingTxt.textAlignment = UITextAlignmentLeft;
    headingTxt.textColor = [UIColor blackColor];

    dateTxt = [[UILabel alloc] initWithFrame:CGRectMake(55.0,23.0,150.0,post_date_ht)];
    dateTxt.text = postData.created_dtm;
    dateTxt.font = [UIFont italicSystemFontOfSize:11];
    dateTxt.textAlignment = UITextAlignmentLeft;
    dateTxt.textColor = [UIColor grayColor];

    NSString * text1 = postData.post_body;
    NSLog(@"text length = %d",[text1 length]);
    CGRect bounds = [UIScreen mainScreen].bounds;
    CGFloat tableViewWidth;
    CGFloat width = 0;
    tableViewWidth = bounds.size.width/2;
    width = tableViewWidth - 40; //fudge factor
    //CGSize textSize = {width, 20000.0f}; //width and height of text area
    CGSize textSize = {245.0, 20000.0f}; //width and height of text area
    CGSize size1 = [text1 sizeWithFont:[UIFont systemFontOfSize:11.0f]
                        constrainedToSize:textSize lineBreakMode:UILineBreakModeWordWrap];

    CGFloat ht = MAX(size1.height, 28);
    textView = [[UILabel alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,ht)];
    textView.text = postData.post_body;
    textView.font = [UIFont systemFontOfSize:11];
    textView.textAlignment = UITextAlignmentLeft;
    textView.textColor = [UIColor blackColor];
    textView.lineBreakMode = UILineBreakModeWordWrap;
    textView.numberOfLines = 3;
    textView.autoresizesSubviews = YES;

    [self.contentView addSubview:imageView];
    [self.contentView addSubview:textView];
    [self.contentView addSubview:webView];
    [self.contentView addSubview:dateTxt];
    [self.contentView addSubview:headingTxt];
    [self.contentView sizeToFit];

    [imageView release];
    [textView release];
    [webView release];
    [dateTxt release];
    [headingTxt release];
}

这是高度和宽度出错的标签:

textView = [[UILabel alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,ht)];

9 回答

  • 127

    要设置行高和估计行高的自动尺寸,请确保执行以下步骤,自动尺寸对单元格/行高度布局有效 .

    • 分配并实现tableview dataSource和delegate

    • UITableViewAutomaticDimension 分配给rowHeight&estimatedRowHeight

    • 实现委托/ dataSource方法(即 heightForRowAt 并返回值 UITableViewAutomaticDimension

    Objective C:

    // in ViewController.h
    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
    
      @property IBOutlet UITableView * table;
    
    @end
    
    // in ViewController.m
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.table.dataSource = self;
        self.table.delegate = self;
    
        self.table.rowHeight = UITableViewAutomaticDimension;
        self.table.estimatedRowHeight = UITableViewAutomaticDimension;
    }
    
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        return UITableViewAutomaticDimension;
    }
    

    Swift:

    @IBOutlet weak var table: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        // Don't forget to set dataSource and delegate for table
        table.dataSource = self
        table.delegate = self
    
        // Set automatic dimensions for row height
        table.rowHeight = UITableViewAutomaticDimension
        table.estimatedRowHeight = UITableViewAutomaticDimension
    }
    
    
    
    // UITableViewAutomaticDimension calculates height of label contents/text
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }
    

    对于UITableviewCell中的标签实例

    • 设置行数= 0(&换行模式=截断尾部)

    • 相对于其superview / cell容器设置所有约束(顶部,底部,右侧) .

    • 可选:如果您希望标签覆盖最小垂直区域,即使没有数据,也要设置标签的最小高度 .

    enter image description here

    Note :如果您希望以更高优先级展开/压缩的标签,则为“内容拥抱和压缩阻力优先级” .

    在这个例子中,我设置了低拥抱和高压缩阻力优先级,这导致为第二(黄色)标签的内容设置更多优先级/重要性 .

    enter image description here

  • 23

    如果所有行都是相同的高度,只需设置UITableView的 rowHeight 属性,而不是实现 heightForRowAtIndexPath . Apple Docs:

    使用tableView:heightForRowAtIndexPath:而不是rowHeight会对性能产生影响 . 每次显示表视图时,它都会在其每个行的委托上调用tableView:heightForRowAtIndexPath:这会导致具有大量行(大约1000或更多)的表视图出现严重的性能问题 .

  • 3

    你的 UITableViewDelegate 应该实现 tableView:heightForRowAtIndexPath:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return [indexPath row] * 20;
    }
    

    您可能希望使用 NSStringsizeWithFont:constrainedToSize:lineBreakMode: 方法来计算行高,而不是仅仅对indexPath执行一些愚蠢的数学运算:)

  • 490

    要使动态单元格高度随着Label文本的增加而增加,首先需要计算高度,即文本将在 -heightForRowAtIndexPath 委托方法中使用并返回其他标签的附加高度,图像(其他静态文本高度的最大高度)组件)并在单元格创建中使用相同的高度 .

    #define FONT_SIZE 14.0f
    #define CELL_CONTENT_WIDTH 300.0f  
    #define CELL_CONTENT_MARGIN 10.0f
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
    {
    
        if (indexPath.row == 2) {  // the cell you want to be dynamic
    
            NSString *text = dynamic text for your label;
    
            CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
            CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
    
            CGFloat height = MAX(size.height, 44.0f);
    
            return height + (CELL_CONTENT_MARGIN * 2);
        }
        else {
            return 44; // return normal cell height
        }
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        static NSString *CellIdentifier = @"Cell";
    
        UILabel *label;
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] ;
        }
    
        label = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, 280, 34)];
    
        [label setNumberOfLines:2];
    
        label.backgroundColor = [UIColor clearColor];
    
        [label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
    
        label.adjustsFontSizeToFitWidth = NO;
    
        [[cell contentView] addSubview:label];
    
    
        NSString *text = dynamic text fro your label;
    
        [label setText:text];
    
        if (indexPath.row == 2) {// the cell which needs to be dynamic 
    
            [label setNumberOfLines:0];
    
            CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
    
            CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
    
            [label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
    
        }
        return  cell;
    }
    
  • 7
    #define FONT_SIZE 14.0f
    #define CELL_CONTENT_WIDTH 300.0f
    #define CELL_CONTENT_MARGIN 10.0f
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath      *)indexPath;
    {
       /// Here you can set also height according to your section and row
       if(indexPath.section==0 && indexPath.row==0)
       {
         text=@"pass here your dynamic data";
    
         CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
    
         CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE]      constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
    
         CGFloat height = MAX(size.height, 44.0f);
    
         return height + (CELL_CONTENT_MARGIN * 2);
       }
       else
       {
          return 44;
       }
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell;
        UILabel *label = nil;
    
        cell = [tv dequeueReusableCellWithIdentifier:@"Cell"];
        if (cell == nil)
        {
           cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"Cell"];
        }
        ********Here you can set also height according to your section and row*********
        if(indexPath.section==0 && indexPath.row==0)
        {
            label = [[UILabel alloc] initWithFrame:CGRectZero];
            [label setLineBreakMode:UILineBreakModeWordWrap];
            [label setMinimumFontSize:FONT_SIZE];
            [label setNumberOfLines:0];
            label.backgroundColor=[UIColor clearColor];
            [label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
            [label setTag:1];
    
            // NSString *text1 =[NSString stringWithFormat:@"%@",text];
    
            CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
    
            CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
    
            if (!label)
            label = (UILabel*)[cell viewWithTag:1];
    
    
            label.text=[NSString stringWithFormat:@"%@",text];
            [label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH          - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
            [cell.contentView addSubview:label];
        }
    return cell;
    }
    
  • 5
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
    {
        CGSize constraintSize = {245.0, 20000}
        CGSize neededSize = [ yourText sizeWithFont:[UIfont systemFontOfSize:14.0f] constrainedToSize:constraintSize  lineBreakMode:UILineBreakModeCharacterWrap]
    if ( neededSize.height <= 18) 
    
       return 45
    else return neededSize.height + 45 
    //18 is the size of your text with the requested font (systemFontOfSize 14). if you change fonts you have a different number to use  
    // 45 is what is required to have a nice cell as the neededSize.height is the "text"'s height only
    //not the cell.
    
    }
    
  • 3

    在自定义UITableViewCell控制器中添加此项

    -(void)layoutSubviews {  
    
        CGRect newCellSubViewsFrame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
        CGRect newCellViewFrame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height);
    
        self.contentView.frame = self.contentView.bounds = self.backgroundView.frame = self.accessoryView.frame = newCellSubViewsFrame;
        self.frame = newCellViewFrame;
    
        [super layoutSubviews];
    }
    

    在UITableView -controller中添加此项

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return [indexPath row] * 1.5; // your dynamic height...
    }
    
  • 17

    感谢关于此主题的所有帖子,有一些非常有用的方法来调整UITableViewCell的rowHeight .

    以下是其他人的一些概念的汇编,这些概念在构建iPhone和iPad时非常有用 . 您还可以访问不同的部分,并根据不同的视图大小进行调整 .

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    {
        int cellHeight = 0;
    
        if ([indexPath section] == 0) 
        {
            cellHeight = 16;
            settingsTable.rowHeight = cellHeight;
        }
        else if ([indexPath section] == 1)
        {
            cellHeight = 20;
            settingsTable.rowHeight = cellHeight;
        }
    
        return cellHeight;
    }
    else
    {
        int cellHeight = 0;
    
        if ([indexPath section] == 0) 
        {
            cellHeight = 24;
            settingsTable.rowHeight = cellHeight;
        }
        else if ([indexPath section] == 1)
        {
            cellHeight = 40;
            settingsTable.rowHeight = cellHeight;
        }
    
        return cellHeight;
    }
    return 0;
    }
    
  • 8

    我看到了很多解决方案,但都是错误的或不完整的 . 您可以在viewDidLoad和autolayout中解决5行的所有问题 . 这对于客观的C:

    _tableView.delegate = self;
    _tableView.dataSource = self;
    self.tableView.estimatedRowHeight = 80;//the estimatedRowHeight but if is more this autoincremented with autolayout
    self.tableView.rowHeight = UITableViewAutomaticDimension;
    [self.tableView setNeedsLayout];
    [self.tableView layoutIfNeeded];
    self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0) ;
    

    对于swift 2.0:

    self.tableView.estimatedRowHeight = 80
     self.tableView.rowHeight = UITableViewAutomaticDimension      
     self.tableView.setNeedsLayout()
     self.tableView.layoutIfNeeded()
     self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0)
    

    现在使用xib创建您的单元格或在Storyboard中创建tableview使用此功能,您无需再执行任何操作或覆盖 . (不要忘记数字os行0)和底部标签(约束)降级“内容拥抱优先级 - 垂直到250”

    enter image description here

    enter image description here

    您可以在下一个网址中下载代码:https://github.com/jposes22/exampleTableCellCustomHeight

    参考文献:http://candycode.io/automatically-resizing-uitableviewcells-with-dynamic-text-height-using-auto-layout/

相关问题