[英]UICollectionView reorder cells after scrolling
我在实现中添加了此UICollectionViewDelegate:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
SAPCollectionViewCell *collectionViewCell = (SAPCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"SAPCollectionViewCell" forIndexPath:indexPath];
NSInteger index = indexPath.item + indexPath.section * 2;
NSString *imagePath = [_images objectAtIndex:index];
collectionViewCell.index = index;
[collectionViewCell setImageWithPath:imagePath];
collectionViewCell.delegateCell = self;
return collectionViewCell;
}
在我的自定义单元格中,我有以下方法:
- (void)setImageWithPath:(NSString *)imagePath
{
if (!self.imageView)
{
CGRect rect = self.contentView.frame;
self.imageView = [[UIImageView alloc] initWithFrame:rect];
[self.contentView addSubview:self.imageView];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *image = [UIImage imageFromPath:imagePath];
UIImage *resizedImage = [UIImage imageWithImage:image scaledToWidth:rect.size.width];
dispatch_async(dispatch_get_main_queue(), ^{
[self.imageView setImage:resizedImage];
});
});
}
}
因此,如您所见,如果单元格没有UIImageView,那么我开始创建它,然后在后台从本地路径获取图像并将其大小调整为单元格内容视图宽度,然后在主队列中将图像设置为UIImageView。
这部分效果很好,但是当我尝试滚动带有10张图像的UICollectionView时,例如,当我向下滚动然后再滚动回到顶部时,如果前2张顶部图像消失了,则图像会更改放置。
这是向下滚动之前的图像状态:
然后将UIColectionView
滚动回到顶部后的这种状态:
因此,如您所见,首先要更改项目的位置。 正如我在上面的代码中设置if (!self.imageView)
,它应该意味着图像永远不会创建两次或多次。
我打开调试器,正在检查此方法:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
因此,当UICollectionView第一次创建单元格时,图像路径会按其工作方式逐一返回。
第一次,第一个UICollectionViewCell具有0x8fbc1d0,第二个具有0x8d0a4c0地址
但是,当我向下滚动然后向上滚动时,调试器在第一个0x8d0a4c0给我显示第二个地址,然后向我显示0x8fbc1d0
但是我不明白为什么物品会改变顺序。 也许这是另一个问题?
另外,我在代码中没有任何方法可以使例如对单元格重新排序。 仅有少数几个UICollection视图方法委托它们配置单元数并创建它们。
另外,如果我删除if (!self.imageView)
似乎一切正常,但是每次我的代码都调用dispatch时,这对我来说就没有好处,因为当我将图像调整为单元格大小时,不需要执行两次。
当您在屏幕外滚动两个项目时, CollectionView
将关联的单元格放回到“队列”中。 当您再次向上滚动时, cellForItemAtIndexPath
的dequeueResuableCellwithReuseIdentifier
将从该队列中检索它们,但(如您所见)不一定以相同的顺序进行。 因此,项目0的单元格已用于项目1,反之亦然。 如您所见, if (!self.imageView)
实际上阻止了正确图像的加载。 如果要避免每次都获取和调整大小,则可以将(调整大小的)imageViews存储在数组中。
- (void)setImageWithPath:(NSString *)imagePath
{
if (!self.imageView)
{
CGRect rect = self.contentView.frame;
self.imageView = [[UIImageView alloc] initWithFrame:rect];
[self.contentView addSubview:self.imageView];
}
if (![self.imagePath isEqualsToString:imagePath] && self.imageView.image == nil)
{
self.imagePath = imagePath;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *image = [UIImage imageFromPath:imagePath];
UIImage *resizedImage = [UIImage imageWithImage:image scaledToWidth:rect.size.width];
dispatch_async(dispatch_get_main_queue(), ^{
if ([self.imagePath isEqualsToString:imagePath])
{
[self.imageView setImage:resizedImage];
}
});
});
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.