UIRefreshControl no UICollectionView funciona apenas se a coleção preencher a altura do contêiner

142

Estou tentando adicionar um UIRefreshControla um UICollectionView, mas o problema é que o controle de atualização não aparece, a menos que o modo de exibição de coleção preencha a altura do seu contêiner pai. Em outras palavras, a menos que a visualização da coleção seja longa o suficiente para exigir rolagem, ela não poderá ser puxada para baixo para revelar a visualização do controle de atualização. Assim que a coleção exceder a altura do contêiner pai, ela é puxada para baixo e revela a exibição de atualização.

Eu configurei um projeto iOS rápido, com apenas uma parte UICollectionViewinterna da visualização principal, com uma saída para a visualização de coleção, para que eu possa adicioná UIRefreshControl-la viewDidLoad. Há também uma célula protótipo com o identificador de reutilizaçãocCell

Esse é todo o código no controlador e demonstra muito bem o problema. Nesse código, defino a altura da célula como 100, o que não é suficiente para preencher a exibição e, portanto, a visualização não pode ser puxada e o controle de atualização não será exibido. Defina-o como algo mais alto para preencher a tela e funcionará. Alguma ideia?

@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
fonte
veja isso no iOS 10 stackoverflow.com/questions/19483511/…
Anish Parajuli 웃
1
UsealwaysBounceVertical
onmyway133

Respostas:

395

Tente o seguinte:

self.collectionView.alwaysBounceVertical = YES;

Código completo para um 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
fonte
1
Impressionante, essa linha é a correção exata, o resto do código não importa. Não é um começo ruim para você no StackOverflow! Felicidades!
Merott
7
Sim, não há problema. É óbvio que eu sou um novato, hein. De qualquer forma, fiquei presa na mesma situação quando vi sua postagem. Quando eu encontrei a solução, eu definitivamente deveria compartilhá-la. Cheers
Larry
6
Bem, Juan, você provavelmente já encontrou a resposta para sua pergunta. Mas, para retornar o controle de atualização ao seu estado normal após uma atualização, você deve chamar [refreshControl endRefreshing].
Merott 29/07
2
Infelizmente, isso não é mais suportado. UIRefreshControl só pode ser usado com UITableViewController e agora é rigorosamente aplicado.
Luke Van Em
3
No iOS 10, UIScrollView(uma visão geral de UICollectionView) tem uma refreshControlpropriedade agora developer.apple.com/videos/play/wwdc2016/219/?time=2033
Streeter
29

Atributos / Exibição de rolagem / rejeição verticalmente no Storyboard / Xib

insira a descrição da imagem aqui

avdyushin
fonte
23

A resposta de Larry rapidamente:

    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
fonte
Const dá um erro de variável indefinida. se alguém encontrar a mesma situação, substitua-a por UIColor.whiteColor()qualquer cor que você desejar.
Faisal
1
Também para Swift 2.2 Utilizaçãoaction: #selector(self.refresh)
Faisal
1

Se você collectionviewtem um tamanho de conteúdo grande o suficiente para rolar verticalmente, tudo bem, mas, no seu caso, não é.

Você deve habilitar a propriedade AlwaysBounceVerticalpara poder definirself.collectionView.alwaysBounceVertical = YES;

Nghia Luong
fonte
0

Eu também estava enfrentando o mesmo problema, não pude usá-lo UIRefreshControlaté que o UICollectionViewtamanho do conteúdo fosse grande o suficiente para rolar verticalmente,

Definir a bouncespropriedade de UICollectionViewresolveu este

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

Estou ligando beginRefreshing()logo depois viewDidLoad(), mas em algumas telas não funciona. E só collectionView.layoutIfNeeded()em viewDidLoad()me ajudou

Nikolai Ischuk
fonte
0

Você deve efetuar o check-in na chamada da API, se a exibição da coleção estiver no estado de atualização e terminar a atualização para dispensar o controle de atualização.

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
fonte
Observe que o salto na rolagem está ativado no meu arquivo de storyboard.
Asad Jamil