title: UICollectionView with overlapping cells and custom insertion and deletion animations
body: <p>I'm working on a custom UICollectionView + Layout where the cells overlap on top of each other. On top of this, I'm implementing custom animations for the addition and removal of items.</p>
  
  <p>Everything's working fine, except the <code>zIndex</code> property of the attributes seem to be ignored during insertion/deletion of items.</p>
  
  <p>Proper cells:
  <a href="https://i.stack.imgur.com/Ptonu.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Ptonu.png" alt="Proper cells"></a></p>
  
  <p>After inserting some cells:
  <a href="https://i.stack.imgur.com/RXYMR.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/RXYMR.png" alt="Cells with improper z order"></a></p>
  
  <p>Here's my implementation for custom insertion/deletion animations. My guess is the problem is somewhere in these methods.</p>
  
  <pre><code>override func initialLayoutAttributesForAppearingItemAtIndexPath(itemIndexPath: NSIndexPath) -&gt; UICollectionViewLayoutAttributes? {
      let attributes = layoutAttributesForItemAtIndexPath(itemIndexPath)
  
      for updateItem in updateItems {
          switch updateItem.updateAction {
          case .Insert:
              if updateItem.indexPathAfterUpdate == itemIndexPath {
                  let translation = collectionView!.bounds.height
                  attributes?.transform = CGAffineTransformMakeTranslation(0, translation)
                  break
              }
          default:
              break
          }
      }
  
      return attributes
  }
  
  override func finalLayoutAttributesForDisappearingItemAtIndexPath(itemIndexPath: NSIndexPath) -&gt; UICollectionViewLayoutAttributes? {
      for updateItem in updateItems {
          switch updateItem.updateAction {
          case .Delete:
              if updateItem.indexPathBeforeUpdate == itemIndexPath {
                  let attributes = layoutAttributesForItemAtIndexPath(itemIndexPath)
                  let translation = collectionView!.bounds.height
                  attributes?.transform = CGAffineTransformMakeTranslation(0, translation)
                  return attributes
              }
          case .Move:
              if updateItem.indexPathBeforeUpdate == itemIndexPath {
                  return layoutAttributesForItemAtIndexPath(updateItem.indexPathAfterUpdate!)
              }
          default:
              break
          }
      }
      let finalIndex = finalIndexForIndexPath(itemIndexPath)
      let shiftedIndexPath = NSIndexPath(forItem: finalIndex, inSection: itemIndexPath.section)
  
      return layoutAttributesForItemAtIndexPath(shiftedIndexPath)
  }
  
  private func finalIndexForIndexPath(indexPath: NSIndexPath) -&gt; Int {
      var newIndex = indexPath.item
      for updateItem in updateItems {
          switch updateItem.updateAction {
          case .Insert:
              if updateItem.indexPathAfterUpdate!.item &lt;= newIndex {
                  newIndex += 1
              }
          case .Delete:
              if updateItem.indexPathBeforeUpdate!.item &lt; newIndex {
                  newIndex -= 1
              }
          case .Move:
              if updateItem.indexPathBeforeUpdate!.item &lt; newIndex {
                  newIndex -= 1
              }
              if updateItem.indexPathAfterUpdate!.item &lt;= newIndex {
                  newIndex += 1
              }
          default:
              break
          }
      }
      return newIndex
  }
  </code></pre>
  
  <p>Things I've tried:</p>
  
  <ul>
  <li>Setting the <code>zIndex</code> in the <code>initialLayoutAttributes...</code> method to the value it will end up being.</li>
  <li>Making the collection view manually reorder the cells after the animation (which is pretty hacky, and I'd like to avoid this, since it can cause some weird behaviour sometimes).</li>
  <li>Calling <code>super.initialLayoutAttributes...</code> etc and modifying the attributes returned from that. The issue with that is it does not handle the other cells shifting when a new one is inserted; instead the cells fade in and out.</li>
  </ul>
  
  <p>A small reproducer of the project can be found on <a href="https://github.com/mpdifran/OverlapCollectionView" rel="nofollow noreferrer">my GitHub</a>. Feel free to clone it and play around with it.</p>