以编程方式创建的 NSCollectionView `makeItem` returns nil 即使已注册
Programmatically created NSCollectionView `makeItem` returns nil even if registered
我正在开发一个针对 macOS 10.10 SDK 并使用 Xcode 9.3 (Swift 4) 的 macOS 应用程序。我没有使用 xibs,而是以编程方式创建所有视图。
我想创建一个 NSCollectionView
。我注册了 NSCollectionViewItem
的子 class,然后通过调用 collectionView.register(:,forItemWithIdentifier)
将 class 注册到 NSCollectionView
。稍后,在数据源中,我调用 collectionView.makeItem(withIdentifier:,for:)
.
然而 makeItem
方法总是 returns nil。我做错了什么?
我找到了类似的 question,但解决方案是调用 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()
}
}
我认为这是一个错误。解决方法:在注册 class 之前设置 collectionViewLayout
。
显然,如果未设置 collectionViewLayout
,则不会存储已注册的 class。 collectionViewLayout
可以在注册class后设置为新布局,注册的class不会被删除。
我正在开发一个针对 macOS 10.10 SDK 并使用 Xcode 9.3 (Swift 4) 的 macOS 应用程序。我没有使用 xibs,而是以编程方式创建所有视图。
我想创建一个 NSCollectionView
。我注册了 NSCollectionViewItem
的子 class,然后通过调用 collectionView.register(:,forItemWithIdentifier)
将 class 注册到 NSCollectionView
。稍后,在数据源中,我调用 collectionView.makeItem(withIdentifier:,for:)
.
然而 makeItem
方法总是 returns nil。我做错了什么?
我找到了类似的 question,但解决方案是调用 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()
}
}
我认为这是一个错误。解决方法:在注册 class 之前设置 collectionViewLayout
。
显然,如果未设置 collectionViewLayout
,则不会存储已注册的 class。 collectionViewLayout
可以在注册class后设置为新布局,注册的class不会被删除。