UICollectionView 中的单元格顺序 [英] Cells order in UICollectionView
问题描述
我需要创建一个具有不同大小(1x1、2x2、2x1、3x2.5)的单元格的 UICollectionView
.我已经编写了代码来根据它们使用的大小添加单元格 collectionView:layout:sizeForItemAtIndexPath:
.
I need to create a UICollectionView
with cells of different sizes (1x1, 2x2, 2x1, 3x2.5). I've already code to add cells depending on which size they are using collectionView:layout:sizeForItemAtIndexPath:
.
这是预期的结果(单元格 1 和 3 必须位于单元格 2 的左侧):
Here is expected result (cells 1 and 3 have to be on the left of cell 2) :
但目前的结果是:
But current result is :
我的(丑陋的)当前代码是(self.cellSize = screen width/3):
My (ugly) current code is (self.cellSize = screen width / 3) :
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGFloat size = self.cellSize;
if (indexPath.item == 0) {
return CGSizeMake(self.cellSize * 3.f, self.cellSize * 2.5f);
}
if (indexPath.item == 1) {
return CGSizeMake(self.cellSize, self.cellSize);
}
if (indexPath.item == 2) {
return CGSizeMake(self.cellSize * 2.f, self.cellSize * 2.f);
}
if (indexPath.item == 3) {
return CGSizeMake(self.cellSize, self.cellSize);
}
if (indexPath.item == 4) {
return CGSizeMake(self.cellSize * 2.f, self.cellSize);
}
if (indexPath.item == 5) {
return CGSizeMake(self.cellSize, self.cellSize);
}
if (indexPath.item == 6) {
return CGSizeMake(self.cellSize, self.cellSize);
}
if (indexPath.item == 7) {
return CGSizeMake(self.cellSize * 2.f, self.cellSize);
}
if (indexPath.item == 8) {
return CGSizeMake(self.cellSize * 3.f, self.cellSize * 2.5f);
}
return CGSizeMake(size, size);
}
有没有办法指定单元格 3 必须在单元格 1 上方,但在单元格 2 的左侧?
Is there a way to specify that cell 3 has to be above cell 1, but on left of cell 2 ?
我不想做一个不会改变的静态布局,因为每个单元格将来可能有不同的大小.例如,单元格 2 可以是 2x1 大小...
I don't want to do a static layout that will not change because each cell could be of different size in future. For example, cell 2 could be 2x1 sized ...
这样做的最佳方法是什么?我期待为 UICollectionViewLayout
指定一个流程(如从顶部"),但它不像那样工作......
Which is the best approach to do that ? I was expecting to specify to UICollectionViewLayout
a flow (like "from top"), but it doesn't work like that ...
推荐答案
继承 UICollectionViewLayout 的示例.所有值都是硬编码的,只是为了明确其背后的逻辑.当然,这可以优化.
A sample example by subclassing UICollectionViewLayout. All values are hard coded, just to explicit the logic behind it. Of course, that could be optimized.
@interface CustomCollectionViewLayout ()
@property (nonatomic, strong) NSMutableDictionary *cellLayouts;
@property (nonatomic, assign) CGSize unitSize;
@end
@implementation CustomCollectionViewLayout
-(id)initWithSize:(CGSize)size
{
self = [super init];
if (self)
{
_unitSize = CGSizeMake(size.width/3,150);
_cellLayouts = [[NSMutableDictionary alloc] init];
}
return self;
}
-(void)prepareLayout
{
for (NSInteger i = 0; i < [[self collectionView] numberOfItemsInSection:0]; i ++)
{
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
CGRect frame;
switch ([indexPath item])
{
case 0:
frame = CGRectMake(0, 0, _unitSize.width*3, _unitSize.height*2.5);
break;
case 1:
frame = CGRectMake(0, _unitSize.height*2.5, _unitSize.width, _unitSize.height);
break;
case 2:
frame = CGRectMake(_unitSize.width, _unitSize.height*2.5, _unitSize.width*2, _unitSize.height*2);
break;
case 3:
frame = CGRectMake(0, _unitSize.height*2.5+_unitSize.height, _unitSize.width, _unitSize.height);
break;
case 4:
frame = CGRectMake(0, _unitSize.height*2.5+_unitSize.height+_unitSize.height, _unitSize.width*2, _unitSize.height);
break;
case 5:
frame = CGRectMake(_unitSize.width*2, _unitSize.height*2.5+_unitSize.height+_unitSize.height, _unitSize.width, _unitSize.height);
break;
case 6:
frame = CGRectMake(0, _unitSize.height*2.5+_unitSize.height+_unitSize.height+_unitSize.height, _unitSize.width, _unitSize.height);
break;
case 7:
frame = CGRectMake(_unitSize.width, _unitSize.height*2.5+_unitSize.height+_unitSize.height+_unitSize.height, _unitSize.width*2, _unitSize.height);
break;
case 8:
frame = CGRectMake(0, _unitSize.height*2.5+_unitSize.height+_unitSize.height+_unitSize.height+_unitSize.height, _unitSize.width*3, _unitSize.height*2.5);
break;
default:
frame = CGRectZero;
break;
}
[attributes setFrame:frame];
[[self cellLayouts] setObject:attributes forKey:indexPath];
}
}
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *retAttributes = [[NSMutableArray alloc] init];
for (NSIndexPath *anIndexPath in [self cellLayouts])
{
UICollectionViewLayoutAttributes *attributes = [self cellLayouts][anIndexPath];
if (CGRectIntersectsRect(rect, [attributes frame]))
{
[retAttributes addObject:attributes];
}
}
return retAttributes;
}
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
return [self cellLayouts][indexPath];
}
-(CGSize)collectionViewContentSize
{
return CGSizeMake(_unitSize.width*3, _unitSize.height*9);
}
@end
然后,您只需调用:
CustomCollectionViewLayout *layout = [[CustomCollectionViewLayout alloc] initWithSize:self.myCollectionView.bounds.frame.size];
[self.myCollectionView setCollectionViewLayout:layout];
渲染:
这篇关于UICollectionView 中的单元格顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!