Come impostare UICollectionViewDelegateFlowLayout?


108

Un UIViewController mantiene un riferimento a un UICollectionView. Il controller deve modificare il layout del flusso incorporato utilizzando UICollectionViewDelegateFlowLayout.

È abbastanza facile impostare l'origine dati della vista su self:

MyViewController.m

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

Ma come si imposta il controller in modo che sia il layout del flusso delegato della visualizzazione?

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

Ho provato:

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

Ma ottengo l'errore: "Tipi di puntatore incompatibili che assegnano ...".

Il file di intestazione della raccolta ha questo aspetto:

MyViewController.h

@interface MyViewController : UIViewController <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>

Risposte:


265

Solo self.collectionView.delegate = self;. Nota che UICollectionViewDelegateFlowLayouteredita da UICollectionViewDelegate.

Ammetto che all'inizio mi ha colto di sorpresa.

Oh, e questo funzionerà solo se self.collectionView.collectionViewLayoutè effettivamente impostato sul layout del flusso. (o impostare con initWithFrame:collectionViewLayout:)


1
@ JohnEstropia, scusa per la domanda, ma come avviare il layout personalizzato nel codice? Vedo esempi con storyboard ma non con il codice stesso. Cosa dovrei fare?
gaussblurinc

3
Probabilmente, self.collectionViewLayout = UICollectionViewFlowLayout(),self.collectionViewLayout = [[UICollectionViewFlowLayout alloc]init]
Daishi Nakajima

14

Secondo la risposta precedente solo un esempio di utilizzo. Davvero non è chiaro, ma posso mostrare come funziona:

@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

1

I miei due centesimi per macOS Mojave - Swift

(Sono caduto qui cercando NSCollectionView... so che la domanda riguardava UICollectionView...)

Tutto quanto detto sopra (specificare delegato implica anche la dimensione della cella) è corretto anche per macOS.

NOTA : se scrivi:

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

il metodo:

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

sarà chiamato.

Se rimosso, non verrà chiamato alcun metodo delegato. (poiché la classe non obbedisce al protocollo).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.