在UITableViewCell中动态计算UILabel宽度

Leo*_*ard 23 iphone dynamic uitableview uilabel

我正在构建一个基于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;
   }
Run Code Online (Sandbox Code Playgroud)

ben*_*ord 16

明确设置字体可以解决您的问题.

CGSize textLabelSize = [textLabel.text sizeWithFont:[UIFont systemFontOfSize:17]];
Run Code Online (Sandbox Code Playgroud)

Gory Detals:
当tableview首次加载时,由于字体大小为0,此片段返回零宽度.

[textLabel.text sizeWithFont:textLabel.font]
Run Code Online (Sandbox Code Playgroud)

我通过显示单元格字体的磅值来解决这个问题.

NSLog(@"font size: %f", cell.textLabel.font.pointSize);
Run Code Online (Sandbox Code Playgroud)

点大小为零,直到细胞离开屏幕然后回来,就像你描述的那样.


Spa*_*ime 5

我完全同意它应该是一个bug是非常烦人的.为什么Apple的优秀人员会在不确保电池完全安装的情况下询问电池高度.愚蠢!但是,不要使用已弃用的函数,请尝试:

[cell layoutIfNeeded];
Run Code Online (Sandbox Code Playgroud)

调用此方法与设置的单元格具有相同的效果,包括边界,单元格字体等.因此,此后的任何计算都可以访问完全设置的单元格.这是整个代码:

-(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;
}
Run Code Online (Sandbox Code Playgroud)