I want to implement pull-down-to-refresh in a UICollectionViewController
under iOS 6. This was easy to achieve with a UITableViewController
, like so:
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(startRefresh:)
forControlEvents:UIControlEventValueChanged];
self.refreshControl = refreshControl;
The above implements a nice liquid-drop animation as part of a native widget.
As UICollectionViewController
is a "more evolved" UITableViewController
one would expect somewhat of a parity of features, but I can't find a reference anywhere to a built-in way to implement this.
- Is there a simple way to do this that I'm overlooking?
- Can
UIRefreshControl
be used somehow withUICollectionViewController
despite the header and docs both stating that it's meant to be used with a table view?
The answers to both (1) and (2) are yes.
Simply add a UIRefreshControl
instance as a subview of .collectionView
and it just works.
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(startRefresh:)
forControlEvents:UIControlEventValueChanged];
[self.collectionView addSubview:refreshControl];
That's it! I wish this had been mentioned in the documentation somewhere, even though sometimes a simple experiment does the trick.
EDIT: this solution won't work if the collection is not big enough to have an active scrollbar. If you add this statement,
self.collectionView.alwaysBounceVertical = YES;
then everything works perfectly. This fix taken from another post on the same topic (referenced in a comment in the other posted answer).
I was looking for the same solution, but in Swift. Based on the above answer, I have done the following:
let refreshCtrl = UIRefreshControl()
...
refreshCtrl.addTarget(self, action: "startRefresh", forControlEvents: .ValueChanged)
collectionView?.addSubview(refreshCtrl)
Not forgetting to:
refreshCtrl.endRefreshing()
I was using Storyboard and setting self.collectionView.alwaysBounceVertical = YES;
did not work. Selecting the Bounces
and Bounces Vertically
does the job for me.
The refreshControl
property has now been added to UIScrollView
as of iOS 10 so you can set the refresh control directly on collection views.
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;
mjh's answer is correct.
I ran into the issue where if the the collectionView.contentSize
was not larger then the collectionView.frame.size
, you can not get the collectionView
to scroll. You can not set the contentSize
property either (at least I couldn't).
If it can't scroll, it won't let you do the pull to refresh.
My solution was to subclass UICollectionViewFlowLayout
and overide the method:
- (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);
}
来源:https://stackoverflow.com/questions/13085662/pull-to-refresh-in-uicollectionviewcontroller