现状
在开发中,由于自定义了
UICollectionViewLayout
,使用默认的iOS11模拟器进行调试,为了在适配设置内容后内容位置不错乱,手动调用了如下语句:
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionTop animated:NO];
结果在iOS11的真机和模拟器上都没有任何问题,但在iOS10的真机和模拟器上却会因为在操作非常快速或正常操作时偶尔也会出现crash的bug
Assertion failure in -[UICollectionViewData layoutAttributesForItemAtIndexPath:]
解决方案
根据提示的内容重写layoutAttributesForItemAtIndexPath
方法,
@interface CustomeLayout()
@property (nonatomic,strong) NSMutableArray *attributes;
@property (nonatomic,assign) NSInteger itemCount;
@end
@implementation TrendNumLayout
- (void)prepareLayout{
_attributes = [NSMutableArray array];
[super prepareLayout];
_itemCount = [self.collectionView numberOfSections];
CGFloat lineWidth = 1.0f;
CGFloat lineHeight = 1.0f;
for (NSInteger rowIndex = 0; rowIndex < _itemCount; rowIndex ++) {
// 一组里有多少列
NSInteger colCount = [self.collectionView numberOfItemsInSection:rowIndex];
for (NSInteger colIndex = 0; colIndex < colCount; colIndex ++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:colIndex inSection:rowIndex];
UICollectionViewLayoutAttributes *pAttri = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
CGFloat x = 0;
CGFloat y = 0;
// 每个item的宽高
x = colIndex * (self.itemSize.width+lineWidth);
y = rowIndex * (self.itemSize.height+lineHeight);
CGFloat width = self.itemSize.width;
if (colCount == 1) {
// 只有一行,则该cell展示位满行
width = self.cols*(lineWidth + self.itemSize.width)-lineWidth;
}
pAttri.frame = CGRectMake(x, y, width, self.itemSize.height);
[_attributes addObject:pAttri];
}
}
}
// 设置内容区域的大小
- (CGSize)collectionViewContentSize{
// sections
NSInteger sec = [self.collectionView numberOfSections];
CGFloat lineWidth = 1;
return CGSizeMake(self.cols * (self.itemSize.width+lineWidth)-lineWidth, sec * (self.itemSize.height + 1));
}
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
return _attributes;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes *attrs = [super layoutAttributesForItemAtIndexPath:indexPath];
if (attrs == nil && indexPath.section==0 && indexPath.item == 0) {
attrs = self.attributes.firstObject;
}
return attrs;
}
@end
网友评论