这是我想要实现的窗口:
它是一个以 NSCollectionView (RedCollectionView) 作为视图的 NSViewController (RedViewController)。
它的项目 (BlueItem) 有一个 NSCollectionView (BlueCollectionView) 作为视图。
它的项目(GreenItem),有一个NSImageView(GreenImageView)作为视图。
RedCollectionView 将垂直滚动,并且其项目将是可选的。但是,BlueCollectionView 仅用于显示,它不会自行滚动并且无法选择。
这是 AppDelegate 的代码:
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
lazy var redViewController: RedViewController = {
let redViewController = RedViewController.init()
return redViewController
}()
lazy var window: NSWindow = {
let window = NSWindow.init(contentViewController: self.redViewController)
return window
}()
lazy var windowController: NSWindowController = {
let windowController = NSWindowController.init(window: self.window)
return windowController
}()
func applicationDidFinishLaunching(_ aNotification: Notification) {
self.windowController.showWindow(nil)
}
}
这是 RedViewController 的代码:
class RedViewController: NSViewController, NSCollectionViewDataSource, NSCollectionViewDelegate {
lazy var collectionViewLayout: NSCollectionViewFlowLayout = {
let collectionViewLayout = NSCollectionViewFlowLayout.init()
collectionViewLayout.itemSize = NSSize(width: 100.0, height: 100.0)
collectionViewLayout.minimumLineSpacing = 10.0
collectionViewLayout.minimumInteritemSpacing = 10.0
collectionViewLayout.sectionInset = NSEdgeInsetsMake(10.0, 10.0, 10.0, 10.0)
return collectionViewLayout
}()
class RedCollectionView: NSCollectionView { /* nothing here for now */ }
lazy var redCollectionView: RedCollectionView = {
let redCollectionView = RedCollectionView.init(frame: NSRect(x: 0.0, y: 0.0, width: 500.0, height: 500.0))
redCollectionView.collectionViewLayout = self.collectionViewLayout
redCollectionView.dataSource = self
redCollectionView.delegate = self
redCollectionView.isSelectable = true
redCollectionView.backgroundColors = [NSColor.red]
return redCollectionView
}()
override func loadView() {
let clipView = NSClipView.init()
clipView.documentView = self.redCollectionView
let scrollView = NSScrollView.init(frame: NSRect(x: 0.0, y: 0.0, width: 500.0, height: 500.0))
scrollView.contentView = clipView
self.view = scrollView
}
override func viewDidLoad() {
super.viewDidLoad()
self.redCollectionView.register(BlueItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier("BlueItemID"))
}
func numberOfSections(in collectionView: NSCollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return 50
}
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "BlueItemID"), for: indexPath)
guard let blueItem = item as? BlueItem else { return item }
return blueItem
}
func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {
indexPaths.forEach({ print($0) })
collectionView.deselectItems(at: indexPaths)
}
}
这是 BlueItem 的代码:
class BlueItem: NSCollectionViewItem, NSCollectionViewDataSource {
lazy var collectionViewLayout: NSCollectionViewFlowLayout = {
let collectionViewLayout = NSCollectionViewFlowLayout.init()
collectionViewLayout.itemSize = NSSize(width: 27.0, height: 27.0)
collectionViewLayout.minimumLineSpacing = 3.0
collectionViewLayout.minimumInteritemSpacing = 3.0
collectionViewLayout.sectionInset = NSEdgeInsetsMake(3.0, 3.0, 3.0, 3.0)
return collectionViewLayout
}()
class BlueCollectionView: NSCollectionView {
override func mouseDown(with event: NSEvent) {
super.mouseDown(with: event)
self.nextResponder?.mouseDown(with: event)
}
override func mouseUp(with event: NSEvent) {
super.mouseUp(with: event)
self.nextResponder?.mouseUp(with: event)
}
}
lazy var blueCollectionView: BlueCollectionView = {
let blueCollectionView = BlueCollectionView.init(frame: NSRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0))
blueCollectionView.collectionViewLayout = self.collectionViewLayout
blueCollectionView.dataSource = self
blueCollectionView.isSelectable = false
blueCollectionView.backgroundColors = [NSColor.blue]
return blueCollectionView
}()
override func loadView() {
self.view = self.blueCollectionView
}
override func viewDidLoad() {
super.viewDidLoad()
self.blueCollectionView.register(GreenItem.self, forItemWithIdentifier: NSUserInterfaceItemIdentifier("GreenItemID"))
}
func numberOfSections(in collectionView: NSCollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return 7
}
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "GreenItemID"), for: indexPath)
guard let greenItem = item as? GreenItem else { return item }
return greenItem
}
}
最后是 GreenItem 的代码:
class GreenItem: NSCollectionViewItem {
class GreenImageView: NSImageView { /* nothing here for now */ }
lazy var greenImageView: GreenImageView = {
let image: NSImage = NSImage.init(imageLiteralResourceName: "greenImage")
let greenImageView = GreenImageView.init(image: image)
return greenImageView
}()
override func loadView() {
self.view = self.greenImageView
}
}
当我启动应用程序时,我得到了这个结果:
所以我有 3 个问题:
1. 带有 BlueCollectionView 的 BlueItem 没有得到预期的蓝色背景。
2. BlueCollectionView 流布局尝试在第一行显示所有项目。看起来它不知道集合视图的大小。
3. 当我尝试选择一个BlueItem 时:如果我点击BlueItem 内的空白区域,RedCollectionView 委托会按预期触发,但如果我点击BlueItem 内的绿色部分,则不会触发RedCollectionView 委托。