NSCollectionView добавить изображения в правильном порядке
Я пытаюсь восстановить галерею приложения MacOS Photos с помощью NSCollectionView
чтобы показать фотографии, которые находятся на моем устройстве Android.
Моя проблема в том, что я получаю эскизы изображений, которые я хочу отображать асинхронно из моего сервиса Android, и не всегда в правильном порядке (из-за многопоточности). Поэтому я сохраняю миниатюру входящего в класс Image
с NSImage
и Int
с правильным индексом миниатюры.
Каждый раз, когда я получаю новый эскиз, мне нужно отсортировать массив миниатюр и вызвать collectionView.reloadData()
для того, чтобы отобразить изображения в правильном порядке. Но этот вызов занимает больше времени, чем больше массив.
Также прокрутка является болью при использовании этого метода. Я открыл другую ветку для этого здесь.
Есть ли способ, которым я могу сделать это более эффективно? Может быть, я могу инициализировать представление коллекции с пустыми элементами, а затем установить изображение позже?
Как приложение родных фотографий справляется с этим? Он также не может загрузить все изображения мгновенно.
ImageViewController
class ImageViewController: NSViewController {
@IBOutlet private weak var collectionView: NSCollectionView!
private var thumbnails: [Image] = []
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
}
}
extension ImageViewController: ImageDelegate {
// Received new thumbnail from android service
func update(image: [String: Any]) {
let index = Int(image["index"] as! Int32) // Correct index of the image
let decodedData = Data(base64Encoded: (image["thumbnail"] as! String))!
let image = Image(image: NSImage(data: decodedData)!, index: index)
thumbnails.append(image)
thumbnails.sort(by: { $0.getIndex() < $1.getIndex()})
collectionView.reloadData()
}
}
extension ImageViewController: NSCollectionViewDataSource, NSCollectionViewDelegate, NSCollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return thumbnails.count
}
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "ImageItem"), for: indexPath) as! ImageItem
item.imageView?.image = thumbnails[indexPath.item].getImage()
return item
}
func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
let width = thumbnails[indexPath.item].getImage().size.width
let height = thumbnails[indexPath.item].getImage().size.height
// Calculate displayed size
if (width >= height) {
return NSSize(width: 120, height: 120 * (height / width))
} else {
return NSSize(width: 120 * (width / height), height: 120)
}
}
}
Образ
class Image: NSObject {
let image: NSImage
let index: Int
init(image: NSImage, index: Int) {
self.image = image
self.index = index
}
public func getImage() -> NSImage {
return image
}
public func getIndex() -> Int {
return index
}
}