Ios UITableViewCell中所有方向的动态UILabel高度/宽度
我的问题基本上归结为支持UITableCell中UILabel(以及我假设的其他元素)动态高度的最佳方法,以及在旋转时正确调整标签宽度/高度和单元格高度的大小 我知道如何获得UILabel的预期高度,并相应地调整高度,但当您支持横向时,事情似乎变得相当棘手 我想这可能是一条路线,但我不确定你如何将其与需要计算细胞高度的表格结合起来。在init上手动设置帧,以确保他们根据已知数量进行计算,但这仅解决部分问题 这是我正在处理的图像,红色箭头指向动态高度标签,蓝色箭头指向将改变高度的单元格 我已经设法让它正常工作,但不确定它是否是正确的方法 以下是我学到的一些东西:Ios UITableViewCell中所有方向的动态UILabel高度/宽度,ios,uikit,Ios,Uikit,我的问题基本上归结为支持UITableCell中UILabel(以及我假设的其他元素)动态高度的最佳方法,以及在旋转时正确调整标签宽度/高度和单元格高度的大小 我知道如何获得UILabel的预期高度,并相应地调整高度,但当您支持横向时,事情似乎变得相当棘手 我想这可能是一条路线,但我不确定你如何将其与需要计算细胞高度的表格结合起来。在init上手动设置帧,以确保他们根据已知数量进行计算,但这仅解决部分问题 这是我正在处理的图像,红色箭头指向动态高度标签,蓝色箭头指向将改变高度的单元格 我已经设
中的cell.frame始终在纵向模式下给出其大小。(例如,对于iphone应用程序,它总是报告320)cellforrowatinexpath
- 将原型单元存储在属性中以供引用也有相同的问题,始终处于纵向模式
- 在这个用例中,自动调整标签宽度的遮罩大小似乎是无用的,事实上会导致旋转时计算的高度出现问题
中的tableView.frame以正确的方向显示其大小cellforrowatinexpath
- 您需要在轮换时调用
。我找不到任何其他方法来更新单元格和标签高度[tableView reloadData]
viewdiload
上,我获取每个标签字体的引用,以及标签宽度百分比与纵向视图中的tableView的浮点值
CWProductDetailDescriptionCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"DescriptionCell"];
self.descriptionLabelWidthPercentage = cell.descriptionLabel.frame.size.width / 320;
self.descriptionLabelFont = cell.descriptionLabel.font;
heightforrowatinexpath
中,我使用tableView宽度和已获取的百分比计算单元格高度:
case TableSectionDescription:
CGFloat labelWidth = self.tableView.frame.size.width * self.descriptionLabelWidthPercentage;
CGSize newLabelFrameSize = [self sizeForString:self.product.descriptionText WithConstraint:CGSizeMake(labelWidth, MAXFLOAT) AndFont:self.descriptionLabelFont];
return newLabelFrameSize.height + kTextCellPadding;
cellforrowatinexpath
中,我计算标签帧的帧并更新它
cell = [tableView dequeueReusableCellWithIdentifier:@"DescriptionCell"];
((CWProductDetailDescriptionCell *)cell).descriptionLabel.text = self.product.descriptionText;
CGRect oldFrame = ((CWProductDetailDescriptionCell *)cell).descriptionLabel.frame;
CGFloat labelWidth = self.tableView.frame.size.width * self.descriptionLabelWidthPercentage;
CGSize newLabelFrameSize = [self sizeForString:self.product.descriptionText WithConstraint:CGSizeMake(labelWidth, MAXFLOAT) AndFont:((CWProductDetailDescriptionCell *)cell).descriptionLabel.font];
((CWProductDetailDescriptionCell *)cell).descriptionLabel.frame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, labelWidth, newLabelFrameSize.height);
didRotateFromInterfaceOrientation
中,您需要[self.tableView重载数据]
- 在返回
中的单元格之前(不确定这是否正确)cellforrowatinedexpath
- 它们在某种程度上打乱了高度计算,而你的标签最终会比风景画中的标签更糟糕
是这样。正确的方法是什么?我见过很多这样的问题,但没有一个能完全解决这个问题。显然,我需要写下我的巨大问题,然后在电脑前休息一下才能弄清楚 这就是解决方案: 动态计算UILabel高度并利用自动调整遮罩大小的主要步骤包括:
rowAtIndexPath高度中
- 根据所处的方向调整参考单元格宽度
- 然后,您可以可靠地使用包含的UILabel框架宽度来计算高度
cellForRowAtIndexPath
中进行任何帧调整
- UITableViewCell在调用后立即执行所有布局工作,因此您的努力充其量是徒劳的,最坏的情况下,它们会把事情搞砸
中的帧调整是否会显示单元格中的行路径
- 我很生气我忘了这件事
- 它发生在所有UITableViewCell内部布局之后和绘制之前
- 带有自动调整大小遮罩的标签已具有正确的宽度,可用于计算
self.descriptionReferenceCell = [self.tableView dequeueReusableCellWithIdentifier:@"DescriptionCell"];
self.attributeReferenceCell = [self.tableView dequeueReusableCellWithIdentifier:@"AttributeCell"];
在heightforrowatinexpath
do计算可变高度单元格
我首先更新引用单元格的宽度,以便它显示其子视图(UILabels),然后我可以将其用于计算。然后,我使用更新的标签宽度来确定标签的高度,并添加任何必要的单元格填充来计算单元格高度。(请记住,只有当单元格的高度随标签一起改变时,才需要进行这些计算)
在cellforrowatinexpath
中,不要根据方向执行任何与布局相关的动态更新
在中,将为rowatinedxpath显示单元格
更新标签高度
由于表格单元格已经执行了布局子视图
,因此标签已经具有正确的宽度,我使用它来计算标签的确切高度。我可以安全地更新我的标签高度
case TableSectionDescription:
CGRect oldFrame = ((CWProductDetailDescriptionCell *)cell).descriptionLabel.frame;
CGSize newLabelFrameSize = [self sizeForString:self.product.descriptionText WithConstraint:CGSizeMake(oldFrame.size.width, MAXFLOAT) AndFont:((CWProductDetailDescriptionCell *)cell).descriptionLabel.font];
((CWProductDetailDescriptionCell *)cell).descriptionLabel.frame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, oldFrame.size.width, newLabelFrameSize.height);
break;
在旋转时重新加载数据
如果不重新加载数据,可见单元格将不会更新其高度和标签
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
[self.tableView reloadData];
}
需要指出的另一点是,我使用了一个helper类来计算标签高度,这个标签高度只包含基本调用。实际上,它不再保存太多的代码(我以前在那里有其他东西),所以直接使用普通的方法
- (CGSize) sizeForString:(NSString*)string WithConstraint:(CGSize)constraint AndFont:(UIFont *)font {
CGSize labelSize = [string sizeWithFont:font
constrainedToSize:constraint
lineBreakMode:UILineBreakModeWordWrap];
return labelSize;
}
我同意大多数人的看法
- (CGSize) sizeForString:(NSString*)string WithConstraint:(CGSize)constraint AndFont:(UIFont *)font {
CGSize labelSize = [string sizeWithFont:font
constrainedToSize:constraint
lineBreakMode:UILineBreakModeWordWrap];
return labelSize;
}
NSLog(@"Cell frame.size.width=%f", cell.frame.size.width);
@interface MyViewController () {
NSArray *_cellHeights; // array of arrays (for each table view section) of numbers (row heights)
}
- (void)_recalculateCellHeights
{
NSMutableArray *cellHeights = [[NSMutableArray alloc] init];
for (NSUInteger section=0; section<[self.tableView numberOfSections]; section++) {
NSMutableArray *sectionCellHeights = [[NSMutableArray alloc] init];
for (NSUInteger row=0; row<[self.tableView numberOfRowsInSection:section]; row++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
// Set cell's width to match table view's width
CGRect cellFrame = cell.frame;
cellFrame.size.width = CGRectGetWidth(self.tableView.frame);
cell.frame = cellFrame;
CGFloat cellHeight = self.tableView.rowHeight; // default
if (cell.textLabel.numberOfLines == 0 || (cell.detailTextLabel && cell.detailTextLabel.numberOfLines == 0)) {
[cell layoutIfNeeded]; // this is necessary on iOS 7 to give the cell's text labels non-zero frames
// Calculate the height of the cell based on the text
[cell.textLabel sizeToFit];
[cell.detailTextLabel sizeToFit];
cellHeight = CGRectGetHeight(cell.textLabel.frame) + CGRectGetHeight(cell.detailTextLabel.frame);
// This is the best I can come up with for this :(
if (self.tableView.separatorStyle != UITableViewCellSeparatorStyleNone) {
cellHeight += 1.0;
}
}
[sectionCellHeights addObject:[NSNumber numberWithFloat:cellHeight]];
}
[cellHeights addObject:sectionCellHeights];
}
_cellHeights = cellHeights;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// Assign any fonts or other adjustments which may affect height here
// Enable multiple line support so textLabel can grow vertically
cell.textLabel.numberOfLines = 0;
}
// Configure the cell...
cell.textLabel.text = [self.texts objectAtIndex:indexPath.section];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (_cellHeights) {
NSArray *sectionCellHeights = [_cellHeights objectAtIndex:indexPath.section];
return [[sectionCellHeights objectAtIndex:indexPath.row] floatValue];
}
return self.tableView.rowHeight; // default
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self _recalculateCellHeights];
[self.tableView reloadData];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[self _recalculateCellHeights];
[self.tableView reloadData];
}