0

当我把 aPHAssetCollection交给PHAsset.fetchAssetsInAssetCollection:options我时,我会得到一个 s 的集合PHAsset。对于每UIImage一个回馈给我,也有一个 nil 值回馈给我。

以下是我的cellForItemAtIndexPath:indexPath方法。

public override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("AssetCellIdentifier", forIndexPath: indexPath) as? AssetCollectionViewCell;

    let asset = self.assetFetchResult!.objectAtIndex(indexPath.row);
    self.imageManager.requestImageForAsset(
        asset as! PHAsset,
        targetSize: CGSize.init(width: asset.pixelWidth, height: asset.pixelHeight),
        contentMode: PHImageContentMode.AspectFill,
        options: nil) { (image, info) -> Void in
            print (image);
            if (image == nil) {
                return;
            }


            cell?.assetThumbnail.contentMode = UIViewContentMode.ScaleAspectFit;
            cell?.assetThumbnail.image = image;
    }

    return cell!;
}

如果我不放零支票

if (image == nil) {
    return;
}

然后 UICollectionView 什么都不渲染。一旦我添加了 nil 检查,集合视图就会开始渲染照片库资产集合中的图像。

为什么返回给我的 nil 数量总是与UIImage对象数量相同?我的请求中有什么我搞砸的吗?

这是我print上面调用的输出。

Optional(<UIImage: 0x12f8263d0>, {40, 30})
Optional(<UIImage: 0x12e5265a0>, {40, 30})
Optional(<UIImage: 0x12e664c90>, {40, 30})
Optional(<UIImage: 0x12e74c860>, {40, 30})
Optional(<UIImage: 0x12e58c580>, {40, 30})
Optional(<UIImage: 0x12e60b6f0>, {40, 30})
Optional(<UIImage: 0x12e7657d0>, {40, 30})
Optional(<UIImage: 0x12e6655e0>, {40, 30})
Optional(<UIImage: 0x12e743ca0>, {40, 30})
Optional(<UIImage: 0x12e5fb6e0>, {40, 30})
Optional(<UIImage: 0x12e5fb8e0>, {40, 30})
Optional(<UIImage: 0x12f85f3b0>, {40, 30})
nil
nil
nil
nil
nil
nil
nil
nil
nil
nil
nil
nil

更新:

似乎这发生在我返回的每个 PHAssetCollection 中。

更新 2:

这是我试图复制的 WWDC 示例中的部分内容。我确实注意到它确实的一件事,但我不是,它是标记单元格,以防止在重复使用时覆盖它。

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    AAPLGridViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellReuseIdentifier forIndexPath:indexPath];

    // Increment the cell's tag
    NSInteger currentTag = cell.tag + 1;
    cell.tag = currentTag;

    PHAsset *asset = self.assetsFetchResults[indexPath.item];
    [self.imageManager requestImageForAsset:asset
                                 targetSize:AssetGridThumbnailSize
                                contentMode:PHImageContentModeAspectFill
                                    options:nil
                              resultHandler:^(UIImage *result, NSDictionary *info) {

        // Only update the thumbnail if the cell tag hasn't changed. Otherwise, the cell has been re-used.
        if (cell.tag == currentTag) {
            cell.thumbnailImage = result;
        }

    }];

    return cell;
}
4

1 回答 1

0

你不能self.imageManager.requestImageForAsset以你在中间调用它的方式调用它cellForItemAtIndexPath。此方法 ,cellForItemAtIndexPath立即返回。同时,requestImageForAsset异步的——这意味着您的完成处理程序稍后会被调用。到它被调用时,我们已经转移到另一个单元格;请记住,细胞被重复使用。所以你的整个方法是荒谬的。

查看 Apple 的示例代码,了解如何使用图像管理器的缓存版本填充集合视图的单元格。

另外,我注意到您忽略了 PHImageRequestOptions。这很重要。你应该仔细考虑你想要什么。如果您没有设置任何值,这意味着您将面临完成处理程序将被多次调用的风险,当我们不再处于填充此单元格的过程中时,这再次没有意义。

于 2015-10-08T02:42:47.913 回答