2009-12-22 116 views
22

我正在構建基於UITableViewCellStyle1(或左右)的自定義應用程序內設置視圖。動態計算UITableViewCell中的UILabel寬度

我想動態地計算一個單元格的左標籤(標題)的寬度,以確定我的文本字段在右側可以有多寬。

當我在模擬器中啓動應用程序並加載視圖時,標題標籤的寬度爲零,直到我向下滾動視圖並且單元格不可見時,那麼當我滾動備份大小時會按預期進行調整。我相信這可能需要做一些細胞再利用。

我需要單元格中的標題標籤在視圖加載時具有其正確的寬度,而不是在它們一次不在視線之後。

- (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; 
    } 

回答

16

顯式設置字體可以解決您的問題。

CGSize textLabelSize = [textLabel.text sizeWithFont:[UIFont systemFontOfSize:17]]; 

蓋瑞Detals:
當的tableview第一負載,此代碼段返回零寬度由於字體大小爲0。

[textLabel.text sizeWithFont:textLabel.font] 

我這出通過顯示的點大小單元格字體。

NSLog(@"font size: %f", cell.textLabel.font.pointSize); 

點的大小爲零,直到單元退出屏幕並返回,就像您所描述的那樣。

3

我發現了同樣的問題,但我找到了解決方法。僅供參考我已經向Apple提出了一個錯誤(錯誤號7535066)。 Lex,在你的例子中,如果你使用cell.font而不是textLabel.font,它應該可以工作,雖然你會得到一個編譯器警告,因爲這是一個不贊成的方法調用。我不確定你是否能夠看到我提出的錯誤的細節,所以我在這裏粘貼細節:

iPhone SDK 3.1.2(7D11)NSString UIKit添加方法sizeWithFont返回零

內容 我在UITableView的委託方法裝飾UITableViewCells:

  • (的UITableViewCell *)的tableView:(UITableView的*)的tableView的cellForRowAtIndexPath:(NSIndexPath *)indexPath

我希望能夠找到已經在單元格中的文本的長度,要正確格式化新的看法,所以我致電的NSString UIKit的添置方法:

  • (CGSize)sizeWithFont:(UIFont *)字體constrainedToSize:(CGSize )大小

當我使用cell.textLabel.font的字體參數,它總是返回一個空CGSize

如果我使用的方法已過時,cell.font對於參數,它返回CGSize價值如預期。

重複步驟 1。創建一個帶有TableView的UITableViewController,並用一些示例數據填充它 2.在stubbed方法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); 

預期成果

如果有的話,你會認爲使用失效的方法來獲取字體的號召,失敗,或者至少兩者返回相同的結果。

實際結果:

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

替代方法& ISOLATION:

如上所述,使用已棄用的方法來獲得的字體。但它變得陌生!

逆向兩種方法我上面給出:


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 cell frame:88.000000 24.000000

看來只要引用[cell font]就足以強制[[cell textLabel] font]正常工作。

5

我完全同意,它是充分討厭它應該是一個錯誤。爲什麼蘋果公司的好人會在沒有確保電池完全安裝的情況下詢問電池的高度。愚蠢!然而,代替使用棄用功能,嘗試:

[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; 
} 
+0

它不起作用 – Dejell 2013-02-27 09:42:49

+0

想象中的想法。 [cell layoutIfNeeded];很棒!其他解決方案不起作用。非常感謝! – Vyacheslav 2014-04-09 15:36:25

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);