我正在尝试布局一个UICollectionView,就像我在照片中绘制的模型一样(也显示了每个项目的索引):
我目前必须尝试实现的代码是:
在ViewDidLoad中:
collectionView.dataSource = self
collectionView.delegate = self
flowLayout.scrollDirection = .horizontal
flowLayout.minimumLineSpacing = 5
flowLayout.minimumInteritemSpacing = 5
flowLayout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 5)
然后在文件上:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let totalWidth = collectionView.bounds.size.width
let totalHeight = collectionView.bounds.size.height
let heightOfView = totalHeight / 3
let numberOfCellsPerRow = 1
let dimensions = CGFloat(Int(totalWidth) / numberOfCellsPerRow)
if (indexPath.item == 4) {
return CGSize(width: collectionView.bounds.size.width, height: heightOfView)
} else {
return CGSize(width: dimensions / 2, height: heightOfView)
}
}
此代码没有达到预期效果,并且正在生成如下所示的UICollectionView:
正如您所看到的,单元格在UICollectionView
中不均匀,右侧单元格溢出到滚动空间。项目之间的部分间隔是错误的,第5个,除非滚动到屏幕的右侧,否则较大的单元格位于屏幕的右侧。
答案 0 :(得分:1)
您无法使用标准UICollectionViewFlowLayout类创建此类布局。首先观看与UICollectionView相关的WWDC视频及其布局:https://developer.apple.com/videos/play/wwdc2012/219/。然后,您可以使用示例代码检查Swift教程以开始使用:http://swiftiostutorials.com/tutorial-creating-custom-layouts-uicollectionview/
最简单的工作,但不是最好的结构化将是自定义UICollectionViewLayout
中的此类代码。以此为出发点:
@interface UICollectionViewCustomLayout ()
@property (nonatomic) NSArray<UICollectionViewLayoutAttributes *> *attributes;
@property (nonatomic) CGSize size;
@end
@implementation UICollectionViewCustomLayout
- (void)prepareLayout
{
[super prepareLayout];
NSMutableArray<UICollectionViewLayoutAttributes *> *attributes = [NSMutableArray new];
id<UICollectionViewDelegate> delegate = (id<UICollectionViewDelegate>)self.collectionView.delegate;
id<UICollectionViewDataSource> dataSource = (id<UICollectionViewDataSource>)self.collectionView.dataSource;
NSInteger count = [dataSource collectionView:self.collectionView numberOfItemsInSection:0];
CGFloat collectionViewWidth = CGRectGetWidth(self.collectionView.frame);
CGFloat collectionViewHeight = CGRectGetHeight(self.collectionView.frame);
CGFloat rowHeight = floor(collectionViewHeight / 3);
NSUInteger numberOfPages = count / 5;
if (count % 5) {
numberOfPages++;
}
for (NSInteger item = 0; item < count; item++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:0];
UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
NSInteger index = item % 5;
NSInteger page = item / 5;
CGFloat width = index == 4 ? collectionViewWidth : collectionViewWidth / 2;
CGSize size = CGSizeMake(width, rowHeight);
CGFloat x = page * collectionViewWidth + (index % 2 == 0 ? 0 : collectionViewWidth / 2);
CGFloat y = (index / 2) * rowHeight;
CGPoint origin = CGPointMake(x, y);
CGRect frame = CGRectZero;
frame.size = size;
frame.origin = origin;
attribute.frame = frame;
[attributes addObject:attribute];
}
self.attributes = attributes;
self.size = CGSizeMake(numberOfPages * collectionViewWidth, collectionViewHeight);
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray<UICollectionViewLayoutAttributes *> *result = [NSMutableArray new];
for (UICollectionViewLayoutAttributes *attribute in self.attributes) {
if (CGRectIntersectsRect(attribute.frame, rect)) {
[result addObject:attribute];
}
}
return result;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"indexPath.section == %@ AND indexPath.item == %@", @(indexPath.section), @(indexPath.item)];
UICollectionViewLayoutAttributes *attributes = [self.attributes filteredArrayUsingPredicate:predicate].firstObject;
return attributes;
}
- (CGSize)collectionViewContentSize
{
return self.size;
}
@end
和控制器:
// Views
#import "UICollectionViewCustomLayout.h"
@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate>
@property (nonatomic) UICollectionView *collectionView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:[UICollectionViewCustomLayout new]];
self.collectionView.backgroundColor = [UIColor whiteColor];
self.collectionView.frame = self.view.bounds;
self.collectionView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class])];
[self.view addSubview:self.collectionView];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 10;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath
{
NSArray *colors = @[[UIColor redColor], [UIColor blueColor], [UIColor grayColor], [UIColor greenColor], [UIColor purpleColor], [UIColor cyanColor]];
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class]) forIndexPath:indexPath];
cell.contentView.backgroundColor = colors[arc4random() % colors.count];
cell.contentView.alpha = (arc4random() % 500 + 500) / 1000.0;
return cell;
}
@end