Программно созданный NSCollectionView `makeItem` возвращает ноль, даже если зарегистрирован - PullRequest
0 голосов
/ 31 мая 2018

Я занимаюсь разработкой приложения macOS для MacOS 10.10 SDK и использую Xcode 9.3 (Swift 4).Я не использую xibs, но создаю все представления программно.

Я хочу создать NSCollectionView.Я регистрирую подкласс NSCollectionViewItem, а затем регистрирую этот класс на NSCollectionView с вызовом collectionView.register(:,forItemWithIdentifier).Позже в источнике данных я вызываю collectionView.makeItem(withIdentifier:,for:).

Однако метод makeItem всегда возвращает ноль.Что я делаю не так?

Я нашел похожий вопрос , но решение состоит в том, чтобы позвонить register, что я уже делаю.

Для справки, вот минимумработает, чтобы воспроизвести мою проблему: когда я ставлю точку останова после вызова makeItem, я вижу, что возвращаемое значение всегда nil.

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!


    func applicationDidFinishLaunching(_ aNotification: Notification) {
        window.contentViewController = TestViewController()
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }


}

let cellIdentifier = NSUserInterfaceItemIdentifier(rawValue: "testIdentifier")

class TestViewController: NSViewController, NSCollectionViewDataSource {

    override func loadView() {
        self.view = NSView()
    }

    override func viewDidLoad() {
        let scroll = NSScrollView()

        self.view.addSubview(scroll)

        scroll.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint(item: scroll, attribute: .bottom, relatedBy: .equal, toItem: self.view, attribute: .bottom, multiplier: 1, constant: 0).isActive = true
        NSLayoutConstraint(item: scroll, attribute: .top, relatedBy: .equal, toItem: self.view, attribute: .top, multiplier: 1, constant: 0).isActive = true
        NSLayoutConstraint(item: scroll, attribute: .left, relatedBy: .equal, toItem: self.view, attribute: .left, multiplier: 1, constant: 0).isActive = true
        NSLayoutConstraint(item: scroll, attribute: .right, relatedBy: .equal, toItem: self.view, attribute: .right, multiplier: 1, constant: 0).isActive = true
        NSLayoutConstraint(item: scroll, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 500).isActive = true
        NSLayoutConstraint(item: scroll, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 500).isActive = true

        let collection = NSCollectionView()
        scroll.documentView = collection

        collection.register(TestViewItem.self, forItemWithIdentifier: cellIdentifier)
        collection.dataSource = self
        collection.collectionViewLayout = NSCollectionViewFlowLayout()
        collection.reloadData()
    }

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

    func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
        let item = collectionView.makeItem(withIdentifier: cellIdentifier, for: indexPath)
        return item
    }
}

class TestViewItem: NSCollectionViewItem {

    override func loadView() {
        self.view = NSView()
    }
}

1 Ответ

0 голосов
/ 02 июня 2018

Я думаю, что это ошибка.Обходной путь: установите collectionViewLayout перед регистрацией класса.

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

...