我正在尝试通过继承UICollectionViewFlowLayout为UICollectionView定义自定义流布局。我想要的布局如下:
正如您所看到的,我已将集合视图沿水平中间分割分成2行。顶行被分成三列,给出3列,底行分成两列,给出2列。
一切似乎都能正常工作,直到向右滚动(集合视图滚动到UICollectionViewScrollDirectionHorizontal),并在完成渲染完5个单元格之后看到一个很大的空间:
我不知道为什么会发生这种情况,但是看起来空的空间看起来与顶行的单元格宽度相同;集合视图宽度的三分之一。
以下是我如何设置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使用。非常感谢答案,提示,想法,拉取请求。
答案 0 :(得分:4)
问题似乎是,当有两排具有不同宽度的单元格时,集合视图的contentSize的计算方式是将一个空白区域留在右侧。解决问题需要一个简单的方法:
- (CGSize)collectionViewContentSize {
return CGSizeMake(1024, 748);
}
使用更改here更新了Github仓库。希望这可以帮助将来的某个人。