Как правильно использовать фреймворк Photos в iOS 8 с UICollectionView, сохраняя пропорции изображения, например, в Messages.app?

85
4

Я хочу создать похожий взгляд на то, что Apple имеет в Messages.app, где у вас горизонтальный скользящий вид изображений.


enter image description here


Я понимаю, что в iOS 8 лучший способ сделать это - использовать новую структуру "Фотографии" и, вероятно, рядом с горизонтальной UICollectionView.


У меня есть мой UICollectionView, прикрепленный к высоте набора в раскадровке диспетчера диспетчера просмотра и расположенный сверху, а затем в viewDidLoad пишу:


let assetCollectionsResult = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype: .SmartAlbumRecentlyAdded, options: nil)
let recentlyAddedCollection = assetCollectionsResult.firstObject as! PHAssetCollection
recentlyAddedFetchResult = PHAsset.fetchAssetsInAssetCollection(recentlyAddedCollection, options: nil)

Где recentlyAddedFetchResult - это переменная экземпляра на контроллере представления.


Затем я создал пользовательский подкласс UICollectionViewCell, который просто имеет UIImageView, прикрепленный с помощью автоматического макета к краям ячейки.


В методах UICollectionViewDataSource у меня есть:


func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return recentlyAddedFetchResult.count
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("ImageCell", forIndexPath: indexPath) as! ImageCollectionViewCell
let asset = recentlyAddedFetchResult[indexPath.row] as! PHAsset

PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: CGSize(width: 300.0, height: 300.0), contentMode: .AspectFill, options: nil) { (result, info) in
cell.imageView.image = result
}

return cell
}


Однако теперь я понимаю, что мне придется реализовать sizeForItem, но я смущен, как с этим справиться. Лучший способ, которым я мог придумать, - выполнить вышеприведенную выборку, но с меньшим размером изображения, так как мне просто нужно соотношение, а затем вернуть размер, основанный на этом. Но выбор является асинхронным, поэтому мне нужно будет его сохранить, а затем вернуть его позже?


Я пробовал это следующим образом:


func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
if let cellSize = cellSizeCache[indexPath] {
return cellSize
} else {
let asset = recentlyAddedFetchResult[indexPath.row] as! PHAsset

PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: CGSize(width: 20.0, height: 20.0), contentMode: .AspectFill, options: nil) { (result, info) in
let imageRatio = result.size.width / result.size.height
let width = 140 * imageRatio

self.cellSizeCache[indexPath] = CGSize(width: width, height: 140.0)
collectionView.reloadItemsAtIndexPaths([indexPath])
}

return CGSize(width: 140, height: 140)
}
}


Но консоль просто заливается бесконечным циклом этого сообщения:


высота элемента должна быть меньше высоты UICollectionView за вычетом верхних и нижних значений разделов.



Но это так. Вид коллекции 150 высот без вставки разделов. Даже если я удалю кеширование, он просто возвращает 140x140 каждый раз, когда он все еще жалуется на это. Зачем? Если я откажу его примерно до 70х70, он отлично работает, но я не знаю, почему.


Кроме того, первые два изображения в скроллере редко появляются при первом загрузке, только один раз, когда я прокручиваю их.


Что я здесь делаю неправильно? Там очень мало учебников по новой структуре фотографий, поэтому, несмотря на все мои усилия, я не могу понять, что я делаю неправильно.

спросил(а) 2015-03-26T09:27:00+03:00 5 лет, 11 месяцев назад
0
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема