UIRefreshControl with UICollectionView in iOS7

匆匆过客 提交于 2019-12-17 10:19:18

问题


In my application I use refresh control with collection view.

UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds];
collectionView.alwaysBounceVertical = YES;
...
[self.view addSubview:collectionView];

UIRefreshControl *refreshControl = [UIRefreshControl new];
[collectionView addSubview:refreshControl];

iOS7 has some nasty bug that when you pull collection view down and don't release your finger when refreshing begins, vertical contentOffset shifts for 20-30 points down which results in ugly scroll jump.

Tables have this problem too if you use them with refresh control outside of UITableViewController. But for them it could be easily solved by assigning your UIRefreshControl instance to UITableView's private property called _refreshControl:

@interface UITableView ()
- (void)_setRefreshControl:(UIRefreshControl *)refreshControl;
@end

...

UITableView *tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds];
[self.view addSubview:tableView];

UIRefreshControl *refreshControl = [UIRefreshControl new];
[tableView addSubview:refreshControl];
[tableView _setRefreshControl:refreshControl];

But UICollectionView does not have such property so there must be some way to deal with it manually.


回答1:


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.




回答2:


- (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];
     }); 

 }


来源:https://stackoverflow.com/questions/19483511/uirefreshcontrol-with-uicollectionview-in-ios7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!