UIRefreshControl con UICollectionView en iOS7
uirefreshcontrol swift 4 (2)
Tener el mismo problema y encontrar una solución alternativa que parece solucionarlo.
Esto parece estar sucediendo porque UIScrollView
está ralentizando el seguimiento del gesto de panorámica cuando se pasa del borde de la vista de desplazamiento. Sin embargo, UIScrollView
no tiene en cuenta los cambios en contentInset durante el seguimiento. UIRefreshControl
cambia contentInset cuando se activa, y este cambio está causando el salto.
setContentInset
en su UICollectionView
y la contabilidad de este caso parece ayudar:
- (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];
}
Curiosamente, UITableView
cuenta esto al NO ralentizar el seguimiento hasta que no PAST el control de actualización. Sin embargo, no veo una forma en que este comportamiento quede expuesto.
En mi aplicación, utilizo el control de actualización con la vista de colección.
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds];
collectionView.alwaysBounceVertical = YES;
...
[self.view addSubview:collectionView];
UIRefreshControl *refreshControl = [UIRefreshControl new];
[collectionView addSubview:refreshControl];
iOS7 tiene algunos errores desagradables que cuando se tira de la vista de colección hacia abajo y no suelta el dedo cuando comienza la actualización, contentOffset
vertical cambia de 20-30 puntos hacia abajo, lo que da como resultado un desagradable salto de desplazamiento.
Las tablas también tienen este problema si las usa con control de actualización fuera de UITableViewController
. Pero para ellos podría resolverse fácilmente asignando su instancia de UITableView
la propiedad privada de _refreshControl
llamada _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];
Pero UICollectionView
no tiene esa propiedad, por lo que debe haber alguna forma de manejarlo manualmente.
- (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];
});
}