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);
}


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;

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


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

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;


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

0

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


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()
}

Observe que o salto na rolagem está ativado no meu arquivo de storyboard.
Asad Jamil
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.