Нет анимации в NSCollectionView с NSCollectionViewFlowLayout

Я программно настраиваю простое представление коллекции, но не вижу анимаций вставки / удаления, которые я ожидал получить бесплатно. Я проверил все методы классов, связанных с представлениями коллекций, и не могу найти ничего, что могло бы повлиять на анимацию. Что-то мне не хватает в этой настройке, пожалуйста?

При вставке чего-либо с индексом 0 я ожидаю увидеть перемещение существующих элементов и исчезновение нового элемента.

class ECTestViewController: NSViewController
{
    var scrollView: NSScrollView!
    var collectionView: NSCollectionView!

    var items = [Int]()

    override func loadView() {
        view = NSView()
        view.translatesAutoresizingMaskIntoConstraints = false
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        scrollView = NSScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(scrollView)
        let scrollViewList = ["view": scrollView]
        var scrollViewConstraints = NSLayoutConstraint.constraints(withVisualFormat: "|[view]|", metrics: nil, views: scrollViewList)
        scrollViewConstraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|-22-[view]-8-|", metrics: nil, views: scrollViewList)
        NSLayoutConstraint.activate(scrollViewConstraints)

        collectionView = NSCollectionView()
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.dataSource = self
        collectionView.delegate = self
        scrollView.documentView = collectionView

        collectionView.collectionViewLayout = NSCollectionViewFlowLayout()

        // Register the item types for the collection
        collectionView.register(ECTestItem.self, forItemWithIdentifier: ECTestItem.interfaceIdentifier)

        // Add our first item
        items.append(0)

        // Buttons to add and remove items
        let openImage = NSImage(named: NSImage.Name("Open"))
        let openButton = ECImageButton(image: openImage!)
        view.addSubview(openButton)
        openButton.action = #selector(openItem)
        openButton.target = self

        let closeImage = NSImage(named: NSImage.Name("Close"))
        let closeButton = ECImageButton(image: closeImage!)
        view.addSubview(closeButton)
        closeButton.action = #selector(closeItem)
        closeButton.target = self
    }

    @objc func closeItem() {
        items.remove(at: 0)
        collectionView.deleteItems(at: [IndexPath(item: 0, section: 0)])
    }

    @objc func openItem() {
        items.insert(0, at: 0)
        collectionView.insertItems(at: [IndexPath(item: 0, section: 0)])
    }
}

extension ECTestViewController: NSCollectionViewDataSource
{
    func numberOfSections(in collectionView: NSCollectionView) -> Int {
        return 1
    }

    func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
        return items.count
    }

    func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
        return collectionView.makeItem(withIdentifier: ECTestItem.interfaceIdentifier, for: indexPath)
    }
}

extension ECTestViewController: NSCollectionViewDelegateFlowLayout // Actually set as the collection view delegate
{
    func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
        return NSMakeSize(100, 100)
    }
}

class ECTestItem: NSCollectionViewItem
{
    static var interfaceIdentifier: NSUserInterfaceItemIdentifier { get { return NSUserInterfaceItemIdentifier("ouliner") } }

    override func loadView() {
        view = NSView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.wantsLayer = true
        view.layer?.backgroundColor = CGColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

person Giles    schedule 22.03.2018    source источник


Ответы (1)


Чтобы изменения были анимированы, необходимо вызвать методы через прокси-сервер аниматора. Внесение изменений ниже дало ожидаемую мной анимацию.

Неправильно:

collectionView.insertItems(at: [IndexPath(item: 0, section: 0)])

Верный:

collectionView.animator().insertItems(at: [IndexPath(item: 0, section: 0)])

Это не было концепцией, о которой я знал раньше, и в документации по анимации представления коллекции нет упоминания об этом.

person Giles    schedule 22.03.2018
comment
большой !. просто чтобы добавить для других: вы также можете сделать collectionView.animator (). performBatchUpdates. - person user1105951; 09.01.2019