web-dev-qa-db-ja.com

UICollectionViewControllerでのプルツーリフレッシュ

IOS 6のUICollectionViewControllerにpull-down-to-refreshを実装したい。これは、次のようにUITableViewControllerで簡単に実現できました。

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

上記は、ネイティブウィジェットの一部としてニースの液滴アニメーションを実装しています。

UICollectionViewControllerは「より進化した」UITableViewControllerであるため、機能の同等性がある程度期待されますが、これを実装する組み込み方法への参照はどこにもありません。

  1. 私が見落としているこれを行う簡単な方法はありますか?
  2. ヘッダーとドキュメントの両方がテーブルビューで使用することを意図しているにもかかわらず、UIRefreshControlUICollectionViewControllerと一緒に使用できますか?
73
mjh

(1)と(2)の両方に対する答えはイエスです。

UIRefreshControlインスタンスを.collectionViewのサブビューとして追加するだけで機能します。

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

それでおしまい!時々簡単な実験でうまくいく場合でも、ドキュメントのどこかでこれが言及されていればよかったです。

編集:コレクションがアクティブなスクロールバーを持つほど大きくない場合、このソリューションは機能しません。このステートメントを追加すると、

self.collectionView.alwaysBounceVertical = YES;

その後、すべてが完全に機能します。この修正は、同じトピックの another post から取られました(他の投稿された回答のコメントで参照されます)。

215
mjh

私は同じソリューションを探していましたが、Swiftでした。上記の回答に基づいて、次のことを行いました。

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

忘れないで:

refreshCtrl.endRefreshing()
18
djbp

Storyboardを使用していて、self.collectionView.alwaysBounceVertical = YES;の設定が機能しませんでした。 BouncesBounces Verticallyを選択すると、仕事ができます。

enter image description here

7
harinsa

IOS 10以降、refreshControlプロパティがUIScrollViewに追加され、コレクションビューで更新コントロールを直接設定できるようになりました。

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;    
4
Berry Blue

mjhの答えは正しいです。

collectionView.contentSizecollectionView.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);
}
2
Padin215