динамический расчет ширины UILabel в UITableViewCell

Я создаю пользовательское, представление в параметрах настройки приложения на основе 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;
   }
23
задан niton 15 April 2015 в 21:30
поделиться

2 ответа

Явная настройка шрифта решает вашу проблему.

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

Gory Detals:
Когда табличный вид впервые загружается, этот фрагмент возвращает нулевую ширину, так как размер шрифта равен 0.

[textLabel.text sizeWithFont:textLabel.font]

Я понял это, отобразив размер точки шрифта ячейки.

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

Размер точки был нулевым до тех пор, пока ячейка не сошла с экрана и не вернулась обратно, как вы и описывали.

16
ответ дан 29 November 2019 в 02:44
поделиться

Я нашел ту же самую проблему, но нашел обходной путь. К вашему сведению, я поднял вопрос об ошибке в Apple (Bug ID# 7535066). Lex, в вашем примере, если вы используете cell.font вместо textLabel.font, это должно сработать, хотя вы получите предупреждение компилятора, так как это устаревший вызов метода. Я не уверен, что вы сможете увидеть подробности проблемы, которую я поднял, поэтому вставляю подробности здесь:

iPhone SDK 3.1.2 (7D11) NSString UIKit Additions метод sizeWithFont возвращает nil

SUMMARY Я декорирую UITableViewCells в методе делегирования UITableView:

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

Я хочу найти длину текста уже в ячейке, чтобы правильно отформатировать новое представление, поэтому вызываю метод NSString UIKit Additions:

  • (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size

When I use cell. textLabel.font для аргумента шрифта, он всегда возвращает пустой CGSize

IF я использую DEPRECATED метод, cell.font для аргумента, он DOES возвращает значение CGSize, как и ожидалось.

ШАГИ ДЛЯ ВОСПРОИЗВЕДЕНИЯ 1. Создайте UITableViewController с помощью TableView и заполните его некоторыми образцами данных. 2. В методе stubbed cellForRowAtIndexPath, после комментария //Set up ячейки, и где заполняется 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);

EXPECTED RESULTS

Если что, то можно ожидать, что вызов, использующий метод 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

WORKAROUND & 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 сотовый кадр: 88.000000 24.000000

Кажется, что одной ссылки на [шрифт ячейки] достаточно, чтобы заставить [[шрифт ячейки textLabel]] работать правильно.

3
ответ дан 29 November 2019 в 02:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: