NSInternalInconsistencyException', reason: 'no UICollectionViewLayoutAttributes instance for -layoutAttributesForItemAtIndexPath, custom layout
For those who encounter the same issue, I discovered that when you do
self.collectionView?.performBatchUpdates({ () -> Void in
// add new items into collection
self.collectionView?.insertItemsAtIndexPaths(indexPaths)
}, completion: { (finished) -> Void in
// do insertion animations
});
the layoutAttributesForElementsInRect
method is not called and the layoutAttributesForItemAtIndexPath
is called instead.
Therefore, you must also override layoutAttributesForItemAtIndexPath
in the custom layout like so:
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
// Logic that calculates the UICollectionViewLayoutAttributes of the item
// and returns the UICollectionViewLayoutAttributes
return self.singleItemLayout(indexPath)
}
EDIT: Also, if you encounter flicker when the batch insertItemsAtIndexPaths
method on it's own.
Why does my custom UICollectionViewLayout throw an error when adding space between cells?
Found the solution! Apparently overriding layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes?
fixes the issue! But I have no idea why.
UICollectionView exception in UICollectionViewLayoutAttributes from iOS7
You need to invalidate the existing layout before updating, see the end of the error message:
without invalidating the layout'
[collectionViewLayout invalidateLayout];
Apple Documentation for UICollectionViewLayout
Using [UICollectionView performBatchUpdates:] with a UICollectionViewFlowLayout that has UIDynamics
try
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *layoutAttributes = [self.dynamicAnimator layoutAttributesForCellAtIndexPath:indexPath];
if(!layoutAttributes) {
layoutAttributes = [super layoutAttributesForItemAtIndexPath:indexPath];
}
return layoutAttributes;
}
when you execute performBatchUpdates
, [self.dynamicAnimator layoutAttributesForCellAtIndexPath:
returns nil
if cell which will be created by update is not visible.
So just returns super
(perhaps UICollectionViewFlowLayout
)'
s layoutAttributes
for now.
And when the cell about to be displayed, UIDynamicAnimator
will do the job for you.
UICollectionViewLayoutAttributes custom derived class instance is not created
Need to use the generic version of CreateForCell:
UICollectionViewLayout.CreateForCell<CustomLayoutAttributes>(indexPath);
This is because C# doesn't have virtual class methods like Objective-C does so it can't tell in CreateForCell which class you called it on unless you tell it with a type argument.
Related Topics
Changing Tab Bar Color (Swift)
How to Select All Text in a Uitextfield Using Swift
Swift Firestore Check If Documents Exists
Delegate Property with Different Type in Swift
Swiftui: How to Switch to a New Navigation Stack with Navigationviews
Argument of '#Selector' Does Not Refer to an '@Objc' Method, Property or Initializer
Swift 2 Error Handling and While
Xcode Generated Coredata Files Cannot Be Processed by Copy Bundle Resources Build Phase
Gcdasyncsocket Multiple Connections Wont Accept Data from Multiple Sockets
Get All Available Characters from a Font
How to Test Required Init(Coder:)
How to Convert 4 Bytes to a Swift Float
Ambigious Reference to Member Request() Issues with Alamofire After Migration to Swift 3
Swift - Associated Types in Protocol with Where Clause
In Which Cases Arscnview.Raycastquery Returns Nil