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

Это на iPhone 0S 2.0. Ответы на 2.1 тоже хороши, хотя я не знаю каких-либо различий в отношении таблиц.

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

Я понял, что метка создается по запросу (поскольку ячейка поддерживает доступ к тексту и изображениям, поэтому она не создает представление данных до тех пор, пока это необходимо), поэтому, если я сделаю что-то вроде этого:

cell.text = @""; // create the label
UILabel* label = (UILabel*)[[cell.contentView subviews] objectAtIndex:0];

тогда я получаю действительную метку, но установка numberOfLines на ней (и lineBreakMode) не работает - я все равно получаю однострочный текст. В UILabel достаточно высоты для отображения текста - я просто возвращаю большое значение высоты в heightForRowAtIndexPath.


person Airsource Ltd    schedule 24.09.2008    source источник


Ответы (10)


Вот более простой способ, и он мне подходит:

Внутри вашей cellForRowAtIndexPath: функции. В первый раз, когда вы создаете свою ячейку:

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

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

Следующая часть - указать, насколько большим будет ваш UITableViewCell, поэтому сделайте это в своей функции heightForRowAtIndexPath:

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

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

person Tim Rupe    schedule 25.05.2009
comment
Вам не нужно устанавливать для вашего cell.textLabel.numberOfLines какое-то произвольно большое число. Установка этого параметра в 0 означает, что для отображения требуется столько строк. - person mmc; 07.06.2009
comment
Спасибо, я отредактирую свой пост сегодня вечером, когда у меня будет возможность проверить его в моем собственном проекте. - person Tim Rupe; 08.06.2009
comment
Установка количества строк на 0 работает нормально (столько строк, сколько требуется для отображения) - person prakash; 17.06.2009
comment
когда я устанавливаю numberOfLines на 0, у меня всегда остается пустая строка в конце. Есть идеи, как я могу от этого избавиться? - person dlinsin; 17.01.2010
comment
Дэвид, у вас вероятно есть новая строка в конце вашей строки. Это единственная причина, которая приходит на ум. - person Tim Rupe; 18.01.2010
comment
Это прекрасно работает - спасибо! Поскольку некоторые из моих строк не являются многострочными, я выборочно вычисляю высоту строки (и при необходимости устанавливаю numberOfLines и lineBreakMode) ... в противном случае я просто возвращаю tableView.rowHeight по умолчанию. Совет для тех, кто пробует это сделать: убедитесь, что вы НЕ ссылаетесь на ячейку табличного представления в tableView: heightForRowForIndexPath :. Как бы удобно это ни было (например, для получения шрифта для данной ячейки), это вызовет бесконечный цикл, и ваш отладчик будет грустным. - person Joe D'Andrea; 11.05.2010
comment
До некоторой степени это работает для меня очень хорошо. Я могу получить только три строки после того, как мой текст усечен. Есть идеи, что могло бы вызвать это? Я использую тот же код, что и выше, за исключением использования detailTextLabel вместо textLabel - person cagreen; 12.05.2010
comment
@cagreen - это, вероятно, не работает для detailTextLabel из-за переопределения макетов subview. Если вы действительно хотите продолжить в том же направлении, возможно, лучше всего будет создать пользовательскую ячейку и вручную управлять layoutSubviews. - person Tim Rupe; 13.05.2010
comment
cagreen: Оказывается, я могу воспроизвести это, но только, если я использую iPhone OS 3.0 в симуляторе. Когда я использую 3.1+, изменение размера detailTextLabel прекрасно совпадает с размером sizeWithFont. Таким образом, метод Тима работает очень хорошо - только для версии 3.1+ (вероятно, из-за ошибки / неправильной работы в рендеринге ячеек по умолчанию 3.0). Для записи я использую вертикальное верхнее / нижнее поле 12 (каждое), размер текстовой метки детали (188.0, CGFLOAT_MAX) и полужирный шрифтSystemFontOfSize 15. - person Joe D'Andrea; 13.05.2010
comment
Каким будет мой CellFont, если в моих ячейках будут разные шрифты и размеры? - (CGFloat) tableView: (UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath {NSString * cellText = @Go получить текст для вашей ячейки .; UIFont * cellFont = [UIFont fontWithName: @Helvetica size: 17.0]; } - person Patricia; 28.10.2010
comment
@Patricia: Это становится немного сложнее, но по сути вам нужно будет отслеживать, какой шрифт и размер имеет каждая ячейка в массиве или таблице, которая индексируется по номеру ячейки. При входе в эту функцию найдите нужную информацию и примените ее, чтобы получить нужный размер ячейки. - person Tim Rupe; 28.10.2010
comment
@Patricia - Попробуйте получить свою ячейку и сослаться на cell.textLabel.font вместо использования массива используемых шрифтов. По сути, вы можете получить свою ячейку, вызвав метод UITableViewCellDelegate tableView: cellForRowAtIndexPath :. надеюсь, это поможет - person Shiun; 23.05.2012
comment
Любое решение для обрезки rightDetail из-за слишком длинной левой метки? Не могу ничего придумать, устанавливая рамку левой метки или увеличивая высоту ячейки. - person Matej; 17.08.2012
comment
Отличное решение. Пробовал несколько других подобных методов, но это работает лучше всего! :) - person Johan Karlsson; 12.12.2012
comment
UILineBreakModeWordWrap устарел в iOS 6. Вместо этого используйте NSLineBreakByWordWrapping. - person Ethan Allen; 20.01.2013
comment
@EthanAllen - Ничего страшного. Но не меняйте так ответ. Добавьте строку редактирования или прокомментируйте ее другим способом. - person Lee Taylor; 20.01.2013
comment
может кто-нибудь перевести это на быстрый. Я не мог правильно получить CGSize labelSize =. - person Esqarrouth; 21.12.2014
comment
@Esq - Этот ответ, более ориентированный на Swift, работает для меня: stackoverflow.com/a/25187891/2371425 - person Sakiboy; 29.06.2015

