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