简体   繁体   English

滚动后,UICollectionView对单元格进行重新排序

[英]UICollectionView reorder cells after scrolling

I have added this UICollectionViewDelegate with my implementation: 我在实现中添加了此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;
}

In my custom cell I have this method: 在我的自定义单元格中,我有以下方法:

- (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];

            });
        });
    }
}

So as you can see if the cell does not have UIImageView then I start to create it and in background I get image from local path and resize it to cell content view width, then in main queue I set image to UIImageView. 因此,如您所见,如果单元格没有UIImageView,那么我开始创建它,然后在后台从本地路径获取图像并将其大小调整为单元格内容视图宽度,然后在主队列中将图像设置为UIImageView。

This part work good but when I try to scroll my UICollectionView eg with 10 images I noticed that for example if first 2 top images were disappeared when I scroll down and then when I scroll back to the top, the images are changed placed. 这部分效果很好,但是当我尝试滚动带有10张图像的UICollectionView时,例如,当我向下滚动然后再滚动回到顶部时,如果前2张顶部图像消失了,则图像会更改放置。

This is state of images before scrolling down: 这是向下滚动之前的图像状态:

在此处输入图片说明

And this state after I scroll UIColectionView back to the top: 然后将UIColectionView滚动回到顶部后的这种状态:

在此处输入图片说明

So as you can see first to item changed theirs location. 因此,如您所见,首先要更改项目的位置。 As I have set if (!self.imageView) in my code above it should means that the image never will be created twice or more times. 正如我在上面的代码中设置if (!self.imageView) ,它应该意味着图像永远不会创建两次或多次。

I opened debugger and was checking this method: 我打开调试器,正在检查此方法:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

So the images paths returned one by one as it worked when UICollectionView just created cells at first time. 因此,当UICollectionView第一次创建单元格时,图像路径会按其工作方式逐一返回。

At first time first UICollectionViewCell has 0x8fbc1d0 and second has 0x8d0a4c0 address 第一次,第一个UICollectionViewCell具有0x8fbc1d0,第二个具有0x8d0a4c0地址

But when I scroll down and then scroll up the debugger shown me second address at first 0x8d0a4c0 and then shown me 0x8fbc1d0 但是,当我向下滚动然后向上滚动时,调试器在第一个0x8d0a4c0给我显示第二个地址,然后向我显示0x8fbc1d0

But I can't understand why items change theirs order. 但是我不明白为什么物品会改变顺序。 Or maybe here is another issue? 也许这是另一个问题?

Also I don't have any method in the code that make for example for me reorder for cell. 另外,我在代码中没有任何方法可以使例如对单元格重新排序。 just few UICollection view methods delegate that configure count of cells and create them. 仅有少数几个UICollection视图方法委托它们配置单元数并创建它们。

Also if I remove if (!self.imageView) seems everything works good, but then my code every time invoke dispatch that's no good for me, because when I resize image to the cell size I don't need do it twice. 另外,如果我删除if (!self.imageView)似乎一切正常,但是每次我的代码都调用dispatch时,这对我来说就没有好处,因为当我将图像调整为单元格大小时,不需要执行两次。

When you scroll the two items off screen, your CollectionView puts the associated cells back onto the 'queue'. 当您在屏幕外滚动两个项目时, CollectionView将关联的单元格放回到“队列”中。 When you scroll back up again, the dequeueResuableCellwithReuseIdentifier in cellForItemAtIndexPath retrieves them from that queue, but (as you've seen) not necessarily in the same order. 当您再次向上滚动时, cellForItemAtIndexPathdequeueResuableCellwithReuseIdentifier将从该队列中检索它们,但(如您所见)不一定以相同的顺序进行。 Thus the cell which was item 0 has been used for item 1 and vice versa. 因此,项目0的单元格已用于项目1,反之亦然。 As you've seen, the if (!self.imageView) actually stops the correct image from being loaded. 如您所见, if (!self.imageView)实际上阻​​止了正确图像的加载。 If you want to avoid retrieving and resizing them each time, then I would store the (resized) imageViews in an array. 如果要避免每次都获取和调整大小,则可以将(调整大小的)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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM