iOS 10 UICollectionView 索引不存在问题 UICollectionView received layout attributes for a cell with an index

27 篇文章 0 订阅
4 篇文章 0 订阅

iOS 10 UICollectionView 索引不存在问题 UICollectionView received layout attributes for a cell with an index path that does not exist

报的错误是

截屏2022-02-08 下午12.05.32

解决方法,在reloadData后添加.collectionViewLayout invalidateLayout

[self.tagCollectionView reloadData];
  [self.tagCollectionView.collectionViewLayout invalidateLayout];

分析解决

奇怪的是iOS11及以上的机型是没问题的

我的页面是UITableviewCell 嵌套CollectionView Collectionviewcell嵌套里再嵌套CollectionView,第一个collectionviewCell为固定宽高,第二个CollectionviewCell是高度自适应- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {

///collectionviewcell大小自适应
- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
    CGSize size = [_titleString sizeWithAttributes:@{NSFontAttributeName : self.titleLabel.font}];
    UICollectionViewLayoutAttributes *att = [super preferredLayoutAttributesFittingAttributes:layoutAttributes];
    att.frame = CGRectMake(0, 0, size.width + 12, 14.5);
    return att;
}

断点后,在遍历整体的CollectionView最后一个的collectionviewCell 执行

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {

后直接报错,不会执行cellForItemAtIndexPath

CollectionViewCell因为复用,还保存上一个cell的页面数据,reloadData只是对data的更新,并不会执行cell的preferredLayoutAttributesFittingAttributes就会导致不同数据,但页面显示位置错乱问题,从而报出错误。 iOS11以上reloadData也会对页面的布局进行更新。所以要在reloadData后对cell的重新布局[self.tagCollectionView.collectionViewLayout invalidateLayout];

官方文档

截屏2022-02-08 下午1.49.29

翻译

总结

使当前布局无效并触发布局更新。
公告

-(无效)无效;
讨论

您可以随时调用此方法来更新布局信息。此方法使集合视图本身的布局无效,并立即返回。因此,可以从同一代码块多次调用此方法,而无需触发多个布局更新。实际布局更新发生在下一个视图布局更新周期中。
如果重写此方法,则必须在实现中的某个点调用super
还有种方案解决

for循环添加view,当刷新页面时删除当前view的子view再添加。这个要控制好布局,适用于小型的view。

- (void) setModel:(TGDiscoveryBookModel *)model {
    _model = model;
    // 删除view里的子view
    for (UIView *view in [self.tagCollectionView subviews])
    {
        [view removeFromSuperview];
    }
    self.titleLabel.text = model.name;
    // X轴布局添加
    CGFloat totalWidth = 0;
    [self.coverImage sd_setImageWithURL:HostURLImage(model.coverUrl) placeholderImage:IMAGENANED(@"banner_default")];
    // 逐个添加
    for (int i = 0; i < [self tagsCount]; i++) {
        CGFloat itemWidth = [[NSString stringWithFormat:@"%@",self.model.labels[i]] sizeWithAttributes:@{NSFontAttributeName :  [UIFont fontWithName:kPingfangSC_Medium size:9]}].width + 9;
        
        UILabel *_titleLabel = [[UILabel alloc] init];
        _titleLabel.font = [UIFont fontWithName:kPingfangSC_Medium size:9];
        CGRect rect = CGRectMake(rect.origin.x + 5, rect.origin.y + 5, rect.size.width - 5, rect.size.height -10);
        _titleLabel.textAlignment = NSTextAlignmentCenter;
        [_titleLabel drawTextInRect:rect];
        _titleLabel.layer.borderColor = HEXCOLOR(0xFCA032).CGColor;
        _titleLabel.textColor = HEXCOLOR(0xFCA032);
        _titleLabel.layer.borderWidth = 0.5;
        _titleLabel.layer.cornerRadius = 2;
        _titleLabel.text = model.labels[i];
        _titleLabel.frame = CGRectMake(totalWidth + 7.5, 5, itemWidth, 18);
        [self.tagCollectionView addSubview: _titleLabel];
        
        totalWidth += itemWidth + 7.5;
    }
    
}
///标签显示一行判断多少个
- (NSInteger) tagsCount {
    CGFloat totalWidth = 0;
    NSInteger count = 0;
    for (NSInteger i = 0; i < self.model.labels.count; i++) {
        CGFloat stringFloat = [[NSString stringWithFormat:@"%@",self.model.labels[i]] sizeWithAttributes:@{NSFontAttributeName :  [UIFont fontWithName:kPingfangSC_Medium size:9]}].width + 10;
        totalWidth += stringFloat;
        if (totalWidth < (kScreenWidth - 40)/2 - 20) {
            count ++;
        }else {
            return count;
        }
    }
    return self.model.labels.count;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值