2013-05-28 16 views
6

Próbuję zdefiniować niestandardowy układ przepływu dla UICollectionView przez podklasowanie UICollectionViewFlowLayout. Układ Chcę wygląda następująco:UICollectionViewFlowLayout pusta przestrzeń o zmiennej szerokości i wysokości komórki

layout

Jak widać, mam podzielić pogląd zbiórki na 2 równe rzędy wzdłuż poziomej środkowej przepaści. Górny rząd jest podzielony na tercje, aby uzyskać 3 kolumny, a dolne rzędy podzielone na pół, aby uzyskać 2 kolumny.

Wszystko wydaje się działać i wyglądać dobrze, dopóki podczas przewijania w prawo (widok kolekcja przewijanie jest UICollectionViewScrollDirectionHorizontal) i zobaczyć tam dużą przestrzeń po 5 komórek zakończeniu są renderowane:

layout

Nie mam pojęcia, dlaczego tak się dzieje, jednak wydaje się, że pusta przestrzeń wygląda na tej samej szerokości co komórka z górnego rzędu; jedna trzecia szerokości widoku kolekcji.

Oto jak skonfigurować UICollectionView i UICollectionViewFlowLayout podklasa

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

Wielkość elementów w widoku kolekcji jest określona przez konfigurację układu dla danej sekcji, więc zaimplementować collectionView:layout:sizeForItemAtIndexPath: tak:

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

    return [collectionViewLayout layoutAttributesForItemAtIndexPath:indexPath].size; 

} 

Mam zwyczaj podklasa UICollectionViewLayout jest realizowany w następujący sposób:

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

Ktoś ma jakieś pomysły, dlaczego mam dużą pustą przestrzeń po wykonaniu wszystkich komórek? A może ktoś ma lepsze podejście do renderowania układu, którego szukam. Cały kod jest dostępny jako przykładowy projekt XCode here. Odpowiedzi, wskazówki, przemyślenia, prośby o pociągnięcie są bardzo mile widziane.

Odpowiedz

4

Problem polegał na tym, że gdy istniały dwa rzędy komórek, które miały różne szerokości, wielkość zawartości widoku kolekcji była obliczana w taki sposób, aby pozostawić obszar białej spacji na prawo. Prosty było konieczne, aby rozwiązać problem:

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

zaktualizowaliśmy repo Github ze zmianami here. Mam nadzieję, że to pomoże komuś w przyszłości.

Powiązane problemy