Как установить высоту ячейки таблицы динамически в зависимости от длины текстовой метки?
Я пытаюсь изучить Obj-C и iOS-программирование, но я все еще очень новый. Я решил попробовать и сделать простое клиентское приложение Reddit. Я пытаюсь отображать сообщения на первой странице в UITableView
, причем каждое сообщение представлено его собственной ячейкой.
В ячейке, вот как я устанавливаю заголовок:
cell.textLabel.numberOfLines = 0;
cell.textLabel.text = [[tempDictionary objectForKey:@"data"] objectForKey:@"title"];
[cell.textLabel sizeToFit];
Тем не менее, ячейка заканчивается, если текст заголовка слишком длинный. Вот изображение:
![enter image description here]()
Как я могу заставить ячейки автоматически настраивать их высоты для размещения более ярких ярлыков заголовков, не пересекая другие ячейки или текстовую метку детали?
Спасибо за помощь!
Ответы
Ответ 1
Для нового iOS 8 есть новый способ сделать это простым.
Появляется новый параметр, который вычисляет высоту вашей ячейки относительно ограничений автоматического макета. Это UITableViewAutomaticDimension
. Вы можете использовать его в методе viewWillAppear
вашего контроллера вида.
Цель C:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.tableView.estimatedRowHeight = 70.0; // for example. Set your average height
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.tableView reloadData];
}
Swift:
override func viewWillAppear(animated: Bool) {
self.tableView.estimatedRowHeight = 70 // for example. Set your average height
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.reloadData()
}
Работайте хорошо и как хотите в своем примере. Что касается меня, я добавляю вещи высоты в viewDidLoad
и оставляю в viewWillAppear
только reloadData(). Существует также полезный .
Из документации: The default value of rowHeight is UITableViewAutomaticDimension.
Я оставляю код таким, какой он есть, на данный момент, но имейте в виду, что вам не нужно устанавливать высоту строки в iOS 8 +.
Главное, что вам нужно сделать, это установить все ограничения явно, например. к ведущему, заднему, верхнему и нижнему. Сначала попробуйте, не добавляя никаких строк кода выше.
Ответ 2
Вы должны проверить ссылку на документацию для
-[UITableViewDelegate tableView:heightForRowAtIndexPath:]
По существу, вам нужно будет самостоятельно измерить текст, чтобы вернуть правильные размеры для каждой строки таблицы. Если они простые NSStrings
, которые, как они выглядят, находятся на вашем скриншоте, вы можете использовать NSString UIKit Additions для их измерения, например
-[NSString sizeWithFont:constrainedToSize:]
Если ограниченный размер может иметь бесконечную высоту, но ширину представления содержимого ячейки таблицы.
Если им присваиваются строки, в NSAttributedString UIKit есть аналогичный метод, который называется boundingRectWithSize:options:context:
Ответ 3
Бывает, что мое приложение TidBITS News делает именно то, что вы описываете. И я считаю, что это было одно из первых приложений, чтобы понять, как это сделать; по крайней мере, в то время, когда я это написал, я не знал о других приложениях, которые это сделали. Я опубликовал свой метод в своей книге "Программирование iOS 4", и с тех пор это стало обычным явлением (хотя я не говорю, что все получили его от меня, в основном есть только один разумный способ приблизиться к нему).
Вот объяснение из текущей версии моей книги:
http://www.apeth.com/iOSBook/ch21.html#_variable_row_heights
Как вы можете видеть, трюк заключается в том, чтобы заранее выработать высоты всех строк, вызывая sizeWithFont:constrainedToSize:
на ярлыке с данными, которые он будет содержать в каждой строке, и делая необходимую математику. Это связано с тем, что tableView:heightForRowAtIndexPath:
будет вызываться вперед, снова и снова, чтобы определить высоты каждой строки, прежде чем вас попросят предоставить данные.
Затем, когда вас попросят cellForRowAtIndexPath:
, вы используете полученные вами результаты заранее, чтобы выложить ячейку в пределах ранее вычисленной высоты.
Вкл Github У меня также есть загружаемый полный пример проекта, который вы можете прочитать и запустить; он показывает вам, как это сделать с ограничениями (только для iOS 6 и более поздних версий). Ищите пример ch21
с variableHeights
в его имени.
Ответ 4
В вашем методе делегата heightForRowAtIndexPath:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 2) {
Message *aMessage = [customTableViewArray objectAtIndex:indexPath.row];
if ( [aMessage.msgBody length] <= 0 )
aMessage.msgBody = @" ";
CGSize constraint = CGSizeMake(450, 40000.0f);
CGSize size = [aMessage.msgBody sizeWithFont:[UIFont fontWithName:@"Helvetica" size:14] constrainedToSize:constraint lineBreakMode:UILineBreakModeCharacterWrap];
size.height = MAX(size.height,36);
return 136+size.height;
} else if(indexPath.row > 1) {
Message *aMessage = [customTableViewArray objectAtIndex:indexPath.row];
if ( [aMessage.msgBody length] <= 0 )
aMessage.msgBody = @" ";
CGSize constraint = CGSizeMake(450, 40000.0f);
CGSize size = [aMessage.msgBody sizeWithFont:[UIFont fontWithName:@"Helvetica" size:14] constrainedToSize:constraint lineBreakMode:UILineBreakModeCharacterWrap];
size.height = MAX(size.height,36);
return 100+size.height;
} else {
return 146;
}
}
Прошу прощения, я включил только часть кода. Это все. Поэтому, если сообщение пусто, оно делает его одним размером. Затем в else, если часть инструкции, он получает размер сообщения и основывает размер ячейки на этом размере сообщения.