Como definir UICollectionViewDelegateFlowLayout?

108

Um UIViewController mantém uma referência a um UICollectionView. O controlador deve modificar o layout de fluxo integrado usando o UICollectionViewDelegateFlowLayout.

É muito fácil definir a fonte de dados da visualização como self:

MyViewController.m

- (void)viewDidLoad
{
    self.collectionView.dataSource = self;
}

Mas como defino o controlador para ser o layout de fluxo de delegado da visualização?

- (void)viewDidLoad
{
    self.collectionView.dataSource= self;
    // self.collectionView.??? = self; 
}

Eu tentei:

- (void)viewDidLoad
{
    self.collectionView.dataSource= self;
    self.collectionView.collectionViewLayout = self; 
}

Mas recebo o erro: "Tipos de ponteiro incompatíveis atribuindo ...".

O arquivo de cabeçalho da coleção tem a seguinte aparência:

MyViewController.h

@interface MyViewController : UIViewController <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
Rich Apodaca
fonte

Respostas:

265

Apenas self.collectionView.delegate = self;. Observe que UICollectionViewDelegateFlowLayoutherda de UICollectionViewDelegate.

Eu admito que me pegou desprevenido no começo.

Ah, e isso só funcionará se self.collectionView.collectionViewLayoutfor realmente definido para o layout do seu fluxo. (ou definir com initWithFrame:collectionViewLayout:)

John Estropia
fonte
1
@JohnEstropia, desculpe a pergunta, mas como inicializar o layout personalizado no código? Vejo exemplos com storyboards, mas não com o código em si. O que devo fazer?
gaussblurinc
3
Provavelmente, self.collectionViewLayout = UICollectionViewFlowLayout(),self.collectionViewLayout = [[UICollectionViewFlowLayout alloc]init]
Daishi Nakajima
14

De acordo com a resposta anterior apenas exemplo de uso. Realmente não está claro, mas posso mostrar como funciona:

@interface PrettyViewController()<UICollectionViewDelegateFlowLayout, UICollectionViewDataSource>
    //some code
@end

@implementation PrettyViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.collectionView.delegate = self;//bingo! right here
}

#pragma mark - UICollectionViewDelegateFlowLayout

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
    return CGSizeMake([[UIScreen mainScreen] bounds].size.width, 20.0);
}


@end
WINSergey
fonte
1

Meus dois centavos para macOS Mojave - Swift

(Eu caí aqui procurando por NSCollectionView... eu sei que a pergunta era sobre UICollectionView..)

Tudo o que foi dito acima (especificar delegado implica também no tamanho da célula) também está correto para o macOS.

NOTA : Se você escrever:

class MyViewController:
    NSCollectionViewDelegate,
    NSCollectionViewDataSource,
    **NSCollectionViewDelegateFlowLayout** 
{

o método:

func collectionView(_ collectionView: NSCollectionView, 
                      layout collectionViewLayout: NSCollectionViewLayout, 
               sizeForItemAt indexPath: IndexPath) -> NSSize

será chamado.

Se removido, nenhum método delegado será chamado. (pois a classe não obedece ao protocolo).

ingconti
fonte