Это на 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.





Я не думаю, что вы можете манипулировать базовым 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 к моей возвращенной высоте ячейки, потому что мне нравится небольшой буфер вокруг моего текста.
Спасибо, я отредактирую свой пост сегодня вечером, когда у меня будет возможность проверить его в моем собственном проекте.
Установка количества строк на 0 работает нормально (столько строк, сколько требуется для отображения)
когда я устанавливаю numberOfLines на 0, у меня всегда остается пустая строка в конце. Есть идеи, как я могу от этого избавиться?
Дэвид, у вас вероятно есть новая строка в конце вашей строки. Это единственная причина, которая приходит на ум.
Это прекрасно работает - спасибо! Поскольку некоторые из моих строк не являются «многострочными», я выборочно вычисляю высоту строки (и при необходимости устанавливаю numberOfLines и lineBreakMode) ... в противном случае я просто возвращаю tableView.rowHeight по умолчанию. Совет для тех, кто пробует это сделать: убедитесь, что вы НЕ ссылаетесь на ячейку табличного представления в tableView: heightForRowForIndexPath :. Как бы удобно это ни было (например, для получения шрифта для данной ячейки), это вызовет бесконечный цикл, «и ваш отладчик будет грустить».
До некоторой степени это работает для меня очень хорошо. Я могу получить только три строки после того, как мой текст усечен. Есть идеи, что могло бы вызвать это? Я использую тот же код, что и выше, за исключением использования detailTextLabel вместо textLabel
@cagreen - это, вероятно, не работает для detailTextLabel из-за переопределения макетов subview. Если вы действительно хотите продолжить в том же направлении, возможно, лучше всего будет создать пользовательскую ячейку и вручную управлять layoutSubviews.
cagreen: Оказывается, я могу воспроизвести это, но Только, если я использую iPhone OS 3.0 в симуляторе. Когда я использую 3.1+, изменение размера detailTextLabel прекрасно совпадает с размером sizeWithFont. Таким образом, метод Тима работает очень хорошо - только для версии 3.1+ (вероятно, из-за ошибки / неправильного отображения ячеек по умолчанию 3.0). Для записи я использую вертикальное верхнее / нижнее поле 12 (каждое), размер текстовой метки детали (188.0, CGFLOAT_MAX) и полужирный шрифтSystemFontOfSize 15.
Каким будет мой cellFont, если в моих ячейках будут разные шрифты и размеры? - (CGFloat) tableView: (UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath {NSString * cellText = @ "Найдите текст для своей ячейки."; UIFont * cellFont = [UIFont fontWithName: @ "Helvetica" размер: 17.0]; }
@Patricia: Это становится немного сложнее, но, по сути, вам нужно будет отслеживать, какой шрифт и размер имеет каждая ячейка в массиве или таблице, которая индексируется по номеру ячейки. Когда вы входите в эту функцию, найдите нужную информацию и примените ее, чтобы получить нужный размер ячейки.
@Patricia - Попробуйте получить свою ячейку и сослаться на cell.textLabel.font вместо использования массива используемых шрифтов. По сути, вы можете получить свою ячейку, вызвав метод UITableViewCellDelegate tableView: cellForRowAtIndexPath :. надеюсь, это поможет
Любое решение для обрезки rightDetail из-за слишком длинной левой метки? Не могу ничего придумать, устанавливая рамку левой метки или увеличивая высоту ячейки.
Отличное решение. Пробовал несколько других подобных методов, но это работает лучше всего! :)
UILineBreakModeWordWrap устарел в iOS 6. Вместо этого используйте NSLineBreakByWordWrapping.
@EthanAllen - Ничего страшного. Но не меняйте так ответ. Добавьте строку редактирования или прокомментируйте ее другим способом.
может кто-нибудь перевести это на быстрый. Я не мог правильно получить CGSize labelSize =.
@Esq - Этот, более ориентированный на Swift ответ, работает для меня: stackoverflow.com/a/25187891/2371425
Я думаю, что это лучшее и более короткое решение. Просто отформатируйте 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:.
Теперь в представлениях таблиц могут быть саморазмерные ячейки. Настройте вид таблицы следующим образом
tableView.estimatedRowHeight = 85.0 //use an appropriate estimate
tableView.rowHeight = UITableViewAutomaticDimension
Попробуйте мой код быстро. Этот код также будет работать с обычными 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
Вам не нужно устанавливать для вашего cell.textLabel.numberOfLines какое-то произвольно большое число. Установка его в 0 означает «столько строк, сколько требуется для отображения».