使用 NSCollectionViewFlowLayout 在 NSCollectionView 上没有动画

No Animations on NSCollectionView with NSCollectionViewFlowLayout

我正在以编程方式设置一个简单的集合视图,但没有看到我希望免费获得的 insert/remove 动画。我检查了 类 上与集合视图关联的所有方法,但找不到任何似乎会影响动画的方法。请问我在这个设置中遗漏了什么吗?

在索引 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()
    }
}

要使更改动画化,需要通过动画代理调用方法。进行以下更改会产生我预期的动画效果。

不正确:

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

正确:

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

这不是我以前知道的概念,集合视图动画文档中也没有提到它。