Изменить высоту UITableViewCell в соответствии с количеством текста - PullRequest
55 голосов
/ 22 марта 2012

Мне нужно иметь возможность настроить высоту отдельной ячейки в моем 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;
}

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

Ответы [ 9 ]

80 голосов
/ 25 февраля 2014

Это просто, просто добавьте это к своему коду:

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

Он автоматически считает высоту строки, а затем возвращает число с плавающей точкой ...: -)

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

56 голосов
/ 22 марта 2012

Привет Джош,

Используя 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: метод.

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

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

44 голосов
/ 29 марта 2016

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

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

21 голосов
/ 22 марта 2012

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

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

Отличный способ понять, что не так с представлением с точки зрения размера, это покрасить его в отличие от фона (попробуйте установить в cell.textLabel background желтый) ипосмотрим, действительно ли установлена ​​высота.

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

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

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

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

5 голосов
/ 08 февраля 2017

Для swift Разработчики:

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

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
    }

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

Надеюсь, она будет работать.

2 голосов
/ 22 марта 2012

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

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

1 голос
/ 27 марта 2018

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

В 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;
}
0 голосов
/ 04 октября 2016
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;


}
0 голосов
/ 07 августа 2013

Я смог добиться этого, используя autolayout.Убедитесь, что ваша метка привязана к верхней и нижней части ячейки (я использую ячейку прототипа), а ее строки установлены в 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...