UIRefreshControl with UICollectionView in iOS7 UIRefreshControl with UICollectionView in iOS7 ios ios

UIRefreshControl with UICollectionView in iOS7

Having the same problem and found a workaround that seems to fix it.

This seems to be happening because the UIScrollView is slowing down the tracking of the pan gesture when you pull past the edge of the scrollview. However, UIScrollView is not accounting for changes to contentInset during tracking. UIRefreshControl changes contentInset when it activates, and this change is causing the jump.

Overriding setContentInset on your UICollectionView and accounting for this case seems to help:

- (void)setContentInset:(UIEdgeInsets)contentInset {  if (self.tracking) {    CGFloat diff = contentInset.top - self.contentInset.top;    CGPoint translation = [self.panGestureRecognizer translationInView:self];    translation.y -= diff * 3.0 / 2.0;    [self.panGestureRecognizer setTranslation:translation inView:self];  }  [super setContentInset:contentInset];}

Interestingly, UITableView accounts for this by NOT slowing down tracking until you pull PAST the refresh control. However, I don't see a way that this behavior is exposed.

- (void)viewDidLoad{     [super viewDidLoad];     self.refreshControl = [[UIRefreshControl alloc] init];     [self.refreshControl addTarget:self action:@selector(scrollRefresh:) forControlEvents:UIControlEventValueChanged];     [self.collection insertSubview:self.refreshControl atIndex:0];     self.refreshControl.layer.zPosition = -1;     self.collection.alwaysBounceVertical = YES; } - (void)scrollRefresh:(UIRefreshControl *)refreshControl {     self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Refresh now"];     // ... update datasource     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{        self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"Updated %@", [NSDate date]]];        [self.refreshControl endRefreshing];        [self.collection reloadData];     });  }