Xcode 6:Table 单元格中的标签不会展开/展开后显示更长的文本/与单元格对齐
Xcode 6: Label in Table Cell won't expand / display longer text upon expansion / line up with cell
问题:
我在 table 单元格中有一个标签,如下所示:
编辑: 虽然 table 视图不使用 AutoLayout,但单元格的 xib 会。这是它的样子:
现在,“...”表示评论(文本)太长,无法显示。然后用户可以单击单元格,这会向下展开单元格和标签,然后会显示其余文本。
这是 heightForRowAtIndexPath
的代码:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
if (tableView == self.rateAndReviewView.ratingsTable) {
BOOL isSelected = [self.selectedIndexPaths containsObject:indexPath];
CGFloat maxHeight = MAXFLOAT;
CGFloat minHeight = 40.0f;
if (isSelected){
CGFloat constrainHeight = isSelected?maxHeight:minHeight;
CGFloat constrainWidth = tableView.frame.size.width - 20.0f;
//
SQLReview *review = [reviewsArray objectAtIndex:indexPath.row];
NSString *text = review.comment;
CGSize constrainSize = CGSizeMake(constrainWidth, constrainHeight);
CGSize labelSize = [text sizeWithFont:[UIFont systemFontOfSize:15.0f]
constrainedToSize:constrainSize
lineBreakMode:NSLineBreakByWordWrapping];
CGFloat labelHeight = labelSize.height;
return MAX(labelHeight+20, 100.0f);
} else {
minHeight = 100.0f;
return minHeight;
}
}
}
这是 cellForRowAtIndexPath
的代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == self.rateAndReviewView.ratingsTable) {
static NSString *CellIdentifier = @"Cell";
VenueReviewCell *cell = (VenueReviewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
cell = [[[NSBundle mainBundle] loadNibNamed:@"ReviewCell" owner:nil options:nil] objectAtIndex:0];
}
[cell.contentView.layer setBorderWidth:0.5f];
cell.contentView.backgroundColor = [UIColor whiteColor];
SQLReview *review = [reviewsArray objectAtIndex:indexPath.row];
cell.usernameLabel.text = (review.user_name == nil) ? @"" : review.user_name;
cell.datetimeLabel.text = (review.datetime == nil) ? @"" : [review.datetime substringToIndex:10];
cell.commentLabel.text = (review.comment == nil) ? @"" : review.comment;
cell.commentLabel2.text = (review.comment == nil) ? @"" : review.comment;
float overallScore = (review.overall == nil) ? 0.0f : [review.overall floatValue];
NSArray *overallImageViewArray = @[cell.overallStarImageView1, cell.overallStarImageView2, cell.overallStarImageView3, cell.overallStarImageView4, cell.overallStarImageView5];
if([selectedIndexPaths containsObject:indexPath]) {
cell.commentLabel.hidden = YES;
cell.commentLabel2.hidden = NO;
CGSize commentLabelComputeSize = [cell.commentLabel2.text sizeWithFont:cell.commentLabel2.font constrainedToSize:CGSizeMake(cell.commentLabel2.frame.size.width, CGFLOAT_MAX) lineBreakMode:cell.commentLabel2.lineBreakMode];
CGFloat commentLabelHeightOffset = (commentLabelComputeSize.height - cell.commentLabel2.frame.size.height > 0) ? (commentLabelComputeSize.height - cell.commentLabel2.frame.size.height) : 0;
cell.commentLabel2.frame = CGRectMake(cell.commentLabel2.frame.origin.x, cell.commentLabel2.frame.origin.y, cell.commentLabel2.frame.size.width, cell.commentLabel2.frame.size.height + commentLabelHeightOffset);
cell.commentLabel2.autoresizingMask = UIViewAutoresizingFlexibleHeight;
cell.commentLabel2.numberOfLines = 0;
} else {
cell.commentLabel.hidden = NO;
cell.commentLabel2.hidden = YES;
}
[CommonUtilities displayStarRatingsWithScore:overallScore starImageViewArray:overallImageViewArray];
return cell;
}
return nil;
}
heightForRowAtIndexPath
中的 isSelected
部分确实有效,并且 table 单元格确实在点击时明显展开,但文本保持不变 - 至少,在 iOS 7 台以上设备。
编辑: 我还注销了 cell.commentLabel2.frame
的值,方法是添加:
NSLog(@"VenueTabViewController: cellForRow: contains indexpath %@, size: %@", indexPath, NSStringFromCGRect(cell.commentLabel2.frame));
在cellForRowAtIndexPath
的if
和else
中,显示如下:
第一次点击:
VenueTabViewController:cellForRow:包含索引路径 {length = 2,path = 0 - 1},大小:{{20, 31}, {285, 60.579999999999998}}
第二次点击:
VenueTabViewController:cellForRow:包含索引路径 {length = 2,path = 0 - 2},大小:{{20, 31}, {285, 21}}
所以它的大小确实发生了变化。
我试过的:
我用谷歌搜索了一下,发现 [string sizeWithFont:[UIFont systemFontOfSize:15.0f] constrainedToSize:constrainSize lineBreakMode:NSLineBreakByWordWrapping];
已经贬值了。因此,我将上面与之相关的行替换为:
CGSize labelSize = [text sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:17.0f]}];
CGFloat labelHeight = ceilf(labelSize.height);
这不仅没用,还阻止了细胞的扩张,我认为这可能是一种倒退。
我也尝试添加以下内容,因为为什么不:
VenueReviewCell *cell = (VenueReviewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
cell = [[[NSBundle mainBundle] loadNibNamed:@"ReviewCell" owner:nil options:nil] objectAtIndex:0];
}
[cell.commentLabel sizeToFit];
但还是不行。
然后,我简单地将 commentLabelHeightOffset
替换为 100,只是为了测试是否会发生任何变化:
cell.commentLabel2.frame = CGRectMake(cell.commentLabel2.frame.origin.x, cell.commentLabel2.frame.origin.y, cell.commentLabel2.frame.size.width, cell.commentLabel2.frame.size.height + commentLabelHeightOffset);
什么都没发生。
编辑: 这是我所做的,最终获得了关注——我按照 saif 的建议删除了单元格上的 AutoLayout。现在,虽然细胞确实在扩张,标签也随之扩张,但出于某种原因,我得到了这个:
我检查了代码,标签框架的 X 和 Y 没有改变(只是框架高度)并且文本在实际文本之前没有 "new lines"。
请问有什么帮助吗?
尝试自动调整大小:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
VenueReviewCell *cell = (VenueReviewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.commentLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight;
cell.commentLabel.numberOfLines = 0;
return cell;
}
如果您使用的是手动布局,那么您必须将标签的 numberOfLines
属性 设置为 0,并且您还需要在设置标签后调用 -sizeToFit
文本。
在这之后您可能还需要相应地更改其他一些框架,这样标签就不会重叠任何东西。
如果您使用的是 AutoLayout,那么仍然需要设置 numberOfLines
,但这取决于您的约束,如果您将标签的左右设置为超级视图的左右,那么它可以推断出最大宽度并垂直增加标签。
无论如何,您的屏幕截图清楚地显示标签设置为 numberOfLines = 1
,您的单元格高度看起来没问题,这是预料之中的,因为您是在代码中用设置的宽度计算它的。这是未被触发的标签的呈现。首先将 numberOfLines
更改为 0,然后在 layoutSubviews
中(如果您手动执行操作),您需要 sizeToFit
试试这个,将框架设置为行单元格中的 desc 标签(取决于文本大小),并在要展开单元格时重新加载 table 视图。
在cellForRowAtIndexPath
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
//code to add desc label
}
CGSize suggestedSize = [descriptionText sizeWithFont:descLabel.font constrainedToSize:CGSizeMake(descLabel.frame.size.width, FLT_MAX) lineBreakMode:descLabel.lineBreakMode];
float padding = 20;
[descLabel setFrame:CGRectMake(padding, CGRectGetMaxY(nameLabel.frame), CGRectGetWidth(tableView.frame)-(2*padding), suggestedSize.height)];
如果您在自定义单元格中使用自动布局,那么
- 保留备份,并取消选中自动布局
- select iPhone 在下拉列表中 select 禁用尺寸 class
如果行高有问题,
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
CGSize suggestedSize = [descriptionText sizeWithFont:descLabel.font constrainedToSize:CGSizeMake(descLabel.frame.size.width, FLT_MAX) lineBreakMode:descLabel.lineBreakMode];
float heightOfRow = CGRectGetMaxY(nameLabel.frame)+suggestedSize.height+5; // height of name label(as it is single line supported) + height of desc label + bottom padding
return heightOfRow;
}
希望对您有所帮助
如果您想继续使用自动版式:
-将 numberOfLines 设置为“0”
-实现以下两个TableView方法
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
Working with Self-Sizing Table View Cells这里有一个有用的参考。
问题:
我在 table 单元格中有一个标签,如下所示:
编辑: 虽然 table 视图不使用 AutoLayout,但单元格的 xib 会。这是它的样子:
现在,“...”表示评论(文本)太长,无法显示。然后用户可以单击单元格,这会向下展开单元格和标签,然后会显示其余文本。
这是 heightForRowAtIndexPath
的代码:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
if (tableView == self.rateAndReviewView.ratingsTable) {
BOOL isSelected = [self.selectedIndexPaths containsObject:indexPath];
CGFloat maxHeight = MAXFLOAT;
CGFloat minHeight = 40.0f;
if (isSelected){
CGFloat constrainHeight = isSelected?maxHeight:minHeight;
CGFloat constrainWidth = tableView.frame.size.width - 20.0f;
//
SQLReview *review = [reviewsArray objectAtIndex:indexPath.row];
NSString *text = review.comment;
CGSize constrainSize = CGSizeMake(constrainWidth, constrainHeight);
CGSize labelSize = [text sizeWithFont:[UIFont systemFontOfSize:15.0f]
constrainedToSize:constrainSize
lineBreakMode:NSLineBreakByWordWrapping];
CGFloat labelHeight = labelSize.height;
return MAX(labelHeight+20, 100.0f);
} else {
minHeight = 100.0f;
return minHeight;
}
}
}
这是 cellForRowAtIndexPath
的代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == self.rateAndReviewView.ratingsTable) {
static NSString *CellIdentifier = @"Cell";
VenueReviewCell *cell = (VenueReviewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
cell = [[[NSBundle mainBundle] loadNibNamed:@"ReviewCell" owner:nil options:nil] objectAtIndex:0];
}
[cell.contentView.layer setBorderWidth:0.5f];
cell.contentView.backgroundColor = [UIColor whiteColor];
SQLReview *review = [reviewsArray objectAtIndex:indexPath.row];
cell.usernameLabel.text = (review.user_name == nil) ? @"" : review.user_name;
cell.datetimeLabel.text = (review.datetime == nil) ? @"" : [review.datetime substringToIndex:10];
cell.commentLabel.text = (review.comment == nil) ? @"" : review.comment;
cell.commentLabel2.text = (review.comment == nil) ? @"" : review.comment;
float overallScore = (review.overall == nil) ? 0.0f : [review.overall floatValue];
NSArray *overallImageViewArray = @[cell.overallStarImageView1, cell.overallStarImageView2, cell.overallStarImageView3, cell.overallStarImageView4, cell.overallStarImageView5];
if([selectedIndexPaths containsObject:indexPath]) {
cell.commentLabel.hidden = YES;
cell.commentLabel2.hidden = NO;
CGSize commentLabelComputeSize = [cell.commentLabel2.text sizeWithFont:cell.commentLabel2.font constrainedToSize:CGSizeMake(cell.commentLabel2.frame.size.width, CGFLOAT_MAX) lineBreakMode:cell.commentLabel2.lineBreakMode];
CGFloat commentLabelHeightOffset = (commentLabelComputeSize.height - cell.commentLabel2.frame.size.height > 0) ? (commentLabelComputeSize.height - cell.commentLabel2.frame.size.height) : 0;
cell.commentLabel2.frame = CGRectMake(cell.commentLabel2.frame.origin.x, cell.commentLabel2.frame.origin.y, cell.commentLabel2.frame.size.width, cell.commentLabel2.frame.size.height + commentLabelHeightOffset);
cell.commentLabel2.autoresizingMask = UIViewAutoresizingFlexibleHeight;
cell.commentLabel2.numberOfLines = 0;
} else {
cell.commentLabel.hidden = NO;
cell.commentLabel2.hidden = YES;
}
[CommonUtilities displayStarRatingsWithScore:overallScore starImageViewArray:overallImageViewArray];
return cell;
}
return nil;
}
heightForRowAtIndexPath
中的 isSelected
部分确实有效,并且 table 单元格确实在点击时明显展开,但文本保持不变 - 至少,在 iOS 7 台以上设备。
编辑: 我还注销了 cell.commentLabel2.frame
的值,方法是添加:
NSLog(@"VenueTabViewController: cellForRow: contains indexpath %@, size: %@", indexPath, NSStringFromCGRect(cell.commentLabel2.frame));
在cellForRowAtIndexPath
的if
和else
中,显示如下:
第一次点击:
VenueTabViewController:cellForRow:包含索引路径 {length = 2,path = 0 - 1},大小:{{20, 31}, {285, 60.579999999999998}}
第二次点击:
VenueTabViewController:cellForRow:包含索引路径 {length = 2,path = 0 - 2},大小:{{20, 31}, {285, 21}}
所以它的大小确实发生了变化。
我试过的:
我用谷歌搜索了一下,发现 [string sizeWithFont:[UIFont systemFontOfSize:15.0f] constrainedToSize:constrainSize lineBreakMode:NSLineBreakByWordWrapping];
已经贬值了。因此,我将上面与之相关的行替换为:
CGSize labelSize = [text sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:17.0f]}];
CGFloat labelHeight = ceilf(labelSize.height);
这不仅没用,还阻止了细胞的扩张,我认为这可能是一种倒退。
我也尝试添加以下内容,因为为什么不:
VenueReviewCell *cell = (VenueReviewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
cell = [[[NSBundle mainBundle] loadNibNamed:@"ReviewCell" owner:nil options:nil] objectAtIndex:0];
}
[cell.commentLabel sizeToFit];
但还是不行。
然后,我简单地将 commentLabelHeightOffset
替换为 100,只是为了测试是否会发生任何变化:
cell.commentLabel2.frame = CGRectMake(cell.commentLabel2.frame.origin.x, cell.commentLabel2.frame.origin.y, cell.commentLabel2.frame.size.width, cell.commentLabel2.frame.size.height + commentLabelHeightOffset);
什么都没发生。
编辑: 这是我所做的,最终获得了关注——我按照 saif 的建议删除了单元格上的 AutoLayout。现在,虽然细胞确实在扩张,标签也随之扩张,但出于某种原因,我得到了这个:
我检查了代码,标签框架的 X 和 Y 没有改变(只是框架高度)并且文本在实际文本之前没有 "new lines"。
请问有什么帮助吗?
尝试自动调整大小:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
VenueReviewCell *cell = (VenueReviewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.commentLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight;
cell.commentLabel.numberOfLines = 0;
return cell;
}
如果您使用的是手动布局,那么您必须将标签的 numberOfLines
属性 设置为 0,并且您还需要在设置标签后调用 -sizeToFit
文本。
在这之后您可能还需要相应地更改其他一些框架,这样标签就不会重叠任何东西。
如果您使用的是 AutoLayout,那么仍然需要设置 numberOfLines
,但这取决于您的约束,如果您将标签的左右设置为超级视图的左右,那么它可以推断出最大宽度并垂直增加标签。
无论如何,您的屏幕截图清楚地显示标签设置为 numberOfLines = 1
,您的单元格高度看起来没问题,这是预料之中的,因为您是在代码中用设置的宽度计算它的。这是未被触发的标签的呈现。首先将 numberOfLines
更改为 0,然后在 layoutSubviews
中(如果您手动执行操作),您需要 sizeToFit
试试这个,将框架设置为行单元格中的 desc 标签(取决于文本大小),并在要展开单元格时重新加载 table 视图。
在cellForRowAtIndexPath
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
//code to add desc label
}
CGSize suggestedSize = [descriptionText sizeWithFont:descLabel.font constrainedToSize:CGSizeMake(descLabel.frame.size.width, FLT_MAX) lineBreakMode:descLabel.lineBreakMode];
float padding = 20;
[descLabel setFrame:CGRectMake(padding, CGRectGetMaxY(nameLabel.frame), CGRectGetWidth(tableView.frame)-(2*padding), suggestedSize.height)];
如果您在自定义单元格中使用自动布局,那么
- 保留备份,并取消选中自动布局
- select iPhone 在下拉列表中 select 禁用尺寸 class
如果行高有问题,
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
CGSize suggestedSize = [descriptionText sizeWithFont:descLabel.font constrainedToSize:CGSizeMake(descLabel.frame.size.width, FLT_MAX) lineBreakMode:descLabel.lineBreakMode];
float heightOfRow = CGRectGetMaxY(nameLabel.frame)+suggestedSize.height+5; // height of name label(as it is single line supported) + height of desc label + bottom padding
return heightOfRow;
}
希望对您有所帮助
如果您想继续使用自动版式:
-将 numberOfLines 设置为“0”
-实现以下两个TableView方法
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
Working with Self-Sizing Table View Cells这里有一个有用的参考。