Изменение высоты UITableViewCell в соответствии с количеством текста

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

Я играл со следующими, но это не работает для меня:

Как обернуть текст в UITableViewCell без пользовательской ячейки

Попытка кода:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];
}

а также

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:17.0];
    CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
    CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

    return labelSize.height + 20;
}

Это не сработало, оно показывает всю строку в ячейке, однако высота ячейки не изменяется вообще.

Ответ 1

На основе кода, который вы предоставили, я думаю, что вы увеличиваете только высоту ячейки, а не высоту cell.textLabel.

В идеале вы должны установить размер ячейки cell.textLabel и ячейку, чтобы вы могли видеть полный текст в ячейке.

Непонятный способ увидеть, что не так с представлением в терминах размера, состоит в том, чтобы покрасить его по-другому, чем фон (попробуйте установить background.ablabel для желтого) и посмотрите, действительно ли установлена ​​высота.

Вот как это должно быть

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];

    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = cell.textLabel.font;
    CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
    CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
    cell.textlabel.frame.size = labelSize; 
    cell.text = cellText;
}

Надеюсь, это поможет!

update: Это довольно старый ответ, и многие строки в этом ответе могут быть устаревшими.

Ответ 2

Просто, просто добавьте это в свой код:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewAutomaticDimension;
}

Он автоматически подсчитывает высоту строки и возвращает return float...: -)

Надеюсь, это поможет!

Ответ 3

Привет, Джош,

Используя tableView:heightForRowAtIndexPath:, вы можете указать размер каждой строки во время выполнения. теперь ваша проблема в том, как получить высоту из вашей строки, есть функция в классе NSString по этому коду, ваша проблема,

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
  NSString *str = [dataSourceArray objectAtIndex:indexPath.row];
    CGSize size = [str sizeWithFont:[UIFont fontWithName:@"Helvetica" size:17] constrainedToSize:CGSizeMake(280, 999) lineBreakMode:NSLineBreakByWordWrapping];
    NSLog(@"%f",size.height);
    return size.height + 10;
}

ниже строки вы устанавливаете номер вашей метки. от линии до макс. поэтому установите его в cellForRowAtIndexPath: method.

cell.textLabel.numberOfLines = 0;

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

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

-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
   //minimum size of your cell, it should be single line of label if you are not clear min. then return UITableViewAutomaticDimension;    
   return UITableViewAutomaticDimension; 
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewAutomaticDimension;
}

вот и все. никаких вычислений не требуется. Для получения дополнительной информации проверьте этот учебник.

Ответ 4

В вашей CustomCell: не забудьте добавить ограничение сверху и снизу для вашей UILabel

Для настройки высоты UILabel в зависимости от текста просто измените строку UILabel на 0 (см. Ответ здесь)

Тогда в вашем коде просто установите только 2 строки

self.tableView.estimatedRowHeight = 80;
self.tableView.rowHeight = UITableViewAutomaticDimension;

Вот моя кастомная клетка
enter image description here Вот мои ограничения UILabel
enter image description here
Экран вы добьетесь

enter image description here

=== Предложение ===
Если в вашей ячейке есть несколько UILabels и Images (не как в моем примере), тогда:

  • Вы должны поместить все UILabels и Images в один GroupView (View)
  • Добавьте constraint top and bottom to supper view для этого GroupView (как UILabel на моем изображении)
  • Отрегулируйте высоту UILabel, как мое предложение выше
  • Отрегулируйте высоту GroupView зависимости от содержимого (все содержимое UILabels и Images)
  • И, наконец, изменить estimateRowHeight и tableView.rowHeight как код выше

Надеюсь это поможет

Ответ 5

Для разработчиков быстрых:

Пользовательская ячейка: Сначала вы можете рассчитать высоту текста, как показано ниже:

func calculateHeight(inString:String) -> CGFloat
    {
        let messageString = inString
        let attributes : [String : Any] = [NSFontAttributeName : UIFont.systemFont(ofSize: 15.0)]

        let attributedString : NSAttributedString = NSAttributedString(string: messageString, attributes: attributes)

        let rect : CGRect = attributedString.boundingRect(with: CGSize(width: 222.0, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, context: nil)

        let requredSize:CGRect = rect
        return requredSize.height
    }

Установите ширину вашей текстовой метки

Затем вызовите эту функцию:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        heightOfRow = self.calculateHeight(inString: conversations[indexPath.row].description)

        return (heightOfRow + 60.0)
}

Для Основной ячейки:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
           return UITableViewAutomaticDimension
    }

Эта функция не будет работать для настраиваемых ячеек.

Надеюсь, что это сработает.

Ответ 6

В tableView:heightForRowAtIndexPath: вы можете взять текст и использовать sizeWithFont:constrainedToSize:, чтобы получить размер текста.

Затем просто верните высоту плюс дополнительный интервал для буфера.

Ответ 7

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

В Swift 4:

func heightForText(text: String,Font: UIFont,Width: CGFloat) -> CGFloat{

    let constrainedSize = CGSize.init(width:Width, height: CGFloat(MAXFLOAT))

    let attributesDictionary = NSDictionary.init(object: Font, forKey:NSAttributedStringKey.font as NSCopying)

    let mutablestring = NSAttributedString.init(string: text, attributes: attributesDictionary as? [NSAttributedStringKey : Any])

    var requiredHeight = mutablestring.boundingRect(with:constrainedSize, options: NSStringDrawingOptions.usesFontLeading.union(NSStringDrawingOptions.usesLineFragmentOrigin), context: nil)

    if requiredHeight.size.width > Width {
        requiredHeight = CGRect.init(x: 0, y: 0, width: Width, height: requiredHeight.height)

    }
    return requiredHeight.size.height;
}

Ответ 8

Мне удалось добиться этого, используя автозапуск. Убедитесь, что метка привязана к верхней и нижней части ячейки (я использую ячейку прототипа), а ее линии установлены на 0. Затем в tableView:heightForRowAtIndexPath:sizeWithFont:constrainedToSize: вы можете установить высоту ячейки, выполнив вычисления на размер текста:

NSString *key = self.detailContent.allKeys[indexPath.row];
NSDictionary *dictionary = self.detailContent[key];
NSString *cellText = dictionary[kSMDetailTableViewCellTextKey];
UIFont *cellFont = [UIFont fontWithName:kFontKeyEmondsans size:12.0];
CGSize constraintSize = CGSizeMake(252.0f, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
return labelSize.height;// + 10;

Ответ 9

NSString *str;
NSArray* dictArr;

if (_index==0) {
    dictArr = mustangCarDetailDictArr[indexPath.section];

}

NSDictionary* dict = dictArr[indexPath.row];


if (indexPath.section ==0)
{

    str = [dict valueForKey:@"FeatureName"];
    if ([[dict valueForKey:@"FeatureDetail"] isKindOfClass:[NSString class]])
    {

        str = [dict valueForKey:@"FeatureDetail"];



    }
    else
    {
        if (dictArr.count>indexPath.row+1)
        {
            NSDictionary* dict2 = dictArr[indexPath.row+1];
            if ([[dict2 valueForKey:@"FeatureDetail"] isKindOfClass:[NSString class]])
            {


            }
        }

    }


}
CGSize size = [str sizeWithFont:[UIFont fontWithName:@"Helvetica" size:17] constrainedToSize:CGSizeMake(280, 999) lineBreakMode:NSLineBreakByWordWrapping];
NSLog(@"%f",size.height);
return size.height + 20;


}