UICollectionView Cell Overlap

Amanda picture Amanda · Apr 10, 2013 · Viewed 10.7k times · Source

I have a horizontal UICollectionView. I want to make the cells overlap each other by a certain amount of 60 pixels so that the second cells overlaps the first by 60 pixels and the third overlaps the second by the same amount and so on.

I tried sub classing UICollectionViewFlowLayout. But I am not able to place the UICollectionviewCell on top of one another.

Answer

mdewitt picture mdewitt · Nov 5, 2013

Starting with this tutorial: https://web-beta.archive.org/web/20151116053251/http://blog.tobiaswiedenmann.com/post/35135290759/stacklayout

I modified the stacklayout specifically for a horizontal UICollectionView

UICollectionViewStackLayout.h

#import <UIKit/UIKit.h>

@interface UICollectionViewStackLayout : UICollectionViewFlowLayout

#define STACK_OVERLAP 60 //this corresponds to 60 points which is probably what you want, not pixels
#define ITEM_SIZE CGSizeMake(190,210)

@end

UICollectionViewStackLayout.m

#import "UICollectionViewStackLayout.h"

@implementation UICollectionViewStackLayout

-(id)init{

    self = [super init];

    if (self) {
        [self commonInit];
    }

    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        [self commonInit];
    }

    return self;
}

-(void)commonInit
{
    self.itemSize = ITEM_SIZE;

    //set minimum layout requirements
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    self.minimumInteritemSpacing = 0;
}

-(CGSize)collectionViewContentSize
{
    NSInteger xSize = [self.collectionView numberOfItemsInSection:0]
    * self.itemSize.width;
    NSInteger ySize = [self.collectionView numberOfSections]
    * (self.itemSize.height);

    CGSize contentSize = CGSizeMake(xSize, ySize);

    if (self.collectionView.bounds.size.width > contentSize.width)
        contentSize.width = self.collectionView.bounds.size.width;

    if (self.collectionView.bounds.size.height > contentSize.height)
        contentSize.height = self.collectionView.bounds.size.height;

    return contentSize;
}

-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSArray* attributesArray = [super layoutAttributesForElementsInRect:rect];
    int numberOfItems = [self.collectionView numberOfItemsInSection:0];

    for (UICollectionViewLayoutAttributes *attributes in attributesArray) {
        CGFloat xPosition = attributes.center.x;
        CGFloat yPosition = attributes.center.y;

        if (attributes.indexPath.row == 0) {
            attributes.zIndex = INT_MAX; // Put the first cell on top of the stack
        } else {
            xPosition -= STACK_OVERLAP * attributes.indexPath.row;
            attributes.zIndex = numberOfItems - attributes.indexPath.row; //Other cells below the first one
        }

        attributes.center = CGPointMake(xPosition, yPosition);
    }

    return attributesArray;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path {
    UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path];
    return attributes;
}

@end