带dynamic高度iOS的UITableViewCell
我在我的应用程序中使用CustomCell实现了TableView,
我想根据UITableViewCell
中的文本长度,我的UITableViewCell
dynamic高度,
这里是Customcell
的快照
:这里是我的UITableView
的快照 : heightForRowAtIndexPath
代码片段
#define FONT_SIZE 14.0f #define CELL_CONTENT_WIDTH 320.0f #define CELL_CONTENT_MARGIN 10.0f - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; { NSString *text = [DescArr objectAtIndex:[indexPath row]]; 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, 100.0); return height; }
正如您在第二张图片中看到的,单元格的高度是固定的,它不会随文本(内容)大小而改变。
我在哪里犯错? 我怎样才能使标签或单元格根据其内容/文本更新其大小?
下面的代码对我来说工作得很好。试试这个
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGFloat lRetval = 10; CGSize maximumLabelSize = CGSizeMake(231, FLT_MAX); CGSize expectedLabelSize; CGFloat numberoflines = [thirdcellText length]/17.0; if (indexPath.section == 0) { expectedLabelSize = [firstcellText sizeWithFont:[UIFont systemFontOfSize:16.0] constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByWordWrapping]; lRetval = expectedLabelSize.height; } else if(indexPath.section == 1) { expectedLabelSize = [secondcellText sizeWithFont:[UIFont systemFontOfSize:16.0] constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByWordWrapping]; lRetval = expectedLabelSize.height; } else if (indexPath.section == 2) { expectedLabelSize = [thirdcellText sizeWithFont:[UIFont systemFontOfSize:16.0] constrainedToSize:CGSizeMake(231, numberoflines*17.0) lineBreakMode:NSLineBreakByWordWrapping]; lRetval = expectedLabelSize.height-128.0; } UIImage *factoryImage = [UIImage imageNamed:NSLocalizedString(@"barcode_factory_reset.png", @"")]; CGFloat height = factoryImage.size.height; if (lRetval < height) { lRetval = height+15.0; } return lRetval; }
尝试在您的customcell类的autolayout方法中添加以下代码
textview.frame = frame; CGRect frame1 = textview.frame; frame1.size.height = textview.contentSize.height-2; textview.frame = frame1; textview.contentSize = CGSizeMake(textview.frame.size.width, textview.frame.size.height); labelPtr.frame = CGRectMake(CGRectGetMinX(imageView.frame)+CGRectGetMaxX(imageView.frame)+5.0, textview.frame.size.height+10.0, 140, 16.0); [labelPtr setNeedsDisplayInRect:labelPtr.frame];
尝试设置如下的标签属性
labelPtr = [[UILabel alloc] initWithFrame:CGRectZero]; labelPtr.backgroundColor =[UIColor clearColor]; [labelPtr setNeedsLayout]; [labelPtr setNeedsDisplay]; [self.contentView addSubview:labelPtr];
请看这里 – dynamic表格视图单元格高度和自动布局教程。
你需要什么:
- 在单元格中设置所需要的元素约束(确保所有的操作都正确完成,否则可能会遇到很多问题)。 另外请确保将IntrinsicSize设置为PlaceHolder值
- 添加几个计算单元格大小的方法
方法:
//this will calculate required height for your cell -(CGFloat)heightForBasicCellAtIndexPath:(NSIndexPath *)indexPath { static UIYourClassCellName *sizingCell = nil; //create just once per programm launching static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sizingCell = [self.tableView dequeueReusableCellWithIdentifier:@"identifierOfCell"]; }); [self configureBasicCell:sizingCell atIndexPath:indexPath]; return [self calculateHeightForConfiguredSizingCell:sizingCell]; } //this method will calculate required height of cell - (CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell { [sizingCell setNeedsLayout]; [sizingCell layoutIfNeeded]; CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; return size.height; }
并致电
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return [self heightForBasicCellAtIndexPath:indexPath]; }
单元格的configuration
- (void)configureBasicCell:(RWBasicCell *)cell atIndexPath:(NSIndexPath *)indexPath { //make some configuration for your cell }
毕竟操作后,我得到下一个(单元格内的文本只作为占位符):
长期以来,如何正确确定单元格高度 – 看起来像 – 这是一个最好的解决scheme,boundingRectWithSize和constrainedToSize经常错误地计算文本高度,你需要创buildUILabel比使用sizeThatFits函数,见下面
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(8, 5, celllabelWidth, 9999)]; label.numberOfLines=0; label.font = [UIFont fontWithName:fontName size:textSize]; label.text = @"celllabelTextHere"; CGSize maximumLabelSize = CGSizeMake(celllabelWidth, 9999); CGSize expectedSize = [label sizeThatFits:maximumLabelSize]; return expectedSize.height; }
我看到很多解决scheme,但都是错误的或不完整的。 你可以用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) ;
对于迅捷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中创build你的单元使用这个,你不需要实现任何更多或覆盖。 (不要忘记号码行0)和底部标签(约束)降级“内容拥抱优先 – 垂直到250”
您可以在下一个url中下载代码: https : //github.com/jposes22/exampleTableCellCustomHeight
参考文献: http : //candycode.io/automatically-resizing-uitableviewcells-with-dynamic-text-height-using-auto-layout/
现在这非常简单
使用下面的步骤
- 为您的标签设置约束(如果使用自定义单元格)
- 行数必须是0
- 设置UITableView的几个属性
self.tableView.estimatedRowHeight = 100.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
请享用:)
欲了解更多详情,你可以检查
http://www.raywenderlich.com
stackoverflow.com
你可以试试这个;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { int topPadding = cell.yourLabel.frame.origin.x; int bottomPadding = cell.frame.size.heigth-(topPadding+cell.yourLabel.frame.size.height); NSString *text = [DescArr objectAtIndex:[indexPath row]]; CGSize maximumSize = CGSizeMake(cell.yourLabel.frame.size.width, 9999); CGSize expectedSize = [text sizeWithFont:yourCell.yourLabel.font constrainedToSize:maximumSize lineBreakMode:yourCell.yourLabel.lineBreakMode]; return topPadding+expectedSize.height+bottomPadding; }
请参阅您使用Autolayout的链接
否则你可以使用下面的方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NewsVCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; if (cell == nil) { cell = [[NewsVCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; } cell.titleCell.numberOfLines = 0; cell.descriptionCell.numberOfLines = 0; cell.titleCell.font = [UIFont systemFontOfSize:12.0f]; cell.descriptionCell.font = [UIFont systemFontOfSize:12.0f]; cell.descriptionCell.textColor = [UIColor lightGrayColor]; CGSize maximumLabelSize; if([UIDevice currentDevice].userInterfaceIdiom==UIUserInterfaceIdiomPad || [[[UIDevice currentDevice] model] isEqualToString:@"iPad Simulator"]) { maximumLabelSize = CGSizeMake(768, 10000); } else { maximumLabelSize = CGSizeMake(270, 10000); } NSString *newsTitle = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"]; NSString *descriptionsText = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"]; CGSize expectedTitleLabelSize = [newsTitle sizeWithFont: cell.titleCell.font constrainedToSize:maximumLabelSize lineBreakMode:cell.titleCell.lineBreakMode]; CGSize expectedDescriptionLabelSize = [descriptionsText sizeWithFont:cell.descriptionCell.font constrainedToSize:maximumLabelSize lineBreakMode:cell.descriptionCell.lineBreakMode]; NSLog(@"cellForRowAtIndexPath :indexpath.row %d: height expectedTitleLabelSize:%f , indexpath.row height expectedDescriptionLabelSize:%f",indexPath.row,expectedTitleLabelSize.height,expectedDescriptionLabelSize.height); if (newsTitle.length > 0) { cell.titleCell.frame = CGRectMake(20.0f, 10.0f, 270.0f ,expectedTitleLabelSize.height+20.0f); } else { cell.titleCell.frame = CGRectMake(20.0f, 10.0f, 270.0f ,expectedTitleLabelSize.height-20.0f); } if (descriptionText.length > 0) { cell.descriptionCell.frame = CGRectMake(20.0f, 10.0f + cell.titleCell.frame.size.height, 270.0f, expectedDescriptionLabelSize.height+20.0f); } else { cell.descriptionCell.frame = CGRectMake(20.0f, cell.titleCell.frame.size.height, 270.0f, 0.0f); } cell.descriptionCell.frame = CGRectMake(20.0f, 10.0f + cell.titleCell.frame.size.height, 270.0f, expectedDescriptionLabelSize.height+20.0f); cell.titleCell.text = newsTitle; cell.descriptionCell.text = descriptionsText; NSLog(@"indexpath.row %d :title %@ ",indexPath.row,newsTitle); NSLog(@"indexpath.row %d :description %@",indexPath.row,descriptionsText); return cell; }
编译标记 – UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { float totalHeight = 0.0f; UILabel *labelTitle; CGSize maximumLabelSize; if([UIDevice currentDevice].userInterfaceIdiom==UIUserInterfaceIdiomPad || [[[UIDevice currentDevice] model] isEqualToString:@"iPad Simulator"]) { labelTitle = [[UILabel alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 692.0f, 20.0f)]; // iPad maximumLabelSize = CGSizeMake(768.0f, 10000.0f); } else { labelTitle = [[UILabel alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 270.0f, 20.0f)]; maximumLabelSize = CGSizeMake(270.0f, 10000.0f); } labelTitle.font = [UIFont systemFontOfSize:12.0f]; NSString *newsTitle; NSString *newsDescription; // cell.titleCell.text = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"]; // cell.descriptionCell.text = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"]; newsTitle = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"]; newsDescription = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"]; NSLog(@"indexpath.row %d :newsDescription.length %d",indexPath.row,newsDescription.length); CGSize expectedTitleLabelSize; CGSize expectedDescriptionLabelSize; if (newsTitle.length > 0) { expectedTitleLabelSize = [newsTitle sizeWithFont:labelTitle.font constrainedToSize:maximumLabelSize lineBreakMode:labelTitle.lineBreakMode]; totalHeight = totalHeight + 20.0f; } else { expectedTitleLabelSize = CGSizeMake(0.0f, 0.0f); totalHeight = -20.0f; } if (newsDescription.length > 0) { expectedDescriptionLabelSize = [newsDescription sizeWithFont:labelTitle.font constrainedToSize:maximumLabelSize lineBreakMode:labelTitle.lineBreakMode]; totalHeight = totalHeight + 20.0f; } else { expectedDescriptionLabelSize = CGSizeMake(0.0f, 0.0f); totalHeight = -20.0f; } // NSLog(@"question: %f title:%f",expectedQuestionLabelSize.height,expectedTitleLabelSize.height); totalHeight = expectedDescriptionLabelSize.height + expectedTitleLabelSize.height + 30.0f+20.0f; return totalHeight; }
如果你想限制最大高度为100磅,你必须使用MIN
而不是MAX
:
CGFloat height = fmin(size.height, 100.0);
我需要一个dynamic的表格视图单元格的高度根据该单元格中显示的文本的数量。 我以这种方式解决了这个问题:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (!isLoading) { if ([self.conditionsDataArray count]>0) { Conditions *condition =[self.conditionsDataArray objectAtIndex:indexPath.row]; int height; UITextView *textview = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 236, 0)]; //you can set your frame according to your need textview.text = condition.comment; textview.autoresizingMask = UIViewAutoresizingFlexibleHeight; [tableView addSubview:textview]; textview.hidden = YES; height = textview.contentSize.height; NSLog(@"TEXT VIEW HEIGHT %f", textview.contentSize.height); [textview removeFromSuperview]; [textview release]; return height; } return 55; //Default height, if data is in loading state }
请注意,文本视图已添加为子视图,然后隐藏,所以请确保您将其添加为子视图,否则它的高度将不被考虑。
我刚刚写了关于这个问题和我最终select的方法。 你可以在这里阅读: 基于内容的dynamicUITableView单元高度
基本上,我创build了一个UITableView子类来处理默认和自定义单元格的所有这些。 这可能需要调整,但我已经使用它,并取得了良好的效果。
你可以在这里获取代码: https : //github.com/danielsaidi/DSTableViewWithDynamicHeight
希望它有帮助(…如果没有,我道歉,并希望听到为什么不)
为行高和估计的行高设置自动尺寸
@IBOutlet weak var table: UITableView! override func viewDidLoad() { super.viewDidLoad() // don't forget to set datasource and delegate. table.delegate = self table.datasource = self // Assign automatic dimension for 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(&line break mode = truncate tail)
- 相对于其超级视图/单元格容器设置所有约束(顶部,底部,左侧)。
- 可选 :即使没有数据,如果您希望标签覆盖的最小垂直面积,请设置标签的最小高度。