这是我初始化collectionView:
的方法[] <<<< Async >>>> playerasync_runAsynchronousCommandOnQueue: Command 3 returned -12784; this async error will be discarded
比我有以下代表方法:
self.collectionView = [[UICollectionView alloc]initWithFrame:self.frame collectionViewLayout:[[customLayout alloc]init]];
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
//[self.collectionView setAlwaysBounceVertical:YES];
[self.collectionView setBackgroundColor:[UIColor blueColor]];
self.collectionView.decelerationRate = UIScrollViewDecelerationRateFast;
UINib *nibf = [UINib nibWithNibName:@"inviteUserCell" bundle:nil];
[self.collectionView registerNib:nibf forCellWithReuseIdentifier:@"user"];
[self addSubview:self.collectionView];
在我的日志中,我得到 - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
NSLog(@"sections 1");
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
NSLog(@"items 40");
return 40;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
inviteUserCell *cell = (inviteUserCell *) [collectionView dequeueReusableCellWithReuseIdentifier:@"user" forIndexPath:indexPath];
[cell setBackgroundColor:[UIColor whiteColor]];
NSLog(@"CELL: %@", cell);
return cell;
}
和sections 1
,但我没有items 40
。对于我的CELL: %@
的子类,我有以下方法。
UICollectionViewLayout
我不确定我没有打电话或设置会让 - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
return true;
}
- (CGSize)collectionViewContentSize{
CGSize size = CGSizeMake(self.collectionView.frame.size.width, self.collectionView.frame.size.height);
return size;
}
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
NSArray *attributesInRect = [super layoutAttributesForElementsInRect:rect];
for (UICollectionViewLayoutAttributes *cellAttributes in attributesInRect) {
// [self modifyLayoutAttributes:cellAttributes];
cellAttributes.size = CGSizeMake(10, 10);
cellAttributes.center = CGPointMake(100, 100);
}
return attributesInRect;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:indexPath];
// [self modifyLayoutAttributes:attributes];
attributes.size = CGSizeMake(10, 10);
attributes.center = CGPointMake(100, 100);
NSLog(@"Attr: %@", attributes); // this is null
return attributes;
}
被调用。
布局
所需的布局是50x50网格,垂直和放大水平滚动。从cellForItemAtIndexPath
左右阅读只能进行垂直或水平滚动。所以我继承了UICollectionViewFlowLayout
答案 0 :(得分:0)
一些观察结果:
关键问题是layoutAttributesForElementsInRect
应该返回特定rect中可见的所有单元格的布局属性数组。如果不返回属性对象数组,每个可见单元格对应一个属性对象,则不会要求cellForItemAt
生成任何单元格。
现在,您将如何针对特定布局执行此操作可能会有所不同,但例如,这会找到与rect
相交的所有内容,为每个内容调用layoutAttributesForItemAtIndexPath
并附加它们到阵列。
您的layoutAttributesForItemAtIndexPath
指定所有单元格的中心位于集合视图中的100,100,并且大小为10,10。简而言之,您指定它们都处于完全相同的位置,彼此重叠。这有点好奇。通常,每个单元格都有一些唯一的center
。
如果你想要它们在50 x 50网格中,你可以这样做:
// CustomLayout.m
#import "CustomLayout.h"
static const CGSize kCellSize = { 70, 30 }; // make whatever size you want
static const CGFloat kCellSpacing = 5;
static const NSInteger kCellsPerRow = 50;
@implementation CustomLayout
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
return true;
}
- (CGSize)collectionViewContentSize {
NSInteger count = [self.collectionView numberOfItemsInSection:0];
if (count == 0) return CGSizeZero;
NSInteger numberOfColumns = MIN(kCellsPerRow, count);
NSInteger numberOfRows = (count - 1) % kCellsPerRow + 1;
return CGSizeMake(numberOfColumns * (kCellSize.width + kCellSpacing) + kCellSpacing,
numberOfRows * (kCellSize.height + kCellSpacing) + kCellSpacing);
}
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray <UICollectionViewLayoutAttributes *> *attributes = [NSMutableArray array];
NSInteger count = [self.collectionView numberOfItemsInSection:0];
NSInteger numberOfRows = (count - 1) % kCellsPerRow + 1;
NSInteger startColumn = MAX(0, floorf(rect.origin.x / (kCellSize.width + kCellSpacing)));
NSInteger endColumn = MIN(kCellsPerRow, ceilf((rect.origin.x + rect.size.width) / (kCellSize.width + kCellSpacing)));
NSInteger startRow = MAX(0, floorf(rect.origin.y / (kCellSize.height + kCellSpacing)));
NSInteger endRow = MIN(numberOfRows, ceilf((rect.origin.y + rect.size.height) / (kCellSize.height + kCellSpacing)));
for (NSInteger row = startRow; row < endRow; row++) {
for (NSInteger column = startColumn; column < endColumn; column++) {
NSInteger index = row * kCellsPerRow + column;
if (index < count) {
[attributes addObject:[self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]]];
}
}
}
return attributes;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
NSInteger column = indexPath.item % kCellsPerRow;
NSInteger row = indexPath.item / kCellsPerRow;
attributes.size = kCellSize;
attributes.center = CGPointMake(column * (kCellSize.width + kCellSpacing) + kCellSpacing + kCellSize.width / 2,
row * (kCellSize.height + kCellSpacing) + kCellSpacing + kCellSize.height / 2);
return attributes;
}
@end
显然,如果你想要一个50 x 50的网格,那么你可能希望单元格的数量为2,500,而不是40。
我确信为简洁起见省略了它,但您的代码段并未演示集合视图collectionViewLayout
的设置。
无论如何,上面的内容呈现了以下集合视图:
现在,我让我的细胞足够大,所以我可以在那里放一个标签并显示细胞的indexPath.item
,但是可以制作任何你想要的尺寸。