Reputation: 307
i'm having problems to align the first row to the top when I have different UICollectionViewCell heights and I don't know why. It seems that minimumLineSpacingForSectionAtIndex method is not working.
Here is my result:
As you can see, the first row is not aligned to the top.
This is my code:
- (void)viewDidLoad
{
...
FlowLayout *flowLayout = [[FlowLayout alloc] init];
flowLayout.itemSize = CGSizeMake(152, 260);
flowLayout.sectionInset = UIEdgeInsetsMake( 5, 5, 5, 5);
flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
self.collectionView.collectionViewLayout = flowLayout;
...
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:
(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)
indexPath{
if (indexPath.row == 0)
return CGSizeMake(152, 200);
if (indexPath.row == 1)
return CGSizeMake(152, 270);
return CGSizeMake(152, 300);
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:
(UICollectionViewLayout*)collectionViewLayout
minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 5.0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 8.0;
}
This is the code of my FlowLayout:
@implementation FlowLayout
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *result = [NSMutableArray array];
NSInteger sectionCount = 1;
if ([self.collectionView.dataSource respondsToSelector:@selector(numberOfSectionsInCollectionView:)])
{
sectionCount = [self.collectionView.dataSource numberOfSectionsInCollectionView:self.collectionView];
}
for (int s = 0; s < sectionCount; s++)
{
NSInteger itemCount = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:s];
for (int i = 0; i < itemCount; i++)
{
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:s];
UICollectionViewLayoutAttributes *layoutAttributes =
[self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath];
if (layoutAttributes != nil) {
[result addObject:layoutAttributes];
}
UICollectionViewLayoutAttributes *layout = [self layoutAttributesForItemAtIndexPath:indexPath];
if (CGRectIntersectsRect(rect, layout.frame))
{
[result addObject:layout];
}
}
}
return result;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes* atts =
[super layoutAttributesForItemAtIndexPath:indexPath];
if (indexPath.item == 0 || indexPath.item == 1) // degenerate case 1, first item of section
return atts;
NSIndexPath* ipPrev =
[NSIndexPath indexPathForItem:indexPath.item-2 inSection:indexPath.section];
CGRect fPrev = [self layoutAttributesForItemAtIndexPath:ipPrev].frame;
CGFloat rightPrev = fPrev.origin.y + fPrev.size.height + 10;
if (atts.frame.origin.y <= rightPrev) // degenerate case 2, first item of line
return atts;
CGRect f = atts.frame;
f.origin.y = rightPrev;
atts.frame = f;
return atts;
}
- (BOOL) shouldInvalidateLayoutForBoundsChange:(CGRect)newBound {
return YES;
}
Upvotes: 1
Views: 557
Reputation: 40028
What you are experiencing is a normal cell placement when using the UICollectionViewFlowLayout
.
You have to tweak the layout attributes being returned by the flow layout. To do so, override the layoutAttributesForElementsInRect:
method and any of the methods that return layout attributes. Modify the attributes provided by the parent class, and then return them. The attribute you have to modify is frame
.
A good example of doing it is a sample code from Apple - Custom Layouts: A Worked Example
Looks like in the layoutAttributesForItemAtIndexPath:
method you are not adjusting the frame
for first item (index 0
). You are returning the attributes you get from parent class. Change the frame's origin.y
to 0
for item 0
.
Upvotes: 1