UIRefreshControl en UICollectionView solo funciona si la colección llena la altura del contenedor

142

Estoy tratando de agregar a UIRefreshControla UICollectionView, pero el problema es que el control de actualización no aparece a menos que la vista de recopilación llene la altura de su contenedor principal. En otras palabras, a menos que la vista de colección sea lo suficientemente larga como para requerir desplazamiento, no se puede desplegar para revelar la vista de control de actualización. Tan pronto como la colección excede la altura de su contenedor principal, se despliega y revela la vista de actualización.

He creado un proyecto IOS rápida con sólo una UICollectionViewdentro de la vista principal, con una salida a la vista de colección para que pueda añadir el UIRefreshControla ella en viewDidLoad. También hay una celda prototipo con el identificador de reutilizacióncCell

Este es todo el código en el controlador, y demuestra el problema bastante bien. En este código, establezco la altura de la celda en 100, que no es suficiente para llenar la pantalla y, por lo tanto, la vista no se puede extraer y el control de actualización no se mostrará. Ajústelo a algo más alto para llenar la pantalla, luego funciona. ¿Algunas ideas?

@interface ViewController () <UICollectionViewDelegateFlowLayout, UICollectionViewDataSource>
@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
    [self.collectionView addSubview:refreshControl];
}

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return 1;
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    return [collectionView dequeueReusableCellWithReuseIdentifier:@"cCell" forIndexPath:indexPath];
}

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return CGSizeMake(self.view.frame.size.width, 100);
}
Merott
fuente
vea esto para iOS 10 stackoverflow.com/questions/19483511/…
Anish Parajuli 웃
1
UsoalwaysBounceVertical
onmyway133

Respuestas:

395

Prueba esto:

self.collectionView.alwaysBounceVertical = YES;

Código completo para un UIRefreshControl

UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
refreshControl.tintColor = [UIColor grayColor];
[refreshControl addTarget:self action:@selector(refershControlAction) forControlEvents:UIControlEventValueChanged];
[self.collectionView addSubview:refreshControl];
self.collectionView.alwaysBounceVertical = YES;
Larry
fuente
1
Impresionante, esa línea es la solución exacta, el resto del código no importa. ¡No es un mal comienzo para ti en StackOverflow! ¡Salud!
Merott
77
Sí, no hay problema. Es tan obvio que soy un novato eh. De todos modos, resultó que estaba atrapado en la misma situación cuando vi tu publicación. Cuando encontré la solución, pensé que definitivamente debería compartirla. Saludos
Larry
66
Bueno, Juan, probablemente ya has encontrado la respuesta a tu pregunta. Pero, para devolver el control de actualización a su estado normal después de una actualización, debe llamar [refreshControl endRefreshing].
Merott
2
Desafortunadamente, esto ya no es compatible. UIRefreshControl solo se puede usar con UITableViewController y ahora se aplica estrictamente.
Luke Van En
3
En iOS 10, UIScrollView(una vista general de UICollectionView) tiene una refreshControlpropiedad ahora developer.apple.com/videos/play/wwdc2016/219/?time=2033
Streeter
29

Atributos / Vista de desplazamiento / Rebotar verticalmente en Storyboard / Xib

ingrese la descripción de la imagen aquí

avdyushin
fuente
23

La respuesta de Larry rápidamente:

    let refreshControl = UIRefreshControl()
    refreshControl.tintColor = UIColor.blueColor()
    refreshControl.addTarget(self, action: "refresh", forControlEvents: .ValueChanged)
    collectionView.addSubview(refreshControl)
    collectionView.alwaysBounceVertical = true

Swift 3:

    let refreshControl = UIRefreshControl()
    refreshControl.tintColor = .blue
    refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged)
    collectionView.addSubview(refreshControl)
    collectionView.alwaysBounceVertical = true
Andrew Schreiber
fuente
Const da un error de variable indefinida. Si alguien se encuentra con la misma situación, simplemente reemplácelo con el UIColor.whiteColor()color que desee.
Faisal
1
También para uso Swift 2.2action: #selector(self.refresh)
Faisal
1

Si collectionviewtiene un tamaño de contenido lo suficientemente grande como para desplazarse verticalmente, está bien, pero en su caso no lo es.

Debe habilitar la propiedad AlwaysBounceVertical, para poder establecerself.collectionView.alwaysBounceVertical = YES;

Nghia Luong
fuente
0

Yo también estaba enfrentando el mismo problema, no pude usarlo UIRefreshControlhasta que el UICollectionViewtamaño del contenido era lo suficientemente grande como para desplazarme verticalmente,

Estableciendo la bouncespropiedad de UICollectionViewresuelto este

[self.collectionView setBounces:YES];
[self.collectionView setAlwaysBounceVertical:YES];
Saif
fuente
0

Llamo beginRefreshing()justo después viewDidLoad(), pero en algunas pantallas no funciona. Y solo collectionView.layoutIfNeeded()en viewDidLoad()me ayudó

Nikolai Ischuk
fuente
0

Debe verificar la llamada a la API si la vista de colección está en estado de actualización y luego finalizar la actualización para descartar el control de actualización.

private let refreshControl = UIRefreshControl()
 refreshControl.tintColor = .white
 refreshControl.addTarget(self, action: #selector(refreshData), for: .valueChanged)
 collectionView.addSubview(refreshControl)
 @objc func refreshData() {
    // API Call
 }
// Disable refresh control if already refreshing 
if refreshControl.isRefreshing {
    refreshControl.endRefreshing()
}
Asad Jamil
fuente
Cabe señalar que el rebote en el desplazamiento está habilitado en mi archivo de guión gráfico.
Asad Jamil