Размер содержимого UITableView при использовании автоматической компоновки

Я хочу рассчитать размер содержимого моего UITableView. Я использую autolayout с высотой UITableViewAutomaticDimension.

Пытался получить [UITableView contentsize] после перезагрузки tableview, в этом случае высота рассчитывается на основе estimatedRowHeight.

self.tableView.estimatedRowHeight = 50;
self.tableView.rowHeight = UITableViewAutomaticDimension;

Делегат -

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return UITableViewAutomaticDimension;
}

Попытка получить размер содержимого и назначить его ограничению высоты.

[self.tableView reloadData];
[self.tableView layoutIfNeeded];
self.tableHeightConstraint.constant = self.tableView.contentSize.height;

Какие-либо предложения? Заранее спасибо.

Редактировать:

Наконец, я решил свою проблему с некоторой настройкой. Я изменил высоту таблицы до макс (в моем случае 300 макс.), Прежде чем перезагружать данные в таблице, поэтому в таблице есть пространство для изменения размера всех ячеек.

self.tableHeightConstraint.constant = 300;
[self.tableView reloadData];
[self.tableView layoutIfNeeded];
self.tableHeightConstraint.constant = self.tableView.contentSize.height;

Спасибо за помощь.

Ответы

Ответ 1

Наконец, я решил свою проблему с некоторой настройкой. Я изменил высоту таблицы до макс (в моем случае 300 макс.), Прежде чем перезагружать данные в таблице, поэтому в таблице есть пространство для изменения размера всех ячеек.

self.tableHeightConstraint.constant = 300;
[self.tableView reloadData];
[self.tableView layoutIfNeeded];
self.tableHeightConstraint.constant = self.tableView.contentSize.height;

Проводя это, это будет полезно для других.

Ответ 2

Наконец, я понял вашу проблему, и вот ее решение.

Надеюсь, вы уже это сделали.

  1. Сначала возьмите некоторую высоту исправления UITableView.
  2. Затем возьмите ограничение IBOutlet UITableView Height.
  3. Затем в режиме viewDidLayoutSubviews вы можете получить исходную высоту UITableView после viewDidLayoutSubviews данных.

Обновите приведенный ниже код:

override func viewDidLayoutSubviews() {

   constTableViewHeight.constant = tableView.contentSize.height
}

Обновить:

self.tableView.estimatedRowHeight = UITableViewAutomaticDimension;

Пожалуйста, проверьте это.

Ответ 3

Установив для параметра initialRowHeight значение нуля во время инициализации табличного представления и добавив следующий код для просмотраDidLayoutSubviews, работал для меня!

tableView.reloadData()
tableView.layoutIfNeeded()
tableView.constant = tableView.contentSize.height

Ответ 4

Вы можете попробовать две вещи,

  1. Вызов метода ниже сразу после нескольких секунд задержки после полной перезагрузки таблицыView.

    - (void)adjustHeightOfTableview
    {
      dispatch_async(dispatch_get_main_queue(), ^{
    
      [self.tableView reloadData];
    
      //In my case i had to call this method after some delay, because (i think) it will allow tableView to reload completely and then calculate the height required for itself. (This might be a workaround, but it worked for me)
      [self performSelector:@selector(adjustHeightOfTableview) withObject:nil afterDelay:0.3];
      });
    }
    
  2. Когда вы вызываете метод выше, не возвращайте validHeightForRow,

    /*
    -(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
       return 44;
    } 
    */
    
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
       return UITableViewAutomaticDimension;
    }
    

Просто попробуйте, это может помочь вам решить эту проблему.

Ответ 5

Для меня решение заключалось в том, чтобы просто установить estimatedRowHeight показатель estimatedRowHeight на значение, большее, чем все, что я счел возможным для данных, которые я должен был отображать.

По какой - то причине это обеспечить, чтобы estimatedRowHeight свойство не используется для определения contentSize. Я не показываю индикатор прокрутки, поэтому для меня не имело значения, что estimatedRowHeight значение estimatedRowHeight было далеко.

Ответ 6

Все вышеперечисленные решения не работали для моего дела. Я закончил тем, что использовал наблюдателя:

self.tableView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if let obj = object as? UITableView {
        if obj == self.tableView && keyPath == "contentSize" {
            if let newSize = change?[NSKeyValueChangeKey.newKey] as? CGSize {
                self.tableView.frame.size.height = newSize.height
            }
        }
    }
}

Ответ 7

Вы также можете подклассифицировать UITableView и вызывать кого угодно (т. layoutSubviews() Контейнерный вид) из него layoutSubviews() где у вас определенно есть правильный contentSize.

Ответ 8

для быстрого использования

tableView.invalidateIntrinsicContentSize()
tableView.layoutIfNeeded()

после reloadData() и

tableView.contentSize.height

будет работать отлично. Пример на среде

Ответ 9

В моем случае я не использую ограничение высоты tableView - при использовании автоматического макета устанавливаются ограничение сверху и снизу и изменяется только ограничение снизу при переходе в/из режима редактирования.

Ответ Tzegenos изменяется следующим образом: 1. добавьте tableView.estimatedRowHeight = 0 в viewDidLoad() 2. добавьте следующее:

override func viewDidLayoutSubviews() {

    // 60 is row height as set by tableView( cellRowAt )
    // places is of type [String] to be used by tableView
    tableView.contentSize.height = 60 * CGFloat(places.count)
}