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
    }
}

0 ответов

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