Swift fetchAssetsInAssetCollection: загрузка фотографий из диапазона в фотопленке

Я хочу, чтобы у пользователя была возможность доступа ко всем его фотографиям, но загрузка их всех сразу занимает слишком много времени, используя PHAsset.fetchAssetsInAssetCollectionособенно если у них более 500 фотографий (я показываю их в виде коллекции в пользовательском представлении). Я думал об использовании scrollViewDidScroll когда пользователь достигает конца представления коллекции, чтобы загрузить следующий набор, но я не знаю, как получить следующий x сумма из фото библиотеки.

Я ограничил количество фотографий, которые они могут использовать fetchOptions.fetchLimit = x, но я не знаю, как сказать функции, где начать выборку активов. Является ли это возможным?

Вот фрагмент моего текущего кода (assetCollections устанавливается в другой части кода):

let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: kFormatOfPredicate, PHAssetMediaType.Image.rawValue)
fetchOptions.sortDescriptors = [NSSortDescriptor(key: kSortByCreationDateString, ascending: false)]
fetchOptions.fetchLimit = 32

//Only want camera roll
if assetCollection.localizedTitle == kCameraRollString {
assets = PHAsset.fetchAssetsInAssetCollection(assetCollection, options: fetchOptions)
if assets.count > 32 {
    for i in 0..<32 {
        if let asset = assets[i] as? PHAsset {
            appendImageArray(assetToBeChanged: asset)
        }
    }
} else {
    for i in 0..<assets.count {
        if let asset = assets[i] as? PHAsset {
            appendImageArray(assetToBeChanged: asset)
        }
    }
}

Есть ли что-то, что я могу добавить к своему fetchOptions сказать, какие активы начать получать? Есть ли лучший способ сделать это? Дайте мне знать, если вы хотите, чтобы я написал больше кода, и заранее благодарю!

2 ответа

У меня есть представление о том, как вы можете достичь этого:

  • Когда прокручивается первая группа выбранных ресурсов, вы должны получить creationDate первого актива. Предположим, вы сделаете это так:

    let firstAsset = assets[0] as! PHAsset
    // The first asset date will be used when scrolling up.
    firstAssetDate = firstAsset.creationDate
    
  • Теперь, чтобы получить другую группу ресурсов, вы настраиваете параметры выборки, используя ваши текущие дескрипторы сортировки (для сортировки в порядке убывания даты):

    fetchOptions.sortDescriptors = [NSSortDescriptor(key: kSortByCreationDateString, ascending: false)] 
    

    и следующий предикат (для получения только самых последних активов в соответствии с текущей последней датой активов):

    let lastAsset = assets[assets.count - 1] as! PHAsset
    fetchOptions.predicate = NSPredicate(format: "(mediaType == %d) AND (creationDate < %@)", PHAssetMediaType.Image.rawValue, lastAsset.creationDate)
    
  • На этом этапе вы можете очистить предыдущую группу активов. Если пользователь прокручивает вверх - используйте сохраненный firstAssetDate в сочетании со следующим предикатом:

    fetchOptions.predicate = NSPredicate(format: "(mediaType == %d) AND (creationDate <= %@)", PHAssetMediaType.Image.rawValue, firstAssetDate) 
    

    Если пользователь прокручивает вниз - используйте creationDate последнего актива в текущем извлеченном массиве и < сравнение в предикате.

Конечно, это всего лишь абстрактная идея, но, я думаю, ее легко реализовать в сочетании с вашим текущим кодом.

Также не забывайте об использовании PHCachingImageManager улучшить производительность прокрутки.

Вы можете обратиться к демонстрационному коду Apple WWDC:

Пример приложения с использованием Photo Framework

Это демонстрирует, как бороться, если пользователь прокручивает все фотографии.

В этом примере кода он имеет область "предварительного нагрева", где он больше, чем видимая область, он будет кэшироваться вперед и останавливать кэширование позади. И он рассчитывает и поддерживает диапазон "предварительного нагрева", когда происходит прокрутка. тогда он использует startCachingImages а также stopCachingImages API-интерфейсы. Таким образом, вы всегда будете иметь данные под рукой.

Наиболее полезная функция для вас такая в этом файле AssetGridViewController

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