web-dev-qa-db-fra.com

UIRefreshControl avec UICollectionView dans iOS7

Dans mon application, j'utilise le contrôle d'actualisation avec la vue Collection.

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

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

iOS7 a un bogue méchant qui, lorsque vous réduisez la vue de la collection et ne relâchez pas votre doigt lorsque le rafraîchissement commence, la verticale contentOffset décale de 20 à 30 points, ce qui entraîne un saut de défilement déplaisant.

Les tables ont également ce problème si vous les utilisez avec le contrôle d'actualisation en dehors de UITableViewController. Mais pour eux, cela pourrait être facilement résolu en assignant votre instance UIRefreshControl à la propriété privée de UITableView appelée _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];

Mais UICollectionView n’a pas cette propriété, il doit donc y avoir un moyen de la gérer manuellement.

30
Ilya Laktyushin

Avoir le même problème et trouvé une solution de contournement qui semble résoudre le problème.

Cela semble se produire car la UIScrollView ralentit le suivi du geste panoramique lorsque vous passez au-delà du bord de la vue à défilement. Cependant, UIScrollView ne comptabilise pas les modifications apportées à contentInset pendant le suivi. UIRefreshControl change contentInset quand il s'active, et ce changement provoque le saut.

Remplacer setContentInset sur votre UICollectionView et comptabiliser ce cas semble aider:

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

Il est intéressant de noter que UITableView explique cela en NE ralentissant PAS le suivi tant que vous n’avez PAS retiré le contrôle de régénération. Cependant, je ne vois pas en quoi ce comportement est exposé.

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

 }
1
Roman Solodyashkin