Pull-to-refresh в UICollectionViewController

Я хочу реализовать pull-down-to-refresh в UICollectionViewController под iOS 6. Этого было легко достичь с помощью UITableViewController, например:

UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(startRefresh:)
    forControlEvents:UIControlEventValueChanged];
self.refreshControl = refreshControl;

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

Поскольку UICollectionViewController является "более развитым" UITableViewController, можно было бы ожидать некоторой четности функций, но я не могу найти ссылку нигде во встроенный способ реализации этого.

  • Есть ли простой способ сделать это, что я пропускаю?
  • Может ли UIRefreshControl каким-то образом использоваться с UICollectionViewController, несмотря на заголовок и документы, заявляющие, что они предназначены для использования в представлении таблицы?

Ответ 1

Ответы на оба (1) и (2) да.

Просто добавьте экземпляр UIRefreshControl в качестве подзадачи .collectionView, и он просто работает.

UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(startRefresh:)
    forControlEvents:UIControlEventValueChanged];
[self.collectionView addSubview:refreshControl];

Что это! Хотелось бы, чтобы это упоминалось в документации где-то, хотя иногда простой эксперимент делает трюк.

EDIT: это решение не будет работать, если коллекция недостаточно велика, чтобы иметь активную полосу прокрутки. Если вы добавите это утверждение,

self.collectionView.alwaysBounceVertical = YES;

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

Ответ 2

Я искал одно и то же решение, но в Swift. Основываясь на приведенном выше ответе, я сделал следующее:

let refreshCtrl = UIRefreshControl()
    ...
refreshCtrl.addTarget(self, action: "startRefresh", forControlEvents: .ValueChanged)
collectionView?.addSubview(refreshCtrl)

Не забывайте:

refreshCtrl.endRefreshing()

Ответ 3

Я использовал Storyboard, а настройка self.collectionView.alwaysBounceVertical = YES; не работала. Выбор Bounces и Bounces Vertically выполняет эту работу для меня.

enter image description here

Ответ 4

Ответ

mjh правильный.

Я столкнулся с проблемой, где, если collectionView.contentSize не больше, чем collectionView.frame.size, вы не можете пропустить прокрутку collectionView. Вы также не можете установить свойство contentSize (по крайней мере, я не мог).

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

Мое решение заключалось в подклассе UICollectionViewFlowLayout и переопределении метода:

- (CGSize)collectionViewContentSize
{
    CGFloat height = [super collectionViewContentSize].height;

    // Always returns a contentSize larger then frame so it can scroll and UIRefreshControl will work
    if (height < self.collectionView.bounds.size.height) {
        height = self.collectionView.bounds.size.height + 1;
    }

    return CGSizeMake([super collectionViewContentSize].width, height);
}

Ответ 5

Теперь свойство refreshControl добавлено в UIScrollView с iOS 10, поэтому вы можете установить элемент управления обновлением непосредственно в представлениях коллекции.

https://developer.apple.com/reference/uikit/uiscrollview/2127691-refreshcontrol

UIRefreshControl *refreshControl = [UIRefreshControl new];
[refreshControl addTarget:self action:@selector(refreshControlAction:) forControlEvents:UIControlEventValueChanged];
self.collectionView.refreshControl = refreshControl;