31

在我的应用程序中,我使用带有集合视图的刷新控件。

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

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

iOS7 有一些令人讨厌的错误,当您将集合视图拉下并且在刷新开始时不松开手指时,垂直contentOffset向下移动 20-30 点会导致难看的滚动跳跃。

如果您在UITableViewController. UIRefreshControl但对他们来说,通过将您的实例分配给UITableView名为的私有财产可以轻松解决_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];

但是UICollectionView没有这样的属性,所以必须有一些方法来手动处理它。

4

2 回答 2

52

遇到同样的问题,并找到了似乎可以解决它的解决方法。

这似乎正在发生,因为UIScrollView当您拉过滚动视图的边缘时,它会减慢平移手势的跟踪。但是,UIScrollView不考虑在跟踪期间对 contentInset 的更改。UIRefreshControl激活时更改 contentInset ,并且此更改导致跳转。

覆盖setContentInsetUICollectionView并考虑这种情况似乎有帮助:

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

有趣的是,UITableView在您拉过刷新控件之前不要减慢跟踪速度来解决这个问题。但是,我看不到这种行为暴露的方式。

于 2013-11-12T10:40:35.057 回答
1
- (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];
     }); 

 }
于 2017-03-19T16:08:33.127 回答