почему UITableViewAutomaticDimension не работает?
Привет есть много вопросов, отвечающих на динамическую высоту для UITableViewCell
of UITableView
. Однако я нахожу это странным, когда я это сделал.
вот некоторые из ответов :
обычно это отвечало бы динамической высоте для ячейки
tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension
но в моем случае я удивляюсь, что эта линия ничего не сделает.
мой UITableView
просматривается после нажатия таббара внутри splitview. Заключаться в следующем полезно?
может быть, я что-то упускаю. Может кто-нибудь помочь мне, я провел 2 часа, делая глупости.
Это мое ограничение для заголовка заголовок может быть длинным, но метка-нет.
а это моя камера
12 ответов
чтобы UITableViewAutomaticDimension работал, вы должны установить все левые, правые, нижние и верхние ограничения относительно представления контейнера ячейки. В вашем случае вам нужно будет добавить недостающее нижнее пространство для ограничения superview для метки под заголовком
я добавил ограничения программно, и случайно добавил их в клетки напрямую, т. е. не на contentView
собственность. Добавление ограничений в contentView
разрешил это для меня!
также убедитесь, что строки для вашего UILabel в ячейке установлены в 0. Если он установлен в 1, он не будет расти вертикально.
для того чтобы установить автоматический размер для высоты строки & расчетной высоты строки, обеспечьте следующие шаги для того чтобы сделать, автоматический размер эффективный для плана высоты клетки/строки.
- назначить и реализовать источник данных tableview и делегировать
- присвоить
UITableViewAutomaticDimension
к rowHeight & estimatedRowHeight - реализовать методы делегата/источник данных (т. е.
heightForRowAt
и возвращает значениеUITableViewAutomaticDimension
к нему)
-
цель C:
// in ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
@property IBOutlet UITableView * table;
@end
// in ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.table.dataSource = self;
self.table.delegate = self;
self.table.rowHeight = UITableViewAutomaticDimension;
self.table.estimatedRowHeight = UITableViewAutomaticDimension;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
Свифт:
@IBOutlet weak var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Don't forget to set dataSource and delegate for table
table.dataSource = self
table.delegate = self
// Set automatic dimensions for row height
// Swift 4.2 onwards
table.rowHeight = UITableView.automaticDimension
table.estimatedRowHeight = UITableView.automaticDimension
// Swift 4.1 and below
table.rowHeight = UITableViewAutomaticDimension
table.estimatedRowHeight = UITableViewAutomaticDimension
}
// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// Swift 4.2 onwards
return UITableView.automaticDimension
// Swift 4.1 and below
return UITableViewAutomaticDimension
}
для экземпляра метки в UITableviewCell
- установить количество строк = 0 (&режим разрыва строки = усеченный хвост)
- установите все ограничения (верхний, нижний, правый левый) относительно своего контейнера superview/ cell.
- дополнительно: установите минимальную высоту для ярлыка, если вы хотите минимальную вертикальную область покрытую ярлыком, даже если нет данные.
Примечание: если у вас есть несколько меток (UIElements) с динамической длиной, которая должна быть скорректирована в соответствии с ее размером содержимого: отрегулируйте "приоритет обнимания содержимого и сопротивления сжатию" для меток, которые вы хотите развернуть/сжать с более высоким приоритетом.
у меня есть конкретный случай, и 99% решений, которые я читал, не работали. Я решил поделиться своим опытом. Надеюсь, это поможет, так как я боролся в течение нескольких часов, прежде чем исправить эту проблему.
мой сценарий:
- я использую два TableViews в одном ViewController
- я загрузка пользовательских ячеек (xib) в этих tableviews
- динамическое содержимое в ячейках состоит из двух метки
- страница использует ScrollView
чего мне нужно было достичь:
- динамическая высота TableView
- динамическая высота TableViewCells
что вам нужно будет проверить, чтобы сделать его работать гладко:
как и каждый учебник и ответ скажет вам, установите все ограничения для вашей метки / контента (сверху, снизу, ведущий & трейлинг) и установите его в ContentView (Superview). это видео-учебник будет полезно.
-
на
viewWillAppear
метод моего ViewController, я даю один из моих tableViews (tableView2
) расчетная высота строки, а затем используйтеUITableViewAutomaticDimension
как таковой (и как видно из всех учебников / ответов):override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) tableView2.estimatedRowHeight = 80 tableView2.rowHeight = UITableViewAutomaticDimension }
для меня этих предыдущих шагов было недостаточно. Мой TableView просто возьмет estimatedRowHeight и умножит его на количество ячеек. Meeeh.
поскольку я использую два разных вида таблиц, я создал выход для каждого из них,
tableView1
иtableView2
. Позволяя мне изменить их размер вviewDidLayoutSubviews
метод. Не стесняйтесь спрашивать в комментариях, как я это сделал.-
один дополнительный шаг исправил его для меня, добавив это в
viewDidAppear
способ:override func viewDidAppear(_ animated: Bool) { tableView1.reloadData() // reloading data for the first tableView serves another purpose, not exactly related to this question. tableView2.setNeedsLayout() tableView2.layoutIfNeeded() tableView2.reloadData() }
надеюсь, что кто-то поможет!
забыл убрать tableView(heightForRowAt:indexPath:)
может быть так, что, как и я, вы случайно забыл убрать шаблонный код heightForRowAt
метод.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60.0
}
начиная с iOS 11 и Xcode 9.3, большая часть приведенной выше информации неверна. руководство Apple предполагает задание
tableView.estimatedRowHeight = 85.0
tableView.rowHeight = UITableViewAutomaticDimension
WWDC 2017 сессия 245 (создание приложений с динамическим типом, около 16: 33 в видео) предлагает что-то подобное. Все это не имело для меня никакого значения.
для ячейки стиля субтитров все, что необходимо для получения ячеек представления таблицы собственного размера, - это установить количество строк (в разделе меток атрибутов инспектор) 0 для заголовка и подзаголовка. Если одна из этих меток слишком длинная, а число строк не равно 0, ячейка представления таблицы не будет изменять свой размер.
в моем случае у меня было два UITableViews, мне пришлось изменить этот метод как
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
CGFloat height = 0.0;
if (tableView == self.tableviewComments) {
return UITableViewAutomaticDimension;
}else if (tableView == self.tableViewFriends) {
height = 44.0;
}
return height;
}
попробуйте это, простое решение это работа для меня,
в viewDidLoad напишите этот код,
-(void)viewDidLoad
{
[super viewDidLoad];
self.tableView.estimatedRowHeight = 100.0; // for example. Set your average height
self.tableView.rowHeight = UITableViewAutomaticDimension;
}
в cellForRowAtIndexPath напишите этот код,
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
}
cell.textLabel.numberOfLines = 0; // Set label number of line to 0
cell.textLabel.text=[[self.arForTable objectAtIndex:indexPath.row] valueForKey:@"menu"];
[cell.textLabel sizeToFit]; //set size to fit
return cell;
}
для того, чтобы UITableViewAutomaticDimension работал, вам нужно убедиться, что все ограничения 4 углов добавлены в superview. В большинстве случаев он хорошо работает с UILabel, но иногда я нахожу, что UITextView делает трюк, когда UILabel не работает хорошо в то время. Поэтому попробуйте переключиться на UITextView и убедитесь, что Scrolling Enabled
не установлен в раскадровке, или вы также можете установить его программно.
У меня было три горизонтальных элемента, и самый левый имел ограничение влево, средний имел верхний, нижний, левый элемент и правый элемент. У правой была правая, а у левой-средняя. Решение состояло в том, чтобы добавить дополнительные ограничения влево и вправо к среднему элементу (моя метка), которые были >= некоторое число в ячейку.
убедитесь, что все представления в ячейке ограничены представлением содержимого, а не ячейкой.
Как говорит apple:
выложите содержимое ячейки представления таблицы в представлении содержимого ячейки. Для определения высоты ячейки требуется непрерывная цепочка ограничений и представлений (с определенными высотами) для заполнения области между верхним и нижним краями представления содержимого.