Как обернуть текст в 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.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
151
0
98 578
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Я не думаю, что вы можете манипулировать базовым 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];
Ответ принят как подходящий

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

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

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

mmc 07.06.2009 19:07

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

Tim Rupe 08.06.2009 19:58

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

prakash 17.06.2009 08:57

когда я устанавливаю numberOfLines на 0, у меня всегда остается пустая строка в конце. Есть идеи, как я могу от этого избавиться?

dlinsin 17.01.2010 14:14

Дэвид, у вас вероятно есть новая строка в конце вашей строки. Это единственная причина, которая приходит на ум.

Tim Rupe 18.01.2010 20:58

Это прекрасно работает - спасибо! Поскольку некоторые из моих строк не являются «многострочными», я выборочно вычисляю высоту строки (и при необходимости устанавливаю numberOfLines и lineBreakMode) ... в противном случае я просто возвращаю tableView.rowHeight по умолчанию. Совет для тех, кто пробует это сделать: убедитесь, что вы НЕ ссылаетесь на ячейку табличного представления в tableView: heightForRowForIndexPath :. Как бы удобно это ни было (например, для получения шрифта для данной ячейки), это вызовет бесконечный цикл, «и ваш отладчик будет грустить».

Joe D'Andrea 11.05.2010 04:25

До некоторой степени это работает для меня очень хорошо. Я могу получить только три строки после того, как мой текст усечен. Есть идеи, что могло бы вызвать это? Я использую тот же код, что и выше, за исключением использования detailTextLabel вместо textLabel

cagreen 12.05.2010 22:26

@cagreen - это, вероятно, не работает для detailTextLabel из-за переопределения макетов subview. Если вы действительно хотите продолжить в том же направлении, возможно, лучше всего будет создать пользовательскую ячейку и вручную управлять layoutSubviews.

Tim Rupe 13.05.2010 01:34

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

Joe D'Andrea 13.05.2010 01:34

Каким будет мой cellFont, если в моих ячейках будут разные шрифты и размеры? - (CGFloat) tableView: (UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath {NSString * cellText = @ "Найдите текст для своей ячейки."; UIFont * cellFont = [UIFont fontWithName: @ "Helvetica" размер: 17.0]; }

Patricia 28.10.2010 00:46

@Patricia: Это становится немного сложнее, но, по сути, вам нужно будет отслеживать, какой шрифт и размер имеет каждая ячейка в массиве или таблице, которая индексируется по номеру ячейки. Когда вы входите в эту функцию, найдите нужную информацию и примените ее, чтобы получить нужный размер ячейки.

Tim Rupe 28.10.2010 02:54

@Patricia - Попробуйте получить свою ячейку и сослаться на cell.textLabel.font вместо использования массива используемых шрифтов. По сути, вы можете получить свою ячейку, вызвав метод UITableViewCellDelegate tableView: cellForRowAtIndexPath :. надеюсь, это поможет

Shiun 23.05.2012 20:25

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

Matej 17.08.2012 04:54

Отличное решение. Пробовал несколько других подобных методов, но это работает лучше всего! :)

Johan Karlsson 12.12.2012 11:37

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

Ethan Allen 20.01.2013 02:07

@EthanAllen - Ничего страшного. Но не меняйте так ответ. Добавьте строку редактирования или прокомментируйте ее другим способом.

Lee Taylor 20.01.2013 02:18

может кто-нибудь перевести это на быстрый. Я не мог правильно получить CGSize labelSize =.

Esqarrouth 21.12.2014 20:23

@Esq - Этот, более ориентированный на Swift ответ, работает для меня: stackoverflow.com/a/25187891/2371425

Sakiboy 29.06.2015 01:13

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

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

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

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

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

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

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

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

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

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

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

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

[self.tableView setRowHeight:80.0f];

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

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

jk7 23.12.2015 20:08

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

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

Ссылка на Apple

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

Другие вопросы по теме