2013-05-28 17 views
6

Sto tentando di definire un layout di flusso personalizzato per UICollectionView sottoclassi UICollectionViewFlowLayout. Il layout che voglio è simile al seguente:UICollectionViewFlowLayout spazio vuoto con larghezza e altezza delle celle variabili

layout

Come potete vedere, ho diviso la vista collezione in 2 righe uguali lungo lo spartiacque centrale orizzontale. La riga superiore è divisa in terzi per dare 3 colonne e le file in basso si dividono a metà per dare 2 colonne.

Tutto sembra funzionare e guardare bene fino a quando si scorre verso destra (lo scorrimento vista raccolta è quello di UICollectionViewScrollDirectionHorizontal), e vedere c'è un grande spazio dopo le 5 celle hanno finito in fase di rendering:

layout

Non ho idea del perché ciò stia accadendo, tuttavia sembra che lo spazio vuoto abbia la stessa larghezza di una cella dalla riga superiore; un terzo della larghezza della vista di raccolta.

Ecco come mi setup UICollectionView e UICollectionViewFlowLayout sottoclasse

- (void)loadView { 
    [super loadView]; 
    [self setupCollectionView]; 
} 

- (void)setupCollectionView { 
    CustomFlowLayout *flowLayout = [[CustomFlowLayout alloc] init]; 
    flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal; 
    flowLayout.minimumInteritemSpacing = 0.0; 
    flowLayout.minimumLineSpacing = 0.0f; 

    CGRect frame = CGRectMake(0, 0, 748, 1024); 
    UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:frame collectionViewLayout:flowLayout]; 

    [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:CollectionViewCellID]; 

    collectionView.delegate = self; 
    collectionView.dataSource = self; 

    collectionView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 

    collectionView.backgroundColor = [UIColor whiteColor]; 

    collectionView.pagingEnabled = YES; 


    self.collectionView = collectionView; 

    [self.view addSubview:self.collectionView]; 
} 

#pragma mark - UICollectionViewDataSource 
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 
    return 1; 
} 

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 

    return 5; 
} 

Le dimensioni degli elementi nella vista raccolta è definita dalla configurazione del layout di una data sezione, in modo da implementare collectionView:layout:sizeForItemAtIndexPath: modo:

- (CGSize)collectionView:(UICollectionView *)collectionView 
        layout:(UICollectionViewLayout*)collectionViewLayout 
    sizeForItemAtIndexPath:(NSIndexPath *)indexPath { 

    return [collectionViewLayout layoutAttributesForItemAtIndexPath:indexPath].size; 

} 

mio sottoclasse personalizzata di UICollectionViewLayout è implementato come segue:

@implementation CustomFlowLayout 

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { 
    NSArray* attributesToReturn = [super layoutAttributesForElementsInRect:rect]; 
    for (UICollectionViewLayoutAttributes* attributes in attributesToReturn) { 
     if (nil == attributes.representedElementKind) { 
      NSIndexPath* indexPath = attributes.indexPath; 
      attributes.frame = [self layoutAttributesForItemAtIndexPath:indexPath].frame; 
     } 
    } 
    return attributesToReturn; 
} 

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { 
    UICollectionViewLayoutAttributes* currentItemAttributes = [super layoutAttributesForItemAtIndexPath:indexPath]; 

    if (!currentItemAttributes) { 
     currentItemAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; 
    } 

    float height = self.collectionView.frame.size.height; 
    float width = self.collectionView.frame.size.width; 

    CGRect frame = CGRectZero;  
    switch (indexPath.row) { 
     case 0: 
      frame.size = CGSizeMake(width/3, height/2); 
      frame.origin = CGPointMake(0, 0); 
      break; 
     case 1: 
      frame.size = CGSizeMake(width/3, height/2); 
      frame.origin = CGPointMake(width/3, 0); 
      break; 
     case 2: 
      frame.size = CGSizeMake(width/3, height/2); 
      frame.origin = CGPointMake(2*width/3, 0); 
      break; 
     case 3: 
      frame.size = CGSizeMake(width/2, height/2); 
      frame.origin = CGPointMake(0, height/2); 
      break; 
     case 4: 
      frame.size = CGSizeMake(width/2, height/2); 
      frame.origin = CGPointMake(width/2, height/2); 
      break; 
     default: 
      break; 
    } 

    currentItemAttributes.frame = frame; 
    currentItemAttributes.size = frame.size; 
    return currentItemAttributes; 
} 

Qualcuno ha qualche idea del perché ho il grande spazio vuoto dopo che tutte le celle sono state renderizzate? O qualcuno ha un approccio migliore per rendere il layout che sto cercando. Tutto il codice è disponibile come esempio di progetto XCode here. Risposte, consigli, pensieri, richieste di pull sono molto apprezzate.

risposta

4

Il problema sembrava essere che quando c'erano due file di celle con larghezza diversa, il contentSize della collectionview veniva calcolato in modo tale da lasciare un'area di spazio bianco sulla destra. Un semplice era necessario per risolvere il problema:

- (CGSize)collectionViewContentSize { 
    return CGSizeMake(1024, 748); 
} 

Aggiornato il repo GitHub con i cambiamenti here. Spero che questo aiuti qualcuno in futuro.

Problemi correlati