title: circular collection view layout
body: <p>im trying to make a collection view that is circular in shape.</p>
  
  <p><img src="https://i.stack.imgur.com/uBv4B.png" alt="this is what im trying to do"></p>
  
  <p>Somehow I managed to get the view circular, but stuck with scrolling. my collection view cells and layout are circular but I'm not able to make the cells scrollable.</p>
  
  <pre><code>`#import "CircleLayout.h"
  
  #define ITEM_SIZE 70
  
  @interface CircleLayout()
  
  // arrays to keep track of insert, delete index paths
  @property (nonatomic, strong) NSMutableArray *deleteIndexPaths;
  @property (nonatomic, strong) NSMutableArray *insertIndexPaths;
  
  @end
  
  @implementation CircleLayout
  -(void)awakeFromNib{
      self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
  
  }
  -(id)init
  {
      if (!(self = [super init])) return nil;
      self.itemSize = CGSizeMake(60.0, 200.0);
      self.sectionInset = UIEdgeInsetsMake(0, 60, 0, 60);
      self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
      return self;
  }
  - (id)initWithCoder:(NSCoder *)aDecoder {
      self = [super initWithCoder:aDecoder];
      if (self) {
          self.itemSize = CGSizeMake(60.0, 200.0);
          self.sectionInset = UIEdgeInsetsMake(0, 60, 0, 60);
          self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
      }
      return self;
  }
  
  -(void)prepareLayout
  {
      [super prepareLayout];
  
      CGSize size = self.collectionView.frame.size;
      _cellCount = [[self collectionView] numberOfItemsInSection:0];
      _center = CGPointMake(size.width, size.height);
      _radius = MIN(size.width, size.height)/1.3f;
  
  }
  
  -(CGSize)collectionViewContentSize
  {
      return [self collectionView].frame.size;
  }
  
  - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path
  {
      UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path];
      attributes.size = CGSizeMake(ITEM_SIZE, ITEM_SIZE);
      attributes.center = CGPointMake(_center.x + _radius * cosf(2 * path.item * M_PI / _cellCount),
                                      _center.y + _radius * sinf(2 * path.item * M_PI / _cellCount));
      return attributes;
  }
  
  -(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
  {
      NSMutableArray* attributes = [NSMutableArray array];
      for (NSInteger i=0 ; i &lt; self.cellCount; i++) {
          NSIndexPath* indexPath = [NSIndexPath indexPathForItem:i inSection:0];
          [attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
      }
      return attributes;
  }
  
  
  
  - (void)prepareForCollectionViewUpdates:(NSArray *)updateItems
  {
      // Keep track of insert and delete index paths
      [super prepareForCollectionViewUpdates:updateItems];
  
      self.deleteIndexPaths = [NSMutableArray array];
      self.insertIndexPaths = [NSMutableArray array];
  
      for (UICollectionViewUpdateItem *update in updateItems)
      {
          if (update.updateAction == UICollectionUpdateActionDelete)
          {
              [self.deleteIndexPaths addObject:update.indexPathBeforeUpdate];
          }
          else if (update.updateAction == UICollectionUpdateActionInsert)
          {
              [self.insertIndexPaths addObject:update.indexPathAfterUpdate];
          }
      }
  }
  
  - (void)finalizeCollectionViewUpdates
  {
      [super finalizeCollectionViewUpdates];
      // release the insert and delete index paths
      self.deleteIndexPaths = nil;
      self.insertIndexPaths = nil;
  }
  
  // Note: name of method changed
  // Also this gets called for all visible cells (not just the inserted ones) and
  // even gets called when deleting cells!
  - (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
  {
      // Must call super
      UICollectionViewLayoutAttributes *attributes = [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];
  
      if ([self.insertIndexPaths containsObject:itemIndexPath])
      {
          // only change attributes on inserted cells
          if (!attributes)
              attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];
  
          // Configure attributes ...
          attributes.alpha = 0.0;
          attributes.center = CGPointMake(_center.x, _center.y);
      }
  
      return attributes;
  }
  
  // Note: name of method changed
  // Also this gets called for all visible cells (not just the deleted ones) and
  // even gets called when inserting cells!
  - (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
  {
      // So far, calling super hasn't been strictly necessary here, but leaving it in
      // for good measure
      UICollectionViewLayoutAttributes *attributes = [super finalLayoutAttributesForDisappearingItemAtIndexPath:itemIndexPath];
  
      if ([self.deleteIndexPaths containsObject:itemIndexPath])
      {
          // only change attributes on deleted cells
          if (!attributes)
              attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];
  
          // Configure attributes ...
          attributes.alpha = 0.0;
          attributes.center = CGPointMake(_center.x, _center.y);
          attributes.transform3D = CATransform3DMakeScale(0.1, 0.1, 1.0);
      }
  
      return attributes;
  }
  - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
      return YES;
  }
  @end
  </code></pre>
  
  <p>`</p>