title: NSInternalInconsistencyException', reason: 'no UICollectionViewLayoutAttributes instance for -layoutAttributesForItemAtIndexPath, custom layout
body: <p>I have a UICollectionView with a custom UICollectionLayout. It all works fine, until I try to insert a row…</p>
  
  <p>Then I get the following error and can't seem to figure out how to solve it.</p>
  
  <pre><code>*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no UICollectionViewLayoutAttributes instance for -layoutAttributesForItemAtIndexPath: &lt;NSIndexPath: 0xc000000000000016&gt; {length = 2, path = 0 - 0}'
  *** First throw call stack:
  (
  0   CoreFoundation                      0x000000010915ae65 __exceptionPreprocess + 165
  1   libobjc.A.dylib                     0x0000000108789deb objc_exception_throw + 48
  2   CoreFoundation                      0x000000010915acca +[NSException raise:format:arguments:] + 106
  3   Foundation                          0x000000010591a4de -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 198
  4   UIKit                               0x00000001073e361c -[UICollectionViewData layoutAttributesForItemAtIndexPath:] + 627
  5   UIKit                               0x00000001073a2859 __51-[UICollectionView _viewAnimationsForCurrentUpdate]_block_invoke1541 + 176
  6   UIKit                               0x00000001073a02ed -[UICollectionView _viewAnimationsForCurrentUpdate] + 4524
  7   UIKit                               0x00000001073a4a5c __62-[UICollectionView _updateWithItems:tentativelyForReordering:]_block_invoke1611 + 197
  8   UIKit                               0x0000000106be01b8 +[UIView(Animation) performWithoutAnimation:] + 65
  9   UIKit                               0x00000001073a3e07 -[UICollectionView _updateWithItems:tentativelyForReordering:] + 3241
  10  UIKit                               0x000000010739eb98 -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:] + 15556
  11  UIKit                               0x00000001073a5ee7 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:] + 415
  12  UIKit                               0x00000001073a5d25 -[UICollectionView _performBatchUpdates:completion:invalidationContext:] + 74
  13  UIKit                               0x00000001073a5cc8 -[UICollectionView performBatchUpdates:completion:] + 53
  14  Qanda                               0x0000000103d9e0d9 _TFC5Qanda32HomeFeedCollectionViewController22redrawViewAfterNewDatafS0_FGSaCS_10QandaModel_T_ + 4105
  15  Qanda                               0x0000000103dad5ca _TFFFC5Qanda32HomeFeedCollectionViewController9fetchDataFS0_FT_T_U_FTGSqGSaCS_10QandaModel__Sb_T_U0_FT_T_ + 1274
  16  Qanda                               0x0000000103afc6b7 _TTRXFo__dT__XFdCb__dT__ + 39
  17  libdispatch.dylib                   0x0000000109dd7e5d _dispatch_call_block_and_release + 12
  18  libdispatch.dylib                   0x0000000109df849b _dispatch_client_callout + 8
  19  libdispatch.dylib                   0x0000000109de02af _dispatch_main_queue_callback_4CF + 1738
  20  CoreFoundation                      0x00000001090bad09 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
  21  CoreFoundation                      0x000000010907c2c9 __CFRunLoopRun + 2073
  22  CoreFoundation                      0x000000010907b828 CFRunLoopRunSpecific + 488
  23  GraphicsServices                    0x000000010c171ad2 GSEventRunModal + 161
  24  UIKit                               0x0000000106b34610 UIApplicationMain + 171
  25  Qanda                               0x0000000103bb537d main + 109
  26  libdyld.dylib                       0x0000000109e2c92d start + 1
  )
  libc++abi.dylib: terminating with uncaught exception of type NSException
  </code></pre>
  
  <p>Here is the code for my layout:</p>
  
  <pre><code>var numberOfColumns: Int = 1
  let cellPadding: CGFloat = 10
  let buttonContainerHeight: CGFloat = 50
  let DEFAULT_HEIGHT: CGFloat = 80
  
  private var contentWidth: CGFloat = UIScreen.mainScreen().bounds.width
  private var totalContentHeight: CGFloat  = 0.0
  
  // Delegate
  var delegate: HomeFeedCollectionViewLayoutDelegate?
  
  
  var cache = [UICollectionViewLayoutAttributes]()
  
  
  override func prepareLayout() {
  
      // If cache is empty, calculate the layout
      if cache.isEmpty {
          // Set the size
          let columnWidth = contentWidth / CGFloat(numberOfColumns)
          var contentHeight: CGFloat  = 0.0
          var column = 0
          let xOffset: CGFloat = 0
          var yOffset: CGFloat = 0
          var yOffsetArray = [CGFloat]()
  
          // First check if sections actually exist
          if collectionView!.numberOfSections() &gt; 0 {
  
              // Loop through items in section
              for item in 0 ..&lt; collectionView!.numberOfItemsInSection(0) {
  
                  let indexPath = NSIndexPath(forItem: item, inSection: 0)
                  let width = columnWidth - cellPadding * 2
  
                  let questionHeight = delegate?.collectionView(collectionView!, heightForQuestionAtIndexPath: indexPath, withWidth:width)
  
  
                  // Calculate frame
                  var height: CGFloat!
  
                  if questionHeight &gt; 0 {
                      height = DEFAULT_HEIGHT + buttonContainerHeight + questionHeight! + 10
                  }
                  else {
                      height = contentWidth + buttonContainerHeight
                  }
  
  
                  if yOffsetArray.isEmpty {
                      log.debug("yOffsetArray is EMPTY")
                  }
                  else {
                      yOffset = yOffsetArray[item - 1] - cellPadding
                  }
  
                  yOffsetArray.append(height + yOffset)
  
  
                  let frame = CGRect(x: xOffset, y: yOffset, width: columnWidth, height: height)
                  let insetFrame = CGRectInset(frame, cellPadding, cellPadding)
  
                  // Create instance of UICollectionViewLayoutAttribute &amp; set insetFrame
                  let attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
                  attributes.frame = insetFrame
                  cache.append(attributes)
  
                  // Make content height
                  contentHeight = contentHeight + (height - cellPadding)
  
                  column = column &gt;= (numberOfColumns - 1) ? 0 : ++column
  
              }
  
              self.totalContentHeight = contentHeight
  
          }
  
      }
  
  }
  
  
  override func collectionViewContentSize() -&gt; CGSize {
      return CGSize(width: UIScreen.mainScreen().bounds.width, height: self.totalContentHeight + cellPadding)
  }
  
  
  override func layoutAttributesForElementsInRect(rect: CGRect) -&gt; [UICollectionViewLayoutAttributes]? {
      var layoutAttributes = [UICollectionViewLayoutAttributes]()
  
      for attributes in cache {
          if CGRectIntersectsRect(attributes.frame, rect) {
              layoutAttributes.append(attributes)
          }
      }
      return layoutAttributes
  }
  </code></pre>
  
  <p><strong>EDIT</strong>: Narrowing down the root of the error, it seems like the UICollectionViewLayoutAttributes returned are only updated to the correct new value if the CV is reloaded first. However, if I do so the batch update throws an error saying the total number of rows AFTER should be equal to before plus the number inserted… which makes sense.</p>
  
  <p><strong>EDIT 2</strong>: Now I am at a loss. Is the batch update trying to retrieve the layout from the default layout and not my custom layout?</p>
  
  <pre><code>layoutAttributesForElementsInRect = [&lt;UICollectionViewLayoutAttributes: 0x7ffc1d8baf70&gt; index path: (&lt;NSIndexPath: 0xc000000000000016&gt; {length = 2, path = 0 - 0}); frame = (10 10; 355 405); , &lt;UICollectionViewLayoutAttributes: 0x7ffc1d8a5930&gt; index path: (&lt;NSIndexPath: 0xc000000000200016&gt; {length = 2, path = 0 - 1}); frame = (10 425; 355 143.222); , &lt;UICollectionViewLayoutAttributes: 0x7ffc1d837240&gt; index path: (&lt;NSIndexPath: 0xc000000000400016&gt; {length = 2, path = 0 - 2}); frame = (10 578.222; 355 143.222); [...] &lt;UICollectionViewLayoutAttributes: 0x7ffc1d8d02f0&gt; index path: (&lt;NSIndexPath: 0xc000000002600016&gt; {length = 2, path = 0 - 19}); frame = (10 3229.44; 355 143.222); ]
  
   *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no UICollectionViewLayoutAttributes instance for -layoutAttributesForItemAtIndexPath: &lt;NSIndexPath: 0xc000000000200016&gt; {length = 2, path = 0 - 1}'
  </code></pre>
  
  <p>How is this possible?</p>