当表格单元格包含大量文本和图像时,我遇到了确定表格单元格高度的问题。但问题是上下文敏感,取决于使用的文本类型。我将解释这个问题,然后给出我用来格式化单元格和确定单元格高度的代码。 当我在单元格的左侧有一个图像时,我从图像的最大高度与文本中获取单元格高度。问题是在所有情况下都没有正确计算文本高度。下面,我在底部单元格中有以下文字:
“P 154越南家常菜:非常好!!将香料搅拌成糊状 - 效果很好;在zuchinni上使用剩余的酱汁烧烤;运作良好;厚猪排;在450和525之间煮熟35分钟“。
表格视图一直滚动到底部。正如您所看到的,文本的底部不存在(“在450和525之间烹饪35分钟”)。实际发生的是文本宽度未正确确定。下面,文本宽度计算为cell.textLabel.bounds.size.width:234像素。基于此,文本的高度计算错误。
但是,如果我按下附件按钮(“>”)并下降到我的下一个视图,然后从该视图返回(使用带有导航控制器的“后退”按钮),我通常会得到以下更改的表格显示(但有时我仍然得到上面的视图而没有剩余的文本):
在这种情况下,第二次显示表视图时,文本的宽度计算为cell.textLabel.bounds.size.width:163像素。
两个文本宽度之间的差异(234 - 163 = 71像素)。图像宽度为100像素。
不幸的是,情况比这更复杂:
1)如果单元格中没有图像,我确定文本的宽度没有问题
2)如果我只使用一系列简单的文本行,例如在每个字符后带有回车符的连续数字/字母系列,则正确确定宽度。例如,如果单元格中的文本是:
1
2
3
4
5
6
7
8
9
0
一个
乙
Ç
3)如果下面(下面)的单元格有大量的全行文本(不是由字符组成的文本后跟回车),那么我永远不会正确计算单元格宽度(因此高度永远不会正确计算。)
我尝试了什么?
在cellForRowAtIndexPath中,我尝试过: cell.textLabel.autoresizingMask = UIViewAutoresizingNone; 正如Dynamic UILabel Heights/Widths in UITableViewCell in all Orientations所建议的那样,但这并没有改变这种情况。
我还尝试将Calculating multiline text height for UILabel/UITableViewCell: different results when calculating vs actual drawing中的建议添加到cellForRowAtIndexPath中,这会强制文本标签的新宽度,但这不起作用。
工作的黑客
的工作原理是强制文本标签宽度为heightForRowAtIndexPath中的正确宽度。然而,这肯定是一个黑客。我想要一个更好的解决方案。想法?
代码
在下面的代码中,BUG74是我在这里描述的问题。
// https://stackoverflow.com/questions/129502/how-do-i-wrap-text-in-a-uitableviewcell-without-a-custom-cell
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"CustomCellCommentList";
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSLog(@"CommentList.cellForRowAtIndexPath: nil case");
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
IF_IOS6_OR_GREATER(
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
);
IF_LESS_THAN_IOS6(
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
);
// To remove any maximum limit, and use as many lines as needed, set the value of this property to 0.
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
cell.textLabel.autoresizingMask = UIViewAutoresizingNone;
}
NSDictionary *menuItemCommentDictionary =
[Globals GetIthMenuItemComment: indexPath.row forMenuItem: menuItemName andRestaurant: restaurantName];
//NSDate *commentDate = [menuItemCommentDictionary objectForKey:@"date"];
if (CommentListDebug) NSLog(@"cellForRowAtIndexPath");
UIImage *theIcon;
NSString *imageFileName = [menuItemCommentDictionary objectForKey:COMMENT_KEY_IMAGE_FILENAME];
if (imageFileName) {
// Scaling images in table view cells
// https://stackoverflow.com/questions/9046573/uitableviewcell-resize-image
#define DEFAULT_TABLE_CELL_HEIGHT 44
#define IMAGE_WIDTH_IN_TABLE_CELL 100
/* I'm going to give images a constant width and adjust
the height of the table cell according to their height.
*/
theIcon = [PersistentStorage retrieveIconFromFile:imageFileName];
if (CommentListDebug) NSLog(@"icon: %@", theIcon);
//NSNumber *iconHeight = [menuItemCommentDictionary objectForKey:@"imageIconHeight"];
//if (CommentListDebug) NSLog(@"iconHeight: %d", [iconHeight intValue]);
cell.imageView.image = theIcon;
} else {
if (CommentListDebug) NSLog(@"No image file name");
cell.imageView.image = nil; // Otherwise, if using old cell, uses old icon image
}
NSString *cellText = [menuItemCommentDictionary objectForKey:@"menuItemComment"];
// 1/5/13; Bug# 62; only if there is no icon/image and no text
// should we mark as empty.
if ((! imageFileName) && ((nil == cellText) || ([cellText length] == 0))) {
cellText = EMPTY_TEXT; // temporary empty text
}
cell.textLabel.text = cellText;
// BUG74: 1/29/13;
// We are not having problems with the text width when there
// is no icon, so only do this when there is an icon
// NOTE: This does *not* work; for some reason, the frame.size.width
// is not retained in the call to heightForRowAtIndexPath.
if (imageFileName) {
CGRect labelFrame = cell.textLabel.frame;
labelFrame.size.width = 287 - 27 - theIcon.size.width;
NSLog(@"CommentList.cellForRowAtIndexPath: labelFrame.size.width: %d", (int) labelFrame.size.width);
cell.textLabel.frame = labelFrame;
[cell.textLabel sizeToFit];
}
return cell;
}
- (CGFloat)tableView:(UITableView *)thisTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *menuItemCommentDictionary =
[Globals GetIthMenuItemComment: indexPath.row forMenuItem: menuItemName andRestaurant: restaurantName];
NSString *cellText = [menuItemCommentDictionary objectForKey:@"menuItemComment"];
// 1/5/13; Bug# 62; I'm going to allow empty comments in the case
// where there is no picture and no text. This is to allow a user
// to have a smiley rating only but no picture and no text.
// The issue here is that with no text, the height of the row
// is too small, and looks odd. And it's hard to select that row to
// delete because it's not very tall.
// My fix for this it to add some temporary empty text. I've used
// non-white space text, because I still get the issue if I use
// white space. If I add the display of smiley's in the comment
// list then this issue should go away).
// For some reason the cellText does not seem to be nil when there
// is no text.
if ((nil == cellText) || ([cellText length] == 0)) {
cellText = EMPTY_TEXT; // temporary empty text
}
//NSDate *commentDate = [menuItemCommentDictionary objectForKey:@"date"];
NSString *imageFileName = [menuItemCommentDictionary objectForKey:COMMENT_KEY_IMAGE_FILENAME];
// If I directly retrieve the icon from the file and display it
// that way, I get a mess! The image is much too large!!
UIImage *theIcon = nil;
if (imageFileName) {
theIcon = [PersistentStorage retrieveIconFromFile:imageFileName];
}
UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:17.0];
// Some of the following code modified from:
//https://stackoverflow.com/questions/1947970/dynamic-calculation-of-uilabel-width-in-uitableviewcell
// Find the cell for this index path
UITableViewCell *cell = [self tableView:thisTableView cellForRowAtIndexPath:indexPath];
//CGFloat cellHeight = cell.frame.size.height;
// Calculate text size after forcing a layout
[cell layoutIfNeeded];
//CGSize textSize = [cell.textLabel.text sizeWithFont:cellFont constrainedToSize:CGSizeMake(cell.contentView.bounds.size.width, MAXFLOAT) lineBreakMode:cell.textLabel.lineBreakMode];
NSLog(@"CommentList.heightForRowAtIndexPath: cell.textLabel.bounds.size.width: %d", (int) cell.textLabel.bounds.size.width);
// In my tests, bounds.size.width is the same as frame.size.width
NSLog(@"CommentList.heightForRowAtIndexPath: cell.textLabel.frame.size.width: %d", (int) cell.textLabel.frame.size.width);
// cell.contentView.bounds.size.width gives the full width of the
// cell contents, which was 287 pixels when I tested it
if (CommentListDebug) NSLog(@"CommentList.heightForRowAtIndexPath: cell.contentView.bounds.size.width: %d", (int) cell.contentView.bounds.size.width);
// parameters to CGSizeMake are: width, height
// the width parameter here is supposed to be the text width;
CGSize constraintSize;
if (theIcon) {
// Start hack for BUG74; 1/29/13
// The number 27 just works; Is it the width of the
// accessory button within the cell?
// cell.contentView.bounds.size.width was 287 when I checked.
int textWidth = cell.contentView.bounds.size.width - 27 - theIcon.size.width;
constraintSize = CGSizeMake(textWidth, MAXFLOAT);
// End hack for BUG74; 1/29/13
} else {
constraintSize = CGSizeMake(cell.textLabel.bounds.size.width, MAXFLOAT);
}
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:cell.textLabel.lineBreakMode];
//NSNumber *iconHeight = [menuItemCommentDictionary objectForKey:@"imageIconHeight"];
#define LABEL_HEIGHT_EXTRA 20
#define ICON_HEIGHT_EXTRA 10
int textHeight = labelSize.height + LABEL_HEIGHT_EXTRA;
if (theIcon) {
//if ([iconHeight intValue] > 0) {
// Add 10 EXTRA here to give some white space between icons;
// with no white space, it can be hard to tell where one icon
// starts and where another ends, particularly because
// icons have variable height.
int iconHeight = ((int) theIcon.size.height) + ICON_HEIGHT_EXTRA;
/* if (CommentListDebug) */NSLog(@"CommentList.heightForRowAtIndexPath: icon height: %d; icon width: %d", (int) theIcon.size.height, (int) theIcon.size.width);
// BUG74: 1/28/13; If the text height is taller than the image
// height use the text height as the cell height.
NSLog(@"CommentList.heightForRowAtIndexPath: iconHeight= %d, textHeight= %d", iconHeight, textHeight);
if (iconHeight >= textHeight) return iconHeight;
return textHeight;
//return [iconHeight intValue] + 10;
} else {
// No image; use label size for height.
return textHeight;
}
}
答案 0 :(得分:0)
所以如果我弄错了,请纠正我,但是如果你能够增加单元格的大小(如底部图片)那么一切都会按你想要的方式工作吗?如果是这种情况,您可以覆盖:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
这将允许您指定单元格的高度。通过这种方式,您可以设置它们并防止它们切割底部的文本(如第一张图片)。