Обновленный ответ Тима Рупа для iOS7:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
    cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
    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];

    NSAttributedString *attributedText =
        [[NSAttributedString alloc]
            initWithString:cellText
            attributes:@
            {
                NSFontAttributeName: cellFont
            }];
    CGRect rect = [attributedText boundingRectWithSize:CGSizeMake(tableView.bounds.size.width, CGFLOAT_MAX)
                                               options:NSStringDrawingUsesLineFragmentOrigin
                                               context:nil];
    return rect.size.height + 20;
}
person ddiego    schedule 06.03.2014

Краткий комментарий / ответ, чтобы записать мой опыт, когда у меня была такая же проблема. Несмотря на использование примеров кода, высота ячейки табличного представления изменялась, но метка внутри ячейки все еще не настраивалась правильно - решение заключалось в том, что я загружал свою ячейку из пользовательского файла NIB, что происходит после высота ячейки отрегулирована.

И у меня были свои настройки внутри файла NIB, чтобы не переносить текст и иметь только одну строку для метки; настройки файла NIB переопределяли настройки, которые я установил в коде.

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

person Richard Le Mesurier    schedule 14.02.2011

Если мы должны добавить только текст в ячейку UITableView, нам понадобится только два делегата для работы (не нужно добавлять дополнительные UILabels)

1) cellForRowAtIndexPath

2) heightForRowAtIndexPath

Это решение сработало для меня: -

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;

    [cell setSelectionStyle:UITableViewCellSelectionStyleGray]; 
    cell.textLabel.text = [mutArr objectAtIndex:indexPath.section];
    NSLog(@"%@",cell.textLabel.text);

    cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrow.png" ]];

    return cell;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{  
    CGSize labelSize = CGSizeMake(200.0, 20.0);

    NSString *strTemp = [mutArr objectAtIndex:indexPath.section];

    if ([strTemp length] > 0)
        labelSize = [strTemp sizeWithFont: [UIFont boldSystemFontOfSize: 14.0] constrainedToSize: CGSizeMake(labelSize.width, 1000) lineBreakMode: UILineBreakModeWordWrap];

    return (labelSize.height + 10);
}

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

РЕДАКТИРОВАТЬ: - Вот массив, который я взял.

mutArr= [[NSMutableArray alloc] init];

