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


151

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

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

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

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

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

Ответы:


277

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

Внутри твоей 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 к моей возвращенной высоте ячейки, потому что мне нравится небольшой буфер вокруг моего текста.


17
Вам не нужно устанавливать для вашего cell.textLabel.numberOfLines какое-то произвольно большое число. Установка его в 0 означает «столько строк, сколько требуется для отображения».
MMC

Спасибо, я отредактирую свой пост сегодня вечером, когда у меня будет возможность проверить это в моем собственном проекте.
Тим Рупе

1
Установка количества строк в 0 работает нормально (столько строк, сколько требуется для отображения)
prakash

1
Cagreen: Оказывается, я могу повторить это, но только если я использую iPhone OS 3.0 в симуляторе. Когда я использую 3.1+, изменение размера detailTextLabel точно соответствует размеру sizeWithFont. Таким образом, метод Тима работает очень хорошо - только для 3.1+ (вероятно, из-за ошибки / неправильной настройки в рендеринге ячеек по умолчанию 3.0). Для записи я использую вертикальное верхнее / нижнее поле 12 (каждый), размер текстовой метки с подробным описанием (188.0, CGFLOAT_MAX) и boldSystemFontOfSize 15.
Джо

17
UILineBreakModeWordWrap устарела в iOS 6. Вместо этого используйте NSLineBreakByWordWrapping.
Итан Аллен

16

Обновленный ответ Тима Рупа для 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;
}

3

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

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

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


2

Если мы хотим добавить только текст в 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"];

2

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

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

Справочник Apple


0

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

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

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

0

Я нашел это довольно простым и понятным:

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

например:

[self.tableView setRowHeight:80.0f];

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


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

0

Попробуйте мой код в Swift. Этот код будет работать и для обычных 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 

-1

Я думаю, что это лучшее и более короткое решение. Просто отформатируйте 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;
}

-2

Я не думаю, что вы можете манипулировать 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];
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.