IGListKit
IGListKit copied to clipboard
App crash whenever adding left/right contentInset in UICollectionView.
App is crashing whenever giving left and right contentInset to UICollectionView.
collectionView.contentInset = UIEdgeInsets(
top: view.safeAreaInsets.top + 20,
left: 16,
bottom: tabbarHeight + miniplayerHeight + 20,
right: 16
)
Error:
*** Assertion failure in -[IGListCollectionViewLayout _calculateLayoutIfNeeded](),
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Width of item 0 in section 10 (414 pt) must be less than or equal to container (382 pt) accounting for section insets {0, 0, 0, 0}'
*** First throw call stack:
(
0 CoreFoundation 0x000000010c6568db __exceptionPreprocess + 331
1 libobjc.A.dylib 0x000000010bbf9ac5 objc_exception_throw + 48
2 CoreFoundation 0x000000010c656662 +[NSException raise:format:arguments:] + 98
3 Foundation 0x0000000107189834 -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:] + 166
4 IGListKit 0x0000000107848349 -[IGListCollectionViewLayout _calculateLayoutIfNeeded] + 4489
5 IGListKit 0x0000000107846ebc -[IGListCollectionViewLayout prepareLayout] + 44
6 UIKitCore 0x00000001150ed5a8 -[UICollectionViewData _prepareToLoadData] + 212
7 UIKitCore 0x00000001150cc9a2 -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:] + 12464
8 UIKitCore 0x00000001150d5f24 -[UICollectionView _endUpdatesWithInvalidationContext:tentativelyForReordering:animator:] + 71
9 UIKitCore 0x00000001150d6267 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:animator:] + 434
10 UIKitCore 0x00000001150d6092 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:] + 90
11 UIKitCore 0x00000001150d6015 -[UICollectionView _performBatchUpdates:completion:invalidationContext:] + 74
12 UIKitCore 0x00000001150d5f6a -[UICollectionView performBatchUpdates:completion:] + 53
13 IGListKit 0x0000000107830991 __62-[IGListAdapterUpdater performBatchUpdatesWithCollectionView:]_block_invoke.115 + 481
14 IGListKit 0x000000010782f237 -[IGListAdapterUpdater performBatchUpdatesWithCollectionView:] + 5559
15 IGListKit 0x0000000107833071 __55-[IGListAdapterUpdater _queueUpdateWithCollectionView:]_block_invoke + 401
16 libdispatch.dylib 0x000000010d7ced7f _dispatch_call_block_and_release + 12
17 libdispatch.dylib 0x000000010d7cfdb5 _dispatch_client_callout + 8
18 libdispatch.dylib 0x000000010d7dd080 _dispatch_main_queue_callback_4CF + 1540
19 CoreFoundation 0x000000010c5bda79 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
20 CoreFoundation 0x000000010c5b8126 __CFRunLoopRun + 2310
21 CoreFoundation 0x000000010c5b74d2 CFRunLoopRunSpecific + 626
22 GraphicsServices 0x000000010ed632fe GSEventRunModal + 65
23 UIKitCore 0x000000011583bfc2 UIApplicationMain + 140
24 DRC 0x000000010302e2fb main + 75
25 libdyld.dylib 0x000000010d844541 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Scenario: I've to display two sections in each row where as my collection view leading and trailing is bind to super view. While presenting, the list should have leading and tailing margin.
Question: What is the best way to adding left and right content insets to collection view?
Current working solution:
override func sectionController(_ section: ListBindingSectionController<ListDiffable>,
viewModelsFor object: ListDiffable) -> [ListDiffable] {
if section.section % 2 == 0 {
inset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 0)
} else {
inset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 16)
}
return [ViewModel(item: object)]
}
Not sure, Whether this is the correct solution or hack.
@tarunbhutani any chance you can create a sample project that demonstrates this issue and post a link here so I can take a look?
For what it's worth I'm running into this issue too. My scenario is a bit different though.
A: Portrait collection view/IGListKit B: Landscape collection view/IGListKit
When A does a UIWindow transition -> B B updates the orientation lock and auto rotate spins the view into landscape.
When B dismisses/tells the coordinator to return to A the collection view within A will sometimes throw this error
*** Assertion failure in -[IGListCollectionViewLayout _calculateLayoutIfNeeded](), /Pods/IGListKit/Source/IGListCollectionViewLayout.mm:527
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Width of item 0 in section 0 (414 pt) must be less than or equal to container (392 pt) accounting for section insets {0, 0, 0, 0}'
Whats weird is it only happens ~5-10% of the time, and it's definitely happening while the auto rotate is being executed by the system and viewDidLoad is called inside controller A.
B is setup like this:
override public var shouldAutorotate: Bool {
switch UIDevice.current.orientation() {
case .landscapeRight: return false
default: return true
}
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscapeRight
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .landscapeRight
}
And A has the same but portrait.
I have the same problem with that assertion our project was written by another programmer so I unlock library and comment this assertion in IGListCollectionViewLayout.mm lines 519-527
I couldn't find which Controller has that problem :|
I'm seeing the same issue on the latest release and also building from master
directly.
@tarunbhutani / @HamidZandi I don't suppose you were able to get to the bottom of this at all please?
I'm building against iOS 12 through to the latest beta. I can try and find some time to put together an app that replicates this over the next few days.
Did anyone found solution for this particular issue?
I have the same problem after updated from iOS 13 to 14.
To anyone that is facing this issue: Please check your sections' func sizeForItem(at index: Int) -> CGSize
to see if you are using collectionContext.containerSize.width
or something similar. Because containerSize
does not take insets into account and will request a size from collection view which will not be available to it (hence, the assertion)!
You can do something like this (in your section):
var cellWidth: CGFloat {
collectionContext.containerSize.width - (self.inset.left + self.inset.right)
}
var cellHeight: CGFloat {
// calculate your height
}
override func sizeForItem(at index: Int) -> CGSize {
CGSize(width: cellWidth, height: cellHeight)
}
p.s.: for some reasons unknown to me, collectionContext.insetContainerSize
does not work properly or, I'm not using it right.