0

I've been noticing a crash with UICollectionViewCompositionalLayout while adding a sticky header to the collection view using NSCollectionLayoutBoundarySupplementaryItem through UICollectionViewCompositionalLayoutConfiguration.

These grid view header items are all pinned to the visible bounds via pinToVisibleBounds property to make them sticky while scrolling through rows.

Here's the crash

2022-04-09 00:28:56.335279-0700 *****[88274:5668805] *** Assertion failure in CGRect _UIPinnedFrameForFrameWithContainerFrameVisibleFrame(CGRect, CGRect, CGRect, NSRectAlignment)(), _UICollectionLayoutHelpers.m:688
2022-04-09 00:28:56.341980-0700 ******[88274:5668805] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Frame {{377, 0}, {0, 627}} does not intersect {{377, 0}, {0, 627}}'
*** First throw call stack:
(
    0  CoreFoundation           0x000000010aa45d44 __exceptionPreprocess + 242
    1  libobjc.A.dylib           0x0000000107671a65 objc_exception_throw + 48
    2  Foundation             0x00000001089357d9 -[NSMutableDictionary(NSMutableDictionary) classForCoder] + 0
    3  UIKitCore              0x00000001187a09cb _UIPinnedNonOverlappingFramesForContentFrameVisibleFrame + 3154
    4  UIKitCore              0x00000001187b7ff4 -[_UICollectionLayoutAuxillaryItemSolver _solveForPinning:visibleRect:] + 5748
    5  UIKitCore              0x00000001187824ed -[_UICollectionCompositionalLayoutSolver updatePinnedSectionSupplementaryItemsForVisibleBounds:] + 723
    6  UIKitCore              0x000000011877e542 -[UICollectionViewCompositionalLayout _updatePinnedSectionSupplementaryItemsForCurrentVisibleBounds] + 381
    7  UIKitCore              0x000000011877f148 -[UICollectionViewCompositionalLayout _solveForPinnedSupplementaryItemsIfNeededWithContext:] + 121
    8  UIKitCore              0x000000011877a203 -[UICollectionViewCompositionalLayout invalidateLayoutWithContext:] + 802
    9  UIKitCore              0x000000011888770d -[UICollectionViewLayout _invalidateLayoutUsingContext:] + 56
    10 UIKitCore              0x00000001188202e5 -[UICollectionView setBounds:] + 757
    11 UIKitCore              0x0000000119713ab2 -[UIScrollView setContentOffset:] + 1047
    12 UIKitCore              0x0000000118839f2e -[UICollectionView setContentOffset:] + 42
    13 UIKitCore              0x0000000119728b6e -[UIScrollView _smoothScrollSyncWithUpdateTime:] + 3152
    14 UIKitCore              0x0000000119727b55 -[UIScrollView _smoothScrollWithUpdateTime:] + 313
    15 UIKitCore              0x0000000119728f06 -[UIScrollView _smoothScrollDisplayLink:] + 613
    16 QuartzCore             0x0000000113937474 _ZN2CA7Display11DisplayLink14dispatch_itemsEyyy + 932
    17 QuartzCore             0x0000000113a369c6 _ZL22display_timer_callbackP12__CFMachPortPvlS1_ + 395
    18 CoreFoundation           0x000000010a97eb42 __CFMachPortPerform + 157
    19 CoreFoundation           0x000000010a9b3125 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
    20 CoreFoundation           0x000000010a9b24cc __CFRunLoopDoSource1 + 617
    21 CoreFoundation           0x000000010a9ac901 __CFRunLoopRun + 2420
    22 CoreFoundation           0x000000010a9aba90 CFRunLoopRunSpecific + 562
    23 GraphicsServices          0x0000000110617c8e GSEventRunModal + 139
    24 UIKitCore              0x00000001191e490e -[UIApplication _run] + 928
    25 UIKitCore              0x00000001191e9569 UIApplicationMain + 101
    26 SEAnalyticsSDKSample        0x0000000106ec8b05 main + 229
    27 dyld                0x0000000107140f21 start_sim + 10
    28 ???                 0x000000011063d51e 0x0 + 4569945374
)
libc++abi: terminating with uncaught exception of type NSException

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Frame {{377, 0}, {0, 627}} does not intersect {{377, 0}, {0, 627}}'
terminating with uncaught exception of type NSException

Here's the rough implementation:

  func layout() -> UICollectionViewLayout {
    UICollectionViewCompositionalLayout(sectionProvider: { [self] section, _ in
      // Building section here 
    }, configuration: configuration)
  }
     
  var configuration: UICollectionViewCompositionalLayoutConfiguration {
    let configuration = UICollectionViewCompositionalLayoutConfiguration()

    var boundaryItems: [NSCollectionLayoutBoundarySupplementaryItem] = []

    var offset = 0
    for column in 0..<datasource.numberOfColumns {
      let columnHeaderSize = NSCollectionLayoutSize(widthDimension: .absolute(100), heightDimension: .absolute(44))

      let headerView = NSCollectionLayoutBoundarySupplementaryItem(
        layoutSize: columnHeaderSize,
        elementKind: "columnHeader",
        alignment: .topLeading,
        absoluteOffset: CGPoint(x: offset, y: 0)
      )

      headerView.pinToVisibleBounds = true
      headerView.zIndex = 2
       
      offset += 100.0
      boundaryItems.append(headerView)
    } 

    configuration.boundarySupplementaryItems = boundaryItems
    return configuration
  }

I'm trying to understand what is causing this crash and how to prevent this crash from happening..

Prasad
  • 166
  • 7

1 Answers1

0

Looks like this crash is happening when there are no items in the collection view and you scroll the global header out of the viewport. In my case, setting alwaysBounceVertical to false when there are no items and back to true when collection view has items to display right before applying the data from the snapshot to the diffable data source helped to fix the issue:

collectionView.alwaysBounceVertical = !collectionViewItems.isEmpty
Bobby
  • 176
  • 1
  • 4
  • Interesting!! I believe i was working with static content,.. this is happening for me while scrolling around the global header after the items were loaded... – Prasad Jun 16 '22 at 18:09