PHAsset fetch возвращает 50% коллекции как ноль

Когда я беру PHAssetCollection и дать это PHAsset.fetchAssetsInAssetCollection:options Мне вернули коллекцию PHAssets. Для каждого UIImage возвращенный мне, есть нулевое значение, также возвращаемое.

Следующее мое 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 просто ничего не рендерит. Как только я добавлю нулевую проверку, представление коллекции начнет рендеринг изображений из коллекции активов библиотеки фотографий.

Почему мне всегда возвращается столько же нилов, сколько 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;
}

1 ответ

Вы не можете позвонить self.imageManager.requestImageForAsset так, как вы называете это в середине cellForItemAtIndexPath, Этот метод, cellForItemAtIndexPath, возвращается немедленно. В то же время, requestImageForAsset является асинхронным - это означает, что ваш обработчик завершения вызывается позже. К тому времени, когда он вызывается, мы переходим к другой ячейке; и помните, клетки используются повторно. Так что весь ваш подход бессмысленен.

Взгляните на пример кода Apple, чтобы узнать, как заполнить ячейки представления коллекции, используя кеширующую версию менеджера изображений.

Кроме того, я заметил, что вы игнорируете PHImageRequestOptions. Это очень важно. Вы должны внимательно подумать о том, что вы хотите здесь. Если вы не установите значение, это означает, что вы рискуете, что ваш обработчик завершения будет вызываться более одного раза, что снова не имеет смысла, когда мы больше не находимся в процессе заполнения этой ячейки.

Другие вопросы по тегам