[mutArr addObject:@"HEMAN"];
[mutArr addObject:@"SUPERMAN"];
[mutArr addObject:@"Is SUPERMAN powerful than HEMAN"];
[mutArr addObject:@"Well, if HEMAN is weaker than SUPERMAN, both are friends and we will never get to know who is more powerful than whom because they will never have a fight among them"];
[mutArr addObject:@"Where are BATMAN and SPIDERMAN"];
person Arshad Parwez    schedule 17.04.2012

Теперь в представлениях таблиц могут быть саморазмерные ячейки. Настройте вид таблицы следующим образом

tableView.estimatedRowHeight = 85.0 //use an appropriate estimate tableView.rowHeight = UITableViewAutomaticDimension

Справочник Apple

person Jason    schedule 12.10.2016

Я использую следующие решения.

Данные предоставляются отдельно в члене:

-(NSString *)getHeaderData:(int)theSection {
    ...
    return rowText;
}

Обработка может быть легко выполнена в cellForRowAtIndexPath. Определите ячейку / определите шрифт и присвойте эти значения «ячейке» результата. Обратите внимание, что numberoflines установлен на «0», что означает, что нужно брать то, что нужно.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    UIFont *cellFont = [UIFont fontWithName:@"Verdana" size:12.0];
    cell.textLabel.text= [self getRowData:indexPath.section];
    cell.textLabel.font = cellFont;
    cell.textLabel.numberOfLines=0;
    return cell;
}

В heightForRowAtIndexPath я вычисляю высоту обернутого текста. Размер кодирования должен соответствовать ширине вашей ячейки. Для iPad это должно быть 1024. Для iPhone и iPod 320.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIFont *cellFont = [UIFont fontWithName:@"Verdana" size:12.0];
    CGSize boundingSize = CGSizeMake(1024, CGFLOAT_MAX);
    CGSize requiredSize = [[self getRowData:indexPath.section] sizeWithFont:cellFont constrainedToSize:boundingSize lineBreakMode:UILineBreakModeWordWrap];
    return requiredSize.height;    
}
person Vincent    schedule 21.06.2012

Я обнаружил, что это довольно просто и понятно.

[self.tableView setRowHeight:whatEvereight.0f];

например, для :

[self.tableView setRowHeight:80.0f];

Это может быть, а может и не быть лучшим / стандартным подходом, но в моем случае он сработал.

person Manish Kr. Shukla    schedule 24.03.2015
comment
Насколько я понимаю, свойство rowHeight устанавливает фиксированную высоту, которая будет использоваться для всех ячеек в табличном представлении. Использование rowHeight лучше для производительности в больших таблицах, но если вам нужно, чтобы высота каждой ячейки варьировалась в зависимости от ее содержимого, кажется, что следует использовать метод tableView: heightForRowAtIndexPath:. - person jk7; 23.12.2015

Попробуйте мой код быстро. Этот код также будет работать с обычными UILabels.

extension UILabel {
    func lblFunction() {
        //You can pass here all UILabel properties like Font, colour etc....
        numberOfLines = 0
        lineBreakMode = .byWordWrapping//If you want word wraping
        lineBreakMode = .byCharWrapping//If you want character wraping
    }
}

Теперь звоните просто так

cell.textLabel.lblFunction()//Replace your label name 
person iOS    schedule 08.01.2019

Я думаю, что это лучшее и более короткое решение. Просто отформатируйте UILabel (textLabel) ячейки для автоматического расчета высоты, указав sizeToFit, и все должно быть в порядке.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    cell.textLabel.text = @"Whatever text you want to put here is ok";
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    [cell.textLabel sizeToFit];

    return cell;
}
person dukz    schedule 16.06.2010

Я не думаю, что вы можете манипулировать базовым UITableViewCell's частным UILabel, чтобы сделать это. Вы можете сами добавить новый UILabel в ячейку и использовать numberOfLines с sizeToFit, чтобы установить соответствующий размер. Что-то типа:

UILabel* label = [[UILabel alloc] initWithFrame:cell.frame];
label.numberOfLines = <...an appriate number of lines...>
label.text = <...your text...>
[label sizeToFit];
[cell addSubview:label];
[label release];
person drewh    schedule 24.09.2008