UIRefreshControl sur UICollectionView ne fonctionne que si la collection remplit la hauteur du conteneur

142

J'essaie d'ajouter un UIRefreshControlà un UICollectionView, mais le problème est que le contrôle d'actualisation n'apparaît que si la vue de collection remplit la hauteur de son conteneur parent. En d'autres termes, à moins que la vue de collection ne soit suffisamment longue pour nécessiter un défilement, elle ne peut pas être tirée vers le bas pour révéler la vue de contrôle d'actualisation. Dès que la collection dépasse la hauteur de son conteneur parent, elle est tirée vers le bas et révèle la vue d'actualisation.

Je l' ai mis en place un projet iOS rapide avec juste UICollectionViewdans la vue principale, avec une sortie à la vue de la collecte afin que je puisse ajouter UIRefreshControlà dans viewDidLoad. Il existe également une cellule prototype avec l'identifiant de réutilisationcCell

C'est tout le code du contrôleur et cela illustre assez bien le problème. Dans ce code, j'ai défini la hauteur de la cellule sur 100, ce qui n'est pas suffisant pour remplir l'affichage.Par conséquent, la vue ne peut pas être extraite et le contrôle d'actualisation ne s'affiche pas. Réglez-le sur quelque chose de plus haut pour remplir l'écran, puis cela fonctionne. Des idées?

@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
la source
voir ceci pour iOS 10 stackoverflow.com/questions/19483511/…
Anish Parajuli 웃
1
UtilisationalwaysBounceVertical
onmyway133

Réponses:

395

Essaye ça:

self.collectionView.alwaysBounceVertical = YES;

Code complet pour 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
la source
1
Génial, cette ligne est la solution exacte, le reste du code n'a pas d'importance. Pas un mauvais départ pour vous sur StackOverflow! À votre santé!
Merott
7
Oui, pas de problème. Il est si évident que je suis un débutant hein. Quoi qu'il en soit, il s'avère que j'étais coincé dans la même situation lorsque j'ai vu votre message. Quand j'ai trouvé la solution, je pensais que je devrais certainement la partager. Cheers
Larry
6
Eh bien, Juan, vous avez probablement déjà trouvé la réponse à votre question. Mais, pour ramener le contrôle d'actualisation à son état normal après une actualisation, vous devez appeler [refreshControl endRefreshing].
Merott
2
Ceci n'est malheureusement plus pris en charge. UIRefreshControl ne peut être utilisé qu'avec UITableViewController et il est maintenant strictement appliqué.
Luke Van
3
Dans iOS 10, UIScrollView(a superview of UICollectionView) a refreshControlmaintenant une propriété developer.apple.com/videos/play/wwdc2016/219/?time=2033
Streeter
29

Attributs / Vue de défilement / Rebondir verticalement dans Storyboard / Xib

entrez la description de l'image ici

avdyushin
la source
23

Réponse rapide de Larry:

    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
la source
Const donne une erreur de variable non définie. si quelqu'un rencontre la même situation, remplacez-le simplement par la UIColor.whiteColor()couleur de votre choix.
Faisal
1
Aussi pour Swift 2.2action: #selector(self.refresh)
Faisal
1

Si votre collectionviewcontenu est suffisamment grand pour faire défiler verticalement, c'est OK, mais dans votre cas, ce n'est pas le cas.

Vous devez activer la propriété AlwaysBounceVerticalpour pouvoir définirself.collectionView.alwaysBounceVertical = YES;

Nghia Luong
la source
0

J'étais moi aussi confronté au même problème, je ne pouvais pas utiliser le UIRefreshControltant que la UICollectionViewtaille du contenu de n'était pas suffisamment grande pour faire défiler verticalement,

Définition de la bouncespropriété de UICollectionViewrésolu ce

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

J'appelle beginRefreshing()juste après viewDidLoad(), mais sur certains écrans, cela ne fonctionne pas. Et seulement collectionView.layoutIfNeeded()en viewDidLoad()m'a aidé

Nikolai Ischuk
la source
0

Vous devez archiver l'appel d'API si la vue de collection est en état d'actualisation, puis terminer l'actualisation pour ignorer le contrôle d'actualisation.

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
la source
Pour être noté, le rebond sur le défilement est activé dans mon fichier de storyboard.
Asad Jamil le