[英]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.