2013-05-28 80 views
6

我试图通过继承UICollectionViewFlowLayout来定义UICollectionView的自定义流布局。我想要的布局是这样的:UICollectionViewFlowLayout可变单元格宽度和高度的空白空间

layout

正如你所看到的,我已经分手集合视图到2个等于行沿水平中间的鸿沟。顶行被分成三份给出3列,底行被分成两份给出2列。

一切似乎工作,直到您滚动到右侧(集合视图滚动是UICollectionViewScrollDirectionHorizo​​ntal)外观精致,并看到有一个大的空间后的5个细胞已经完成渲染:

layout

我不知道为什么会发生这种情况,但是看起来空白空间与顶部行的单元格宽度相同;集合视图宽度的三分之一。

下面是我设置的UICollectionView和UICollectionViewFlowLayout子

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

在集合视图中的项目的大小是通过对给定段的布局配置中定义的,所以我实现collectionView:layout:sizeForItemAtIndexPath:像这样:

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

    return [collectionViewLayout layoutAttributesForItemAtIndexPath:indexPath].size; 

} 

我定制UICollectionViewLayout的子类实现如下:

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

任何人都有任何想法,为什么我所有的单元格都渲染后,我有大的空白空间?或者没有人有更好的方法来呈现我之后的布局。所有的代码都可以作为示例XCode项目here。回答,提示,想法,拉请求非常感谢。

回答

4

这个问题似乎是,当有两行宽度不同的单元格时,collectionview的contentSize是以这样一种方式计算的,即将空白区域留在右侧。一个简单的必要解决这个问题:

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

更新了Github上回购与变化here。希望这有助于未来的人。

相关问题