Динамическая высота/ширина UILabel в UITableViewCell во всех ориентациях

Мой вопрос по существу сводится к лучшему способу поддержки динамической высоты UILabel (, и я полагаю, что другие элементы )в UITableCell , а также правильно изменяют размер ширины/высоты метки и ячейки высоты при вращении .

Я знаю, как получить ожидаемую высоту UILabels и соответственно изменить размер высоты, но все становится довольно сложно, когда вы также поддерживаете альбомную ориентацию.

Я думаю, что это может пойти по пути layoutSubviews , но я не уверен, как вы могли бы объединить это с таблицей, требующей вычисления высоты ячеек. В другом интересном посте фрейм устанавливается вручную при инициализации, чтобы убедиться, что они выполняют расчеты по известной величине, но это решает только часть проблемы.

Итак, вот изображение того, с чем я имею дело, с красными стрелками, указывающими на метки динамической высоты, и синими стрелками, указывающими на ячейки, высота которых будет изменяться.

Dynamic UILabel/Cell Height/Width

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

Вот несколько вещей, которые я узнал:

  • Cell.frame в cellForRowAtIndexPathвсегда указывает свой размер в портретном режиме. (т.е. для приложения iphone оно всегда сообщает 320 ).
  • Сохранение ячейки-прототипа для ссылки в свойстве имеет ту же проблему, всегда в портретном режиме
  • . маски автоматического изменения ширины меток в этом случае кажутся бесполезными и на самом деле вызывают проблемы с вычислением высоты при вращении
  • tableView.frame в cellForRowAtIndexPathдает свой размер в правильной ориентации
  • Вам нужно позвонить [tableView reloadData]по очереди.Я не смог найти другого способа обновить высоту ячеек и меток

Вот шаги, которые я предпринял, чтобы заставить это работать на меня:

  1. Отключите любые маски автоматического изменения размера для UILabels, так как они по какой-то причине мешают получить правильную высоту метки
  2. . В viewDidLoadя беру ссылку на каждый шрифт метки и число с плавающей запятой для процента ширины метки по сравнению с tableView в портретной ориентации

    CWProductDetailDescriptionCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"DescriptionCell"];
    self.descriptionLabelWidthPercentage = cell.descriptionLabel.frame.size.width / 320;
    self.descriptionLabelFont = cell.descriptionLabel.font;
    
  3. . В heightForRowAtIndexPathя рассчитываю высоту ячейки, используя ширину tableView и процент, который я уже захватил:

    case TableSectionDescription:
        CGFloat labelWidth = self.tableView.frame.size.width * self.descriptionLabelWidthPercentage;
        CGSize newLabelFrameSize = [self sizeForString:self.product.descriptionText WithConstraint:CGSizeMake(labelWidth, MAXFLOAT) AndFont:self.descriptionLabelFont];
        return newLabelFrameSize.height + kTextCellPadding;
    
  4. В cellForRowAtIndexPathя вычисляю кадр для кадра метки и обновляю его

    cell = [tableView dequeueReusableCellWithIdentifier:@"DescriptionCell"];
    ((CWProductDetailDescriptionCell *)cell).descriptionLabel.text = self.product.descriptionText;
    CGRect oldFrame = ((CWProductDetailDescriptionCell *)cell).descriptionLabel.frame;
    CGFloat labelWidth = self.tableView.frame.size.width * self.descriptionLabelWidthPercentage;
    CGSize newLabelFrameSize = [self sizeForString:self.product.descriptionText WithConstraint:CGSizeMake(labelWidth, MAXFLOAT) AndFont:((CWProductDetailDescriptionCell *)cell).descriptionLabel.font];
    ((CWProductDetailDescriptionCell *)cell).descriptionLabel.frame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, labelWidth, newLabelFrameSize.height);
    
  5. В didRotateFromInterfaceOrientationнужно[self.tableView reloadData]

Проблемы с этим методом:

  1. Вы не можете использовать маски автоматического изменения размера и поля, которые вы могли бы установить в IB
    • . они, кажется, не срабатывают до тех пор, пока вы не вернете ячейку вcellForRowAtIndexPath(не уверен, что это точно так)
    • они каким-то образом искажают вычисление высоты, и ваши метки оказываются выше , чем желаемое в альбомной ориентации.
  2. Если ширина вашей этикетки не равна в процентах в книжной и альбомной , вам необходимо знать оба процента
  3. . Вам нужно знать/рассчитать процент ширины этикетки. В идеале вы могли бы вычислить их на лету после того, как маска автоматического изменения размера -сделала свое дело.
  4. Это просто кажется неуклюжим. У меня такое чувство, что в режиме редактирования с отступами у меня будет больше головной боли.

Так. Как правильно это сделать? Я видел много вопросов SO, но ни один из них не касается этого точно.

15
задан Community 23 May 2017 в 10:29
поделиться