我正在构建一个基于UITableViewCellStyle1(左右)的自定义应用程序内设置视图。
我正在尝试动态计算单元格左侧标签(标题)的宽度,以确定右侧文本字段的宽度。
当我在模拟器中启动应用程序并加载视图时,标题标签的宽度为零,直到我向下滚动视图并且单元格不可见,然后当我向后滚动时,大小按预期调整。我相信这可能与细胞重复使用有关。
我需要单元格中的标题标签在视图加载时具有正确的宽度,而不是在它们一次消失之后。
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
static NSString* reuseIdentifier = @"SettingsCell";
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if ( !cell )
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier] autorelease];
[cell setBackgroundColor:[UIColor baeDarkGrayColor]];
UILabel* cellLabel = [cell textLabel];
[cellLabel setTextColor:[UIColor whiteColor]];
[cellLabel setBackgroundColor:[UIColor clearColor]];
[cell setUserInteractionEnabled:YES];
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
}
// Populate cell with corresponding data.
NSDictionary* tableSection = [_tableData objectAtIndex:indexPath.section];
// Set the label
UILabel* textLabel = [cell textLabel];
NSString* labelString = [[tableSection objectForKey:@"itemTitles"] objectAtIndex:indexPath.row];
[textLabel setText:labelString];
// CGSize constrainedSize;
// constrainedSize.width = MAXFLOAT;
// constrainedSize.height = MAXFLOAT;
CGSize textLabelSize = [textLabel.text sizeWithFont:textLabel.font /*constrainedToSize:constrainedSize*/];
NSLog(@"text label width: %f", textLabelSize.width);
// Set the accessory view
BAESettingsTableCellAccessoryType accessoryType = [[[tableSection objectForKey:@"itemAccessories"] objectAtIndex:indexPath.row] integerValue];
switch ( accessoryType )
{
case BAESettingsTableCellAccessoryDisclosureIndicator:
{
UIImageView* disclosureView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"AccessoryDisclosure.png"]];
[cell setAccessoryView:disclosureView];
[disclosureView release];
break;
}
case BAESettingsTableCellAccessoryOnOffSwitch:
{
UISwitch* onOffSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
[onOffSwitch setOn:YES];
[cell setAccessoryView:onOffSwitch];
[onOffSwitch release];
break;
}
case BAESettingsTableCellAccessoryNone:
// default:
// break;
{
CGRect cellFrame = [cell frame];
float detailTextFieldWidth = cellFrame.size.width - ( textLabelSize.width + 50 );
float detailTextFieldHeight = cellFrame.size.height - 1;
NSLog(@"detail text field calculated frame width, height, %f, %f", detailTextFieldWidth, detailTextFieldHeight);
CGRect frame = CGRectMake(cellFrame.origin.x, cellFrame.origin.y, detailTextFieldWidth, detailTextFieldHeight);
UITextField* textField = [[UITextField alloc] initWithFrame:frame];
NSString* detailLabelString = [[tableSection objectForKey:@"itemDetailStrings"] objectAtIndex:indexPath.row];
textField.text = detailLabelString;
textField.textColor = cell.detailTextLabel.textColor;
textField.textAlignment = UITextAlignmentRight;
textField.borderStyle = UITextBorderStyleRoundedRect;
[cell setAccessoryView:textField];
[textField release];
break;
}
}
return cell;
}
答案 0 :(得分:16)
明确设置字体可以解决您的问题。
CGSize textLabelSize = [textLabel.text sizeWithFont:[UIFont systemFontOfSize:17]];
Gory Detals:
当tableview首次加载时,由于字体大小为0,此片段返回零宽度。
[textLabel.text sizeWithFont:textLabel.font]
我通过显示单元格字体的磅值来解决这个问题。
NSLog(@"font size: %f", cell.textLabel.font.pointSize);
点大小为零,直到细胞离开屏幕然后回来,就像你描述的那样。
答案 1 :(得分:5)
我完全同意它应该是一个bug是非常烦人的。为什么Apple的优秀人员会在不确保电池完全安装的情况下询问电池高度。愚蠢!但是,请尝试:
,而不是使用已弃用的函数[cell layoutIfNeeded];
调用此方法与设置的单元格具有相同的效果,包括边界,单元格字体等。因此,此后的任何计算都可以访问完全设置的单元格。这是完整的代码:
-(CGFloat) tableView:(UITableView *) tableView heightForRowAtIndexPath:(NSIndexPath *) indexPath {
// Find the cell for this index path
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
CGFloat cellHeight = cell.frame.size.height;
// Calculate text size after forcing a layout
[cell layoutIfNeeded];
CGSize textSize = [cell.textLabel.text sizeWithFont:cell.textLabel.font constrainedToSize:CGSizeMake(cell.contentView.bounds.size.width, 99999) lineBreakMode:cell.textLabel.lineBreakMode];
// Only change the cell height if the text forces a growth
if (textSize.height > cellHeight) {
cellHeight = textSize.height;
}
return cellHeight;
}
答案 2 :(得分:3)
我发现了同样的问题,但我找到了解决方法。仅供参考我提出了Apple的错误(错误ID#7535066)。 Lex,在你的例子中,如果你使用cell.font而不是textLabel.font,它应该可以工作,虽然你会得到一个编译器警告,因为这是一个不推荐的方法调用。我不确定你是否能够看到我提出的错误的细节,所以我在这里粘贴细节:
iPhone SDK 3.1.2(7D11)NSString UIKit Additions方法sizeWithFont返回nil
内容 我在UITableView委托方法中装饰UITableViewCells:
我希望找到单元格中已有的文本长度,以正确格式化新视图,所以我调用了NSString UIKit Additions方法:
当我使用cell.textLabel.font作为font参数时,它总是返回一个空的CGSize
如果我使用DEPRECATED方法,cell.font作为参数,它会按预期返回CGSize值。
再现的步骤 1.使用TableView创建一个UITableViewController,并用一些示例数据填充它 2.在存根方法cellForRowAtIndexPath中,在注释//设置单元格之后,以及填充cell.textLabel.text的位置,请输入以下内容:
CGSize size = [cell.textLabel.text sizeWithFont:[[cell textLabel] font] constrainedToSize:CGSizeMake(320, 480)];
NSLog(@"cell frame: %f %f", size.width, size.height);
CGSize size2 = [cell.textLabel.text sizeWithFont:[cell font] constrainedToSize:CGSizeMake(320, 480)];
NSLog(@"DEPRECATED cell frame: %f %f", size2.width, size2.height);
预期成果
如果有的话,你会期望使用Deprecated方法的调用检索字体,失败,或者至少两者都返回相同的结果。
实际结果:
2010-01-12 22:06:36.645 PrefTest [9659:207]单元格框架:0.000000 0.000000 2010-01-12 22:06:36.646 PrefTest [9659:207] DEPRECATED相框:88.000000 24.000000
替代方案&隔震:
如上所述,使用不推荐使用的方法来获取字体。但它变得陌生!
颠倒我上面给出的两种方法:
CGSize size2 = [cell.textLabel.text sizeWithFont:[cell font] constrainedToSize:CGSizeMake(320, 480)];
NSLog(@"DEPRECATED cell frame: %f %f", size2.width, size2.height);
CGSize size = [cell.textLabel.text sizeWithFont:[[cell textLabel] font] constrainedToSize:CGSizeMake(320, 480)];
NSLog(@"cell frame: %f %f", size.width, size.height);
结果现在是:
2010-01-12 22:06:36.645 PrefTest [9659:207]格式框架:88.000000 24.000000 2010-01-12 22:06:36.646 PrefTest [9659:207] DEPRECATED相框:88.000000 24.000000
似乎只需引用[cell font]就足以强制[[cell textLabel] font]正常工作。
答案 3 :(得分:3)
使用 [myLbl sizeToFit]; 自动调整标签大小。
以下是示例代码。
UILabel *lbl1, *lbl2;
if (cell == nil) {
UILabel *lbl1 = [[UILabel alloc] init];
[lbl1 setFont:[UIFont boldSystemFontOfSize:20]];
[cell.contentView addSubview:lbl1];
lbl1.frame = CGRectMake(3, 10, 0, 0);
lbl1.tag = 10;
[lbl1 release];
UILabel *lbl2 = [[UILabel alloc] init];
[lbl2 setFont:[UIFont systemFontOfSize:20]];
[cell.contentView addSubview:lbl2];
lbl2.tag = 20;
[lbl2 release];
}
else {
lbl1 = (UILabel*)[cell.contentView viewWithTag:10];
lbl2 = (UILabel*)[cell.contentView viewWithTag:20];
}
lbl1.text = @"Hello ";
[lbl1 sizeToFit];
lbl2.text = @"World";
[lbl2 sizeToFit];
lbl2.frame = CGRectMake(lbl1.frame.origin.x+lbl1.frame.size.width+5,
lbl1.frame.origin.y,
lbl2.frame.size.width,
lbl1.frame.size.height);