2009-12-22 23 views
22

Tôi đang xây dựng chế độ xem cài đặt tùy chỉnh, trong ứng dụng dựa trên UITableViewCellStyle1 (hoặc hơn).tính toán động của chiều rộng UILabel trong UITableViewCell

Tôi đang cố gắng tính toán chiều rộng của nhãn bên trái (tiêu đề) của một ô để xác định độ rộng trường văn bản của tôi ở bên phải có thể.

Khi tôi khởi chạy ứng dụng trong trình mô phỏng và lượt xem, chiều rộng của nhãn tiêu đề bằng 0 cho đến khi tôi cuộn xuống chế độ xem và ô không hiển thị, sau đó cuộn lại kích thước điều chỉnh như mong đợi. Tôi tin rằng điều này có thể phải làm một cái gì đó với reusage tế bào.

Tôi cần các nhãn tiêu đề trong ô để có chiều rộng chính xác khi lượt xem tải xuống, không phải sau khi chúng bị mất tầm nhìn một lần.

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

Trả lời

16

Đặt phông chữ rõ ràng giải quyết vấn đề của bạn.

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

Gory Detals:
Khi tableview tải đầu tiên, đoạn này trả về zero chiều rộng do kích thước phông chữ là 0.

[textLabel.text sizeWithFont:textLabel.font] 

tôi figured này ra bằng cách hiển thị kích thước điểm phông chữ của ô.

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

Kích thước điểm bằng không cho đến khi ô tắt màn hình và quay lại, giống như bạn đã mô tả.

3

Tôi đã tìm thấy vấn đề tương tự, nhưng tôi đã tìm thấy giải pháp thay thế. FYI Tôi đã đưa ra một lỗi với Apple (Bug ID # 7535066). Lex, trong ví dụ của bạn, nếu bạn sử dụng cell.font thay vì textLabel.font, nó sẽ làm việc, mặc dù bạn sẽ nhận được một cảnh báo trình biên dịch, vì đây là một cuộc gọi phương thức không được chấp nhận. Tôi không chắc liệu bạn có thể xem chi tiết về lỗi mà tôi nêu ra hay không, vì vậy tôi đang dán chi tiết tại đây:

SDK iPhone 3.1.2 (7D11) NSString UIKit Kích thước phương thức bổ sungWithFont trả về nil

TÓM TẮT tôi trang trí UITableViewCells trong UITableView phương pháp đại biểu:

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

Tôi muốn tìm chiều dài của văn bản đã có trong các tế bào, để định dạng một cách chính xác quan điểm mới, vì vậy tôi kêu gọi các phương pháp NSString UIKit bổ sung:

  • (CGSize) sizeWithFont: (UIFont *) phông chữ constrainedToSize: (CGSize) kích thước

Khi tôi sử dụng cell.textLabel.font cho đối số font chữ, nó luôn luôn trả về một CGSize trống

NẾU tôi sử dụng phương pháp NỮA, cell.font cho lập luận, nó KHÔNG trả lại CGSize giá trị như mong đợi.

BƯỚC ĐỂ ĐẢM BẢO 1.Tạo một UITableViewController với một TableView, và điền nó với một số dữ liệu mẫu 2. Trong phương thức stubbed cellForRowAtIndexPath, sau khi nhận xét // Thiết lập ô và nơi cell.textLabel.text được điền, hãy đặt như sau:


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

kẾT qUẢ dỰ KIẾN

Nếu bất cứ điều gì, bạn mong chờ cuộc gọi có sử dụng phương pháp Deprecated để lấy font chữ, thất bại, hoặc ít nhất là cả hai phải trả lại kết quả tương tự.

KẾT QUẢ THỰC TẾ:

2010-01-12 22: 06: 36,645 PrefTest [9659: 207] khung tế bào: 0,000000 0,000000 2010-01-12 22: 06: 36,646 PrefTest [9659: 207] KHÔNG DÙNG NỮA khung tế bào: 88.000000 24.000000

cÁCH GIẢI QUYẾT & cô lập:

Như đã đề cập, sử dụng phương pháp phản đối để có được phông chữ. Nhưng nó trở nên xa lạ!

Đảo ngược hai phương pháp tôi đã ở trên:


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

Kết quả bây giờ là:

2010-01-12 22: 06: 36,645 PrefTest [9659: 207] khung tế bào: 88,000000 24,000000 2010-01-12 22: 06: 36.646 PrefTest [9659: 207] DEPRECATED cell frame: 88.000000 24.000000

Dường như chỉ tham chiếu [cell font] là đủ để buộc [[cell textLabel] font] hoạt động chính xác.

5

Tôi hoàn toàn đồng ý rằng nó đủ gây phiền nhiễu rằng nó phải là một lỗi. Tại sao những người đẹp ở Apple lại yêu cầu chiều cao tế bào mà không đảm bảo rằng tế bào được thiết lập hoàn toàn. Ngớ ngẩn! Tuy nhiên, thay vì sử dụng một hàm phản đối, hãy thử:

[cell layoutIfNeeded]; 

gọi method này có tác dụng tương tự với các tế bào được thành lập bao gồm các giới hạn, phông chữ di động, vv Do đó, bất kỳ tính toán sau này có quyền truy cập vào thiết lập đầy đủ ô. Đây là toàn bộ mã:

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

Nó không hoạt động – Dejell

+0

Ngắm ý tưởng. [cell layoutIfNeeded]; hoạt động tuyệt vời! Các giải pháp khác không hoạt động. Cảm ơn rất nhiều! – Vyacheslav

3

Sử dụng [myLbl sizeToFit]; để tự động thay đổi kích thước nhãn.

Đây là mã mẫu.

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); 
Các vấn đề liên quan