UITableView: запустить код при отображении tableFooterView?

Я использую UIView tableFooterView в своем UITableView, чтобы показать ярлык "Загрузка большего" в нижней части таблицы. Когда отображается UIView в tableFooterView, мне нужно запустить некоторую ленивую загрузку контента. Как узнать, когда отображается TableFooterView?

Ответ 1

Вместо того, чтобы определять, когда нижний колонтитул покажет вам, может проверить, когда запрашивается последняя строка таблицы, и затем загружать данные. Число пользователей, прокручивающихся до последней строки без прокрутки вниз, чтобы увидеть нижний колонтитул, вероятно, очень мало. Эффект будет таким же, т.е. Вы знаете, когда пользователь прокручивается донизу, и вы должны загружать больше данных.

Это может быть легко реализовано в tableView:cellForRowAtIndexPath:. Следя за тем, что IndexPath является последним, и обновляя его каждый раз, когда новые строки добавляются или удаляются, вы можете просто проверить, является ли IndexPath запрашиваемой ячейки такой же, как IndexPath последней строки, и запускает ленивую загрузку больше данных оттуда, так же, как вы это делаете сейчас.

Ответ 2

Вы можете преобразовать нижний колонтитул в координаты окна и сравнить их. Когда нижний колонтитул скрыт, он предполагает, что он имеет координаты Y начала координат > 480 (для портретного режима), когда нижний колонтитул будет отображаться, тогда координаты координат Y < 480. Вы можете сделать сравнение в методе didScroll.

Спасибо, надеюсь, это поможет вам.

См. метод convertRect: toView:

Ответ 3

Поскольку tableFooter, как вы говорите, UIView, он обрабатывает чертеж в drawRect:. Если вы перезапишете, вы можете получить уведомление.

Изменить: старый ответ был неправильным.

Ответ 4

Если ваш tableFooterView отслеживает изменения в свойстве table contentOffset (и, возможно, также изменениях в свойстве таблицы contentSize), вы можете точно вычислить его, когда он прокручивается в представлении со следующими переменными:

  • tableView.contentOffset.y - вертикальная сумма, по которой начало представления содержимого смещается от начала прокрутки.
  • tableView.contentSize.height - высота представления содержимого
  • tableView.bounds.size.height - высота таблицы ограничена

Если смещение вертикального содержимого + высота таблицы превышает высоту размера таблицы, мы можем предположить, что нижний колонтитул теперь находится в поле зрения.

Вы можете обернуть это в оператор if и использовать его для отправки уведомления. Затем вы можете продолжить тестирование, чтобы нижний колонтитул динамически растягивал или другие предполагаемые эффекты:

if((tableView.contentOffset.y + tableView.bounds.size.height) > tableView.contentSize.height){
    //send notification, dynamic resizing, etc...` 
}

Вот несколько фрагментов кода в действии:

// Set up an observer for changes in the table contentOffset or contentSize.
// This can be done during initialisation of the tableFooterView
[tableView addObserver:self 
            forKeyPath:@"contentOffset" 
               options:NSKeyValueObservingOptionNew
               context:NULL];
[tableView addObserver:self 
            forKeyPath:@"contentSize"
               options:NSKeyValueObservingOptionNew
               context:NULL];

// Further down in code, listen for the changes:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
  change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:@"contentOffset"] || 
        [keyPath isEqualToString:@"contentSize"]) {

        if((tableView.contentOffset.y + tableView.bounds.size.height) > tableView.contentSize.height){
            // the tableFooterView should now be in view
            [[NSNotificationCenter defaultCenter] 
                postNotificationName:@"scrollToLoadNeedsLoad"
                              object:self];
            // dynamically change the footer here (ideal for making it stretch with the table)
        }

    }
}

Вы можете реализовать это внутри контроллера представления, который содержит ссылку на таблицу, или вы можете инкапсулировать его внутри своего собственного ScrollToLoadView.