Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using setCollectionViewLayout leads to crash , says layoutAttributesForItemAtIndexPath not found

I am having a collection Views and I have to change the layout of the collection view dynamically.On setting the new layout , the application crashes with the log ,

2016-02-15 13:47:31.663 PhotoBoard[92347:5235792] *** Assertion failure in -[UICollectionViewData layoutAttributesForItemAtIndexPath:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.30.14/UICollectionViewData.m:666

2016-02-15 13:47:31.666 PhotoBoard[92347:5235792] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no UICollectionViewLayoutAttributes instance for -layoutAttributesForItemAtIndexPath: {length = 2, path = 0 - 0}' * First throw call stack: ( 0 CoreFoundation 0x000000010d94de65 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x000000010f8b5deb objc_exception_throw + 48 2 CoreFoundation 0x000000010d94dcca +[NSException raise:format:arguments:] + 106 3 Foundation 0x000000010dfbe4de -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 198 4 UIKit 0x000000010ec4161c -[UICollectionViewData layoutAttributesForItemAtIndexPath:] + 627 5 UIKit 0x000000010ebeee24 -[UICollectionView _setCollectionViewLayout:animated:isInteractive:completion:] + 1606 6 UIKit 0x000000010ebee4db -[UICollectionView setCollectionViewLayout:] + 318

On printing the layout attributes I see one layout attribute item for the layoutAttributesForItemAtIndexPath: {length = 2, path = 0 - 0}' , I see an entry in the layout , so not sure why the layout attribute cannot be found ,

Attributes index path: ( {length = 2, path = 0 - 0}); frame = (6 293; 298 403.695);

Attributes index path: ( {length = 2, path = 0 - 1}); frame = (6 293; 298 408.695);

Attributes index path: ( {length = 2, path = 0 - 2}); frame = (6 293; 298 418.695);

Attributes index path: ( {length = 2, path = 0 - 3}); frame = (6 293; 298 433.695);

Attributes index path: ( {length = 2, path = 0 - 4}); frame = (6 293; 298 453.695);

Attributes index path: ( {length = 2, path = 0 - 5}); frame = (6 293; 298 478.695);

Attributes index path: ( {length = 2, path = 0 - 6}); frame = (6 293; 298 508.695);

Attributes index path: ( {length = 2, path = 0 - 7}); frame = (6 293; 298 543.695);

Attributes index path: ( {length = 2, path = 0 - 8}); frame = (6 293; 298 583.695);

Attributes index path: ( {length = 2, path = 0 - 9}); frame = (6 293; 298 628.695);

Attributes index path: ( {length = 2, path = 0 - 10}); frame = (6 293; 298 678.695);

Attributes index path: ( {length = 2, path = 0 - 11}); frame = (6 293; 298 733.695);

Attributes index path: ( {length = 2, path = 0 - 12}); frame = (6 293; 298 793.695);

Attributes index path: ( {length = 2, path = 0 - 13}); frame = (6 293; 298 858.695);

Attributes index path: ( {length = 2, path = 0 - 14}); frame = (6 293; 298 928.695);

Attributes index path: ( {length = 2, path = 0 - 15}); frame = (6 293; 298 1003.69);

This is how I am setting the new custom layout ,

 self.collectionView!.collectionViewLayout = self.stackLayout
        self.stackLayout.delegate = self
        self.collectionView!.collectionViewLayout.invalidateLayout()
        self.collectionView!.setCollectionViewLayout(self.stackLayout,   animated:true)
        self.collectionView?.reloadData()

If I load the two custom layouts statically they work fine , the crash happens only when the layout is changed dynamically.

like image 367
Vinodha Sundaramoorthy Avatar asked Oct 19 '22 15:10

Vinodha Sundaramoorthy


1 Answers

I had the same problem and this solves my problem.

If you are using multiple custom layouts for switching, then override the following methods in both custom layout classes,

 - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
 - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath

Example for Swift:

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
    return cache[indexPath.item]
}

Example for Objective C:

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{ 
   return self.cache[indexPath.item];
}

HAPPY CODING..!

like image 131
Manivel Nagarajan Avatar answered Oct 21 '22 04:10

Manivel Nagarajan