почему UITableViewAutomaticDimension не работает?

Привет есть много вопросов, отвечающих на динамическую высоту для UITableViewCell of UITableView. Однако я нахожу это странным, когда я это сделал.

вот некоторые из ответов :

здесь и здесь

обычно это отвечало бы динамической высоте для ячейки

tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension

но в моем случае я удивляюсь, что эта линия ничего не сделает.

мой UITableView просматривается после нажатия таббара внутри splitview. Заключаться в следующем полезно?

может быть, я что-то упускаю. Может кто-нибудь помочь мне, я провел 2 часа, делая глупости.

Это мое ограничение для заголовка заголовок может быть длинным, но метка-нет.

enter image description here

а это моя камера

enter image description here

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.
  • дополнительно: установите минимальную высоту для ярлыка, если вы хотите минимальную вертикальную область покрытую ярлыком, даже если нет данные.

enter image description here

Примечание: если у вас есть несколько меток (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:

выложите содержимое ячейки представления таблицы в представлении содержимого ячейки. Для определения высоты ячейки требуется непрерывная цепочка ограничений и представлений (с определенными высотами) для заполнения области между верхним и нижним краями представления содержимого.