项目之间的 NSOutlineView 间距不正确

问题描述

我有一个 NSOutlineView,第 1 项和第 2 项之间的间距大于所有其他项之间的间距。这些是组项目。大纲视图非常简单。下面是我的代码,下面是我所指问题的图像:

var sections: [SidebarSection] = [
    SidebarSection(title: "Section 1",items: ["1","2","3","4","5"]),SidebarSection(title: "Section 2","2"]),SidebarSection(title: "Section 3",SidebarSection(title: "Section 4",SidebarSection(title: "Section 5","2"])]

private let outlineView: SidebarOutlineView = SidebarOutlineView()

extension SidebarViewController: NSOutlineViewDataSource {

    func outlineView(_ outlineView: NSOutlineView,isItemExpandable item: Any) -> Bool {
        return item is SidebarSection
    }
    
    func outlineView(_ outlineView: NSOutlineView,child index: Int,ofItem item: Any?) -> Any {
        if let section = item as? SidebarSection {
            return section.items[index]
        }
    
        return sections[index]
    }

    func outlineView(_ outlineView: NSOutlineView,numberOfChildrenOfItem item: Any?) -> Int {
        if let section = item as? SidebarSection {
            return section.items.count
        }
        return sections.count
    }
}

extension SidebarViewController: NSOutlineViewDelegate {

    func outlineView(_ outlineView: NSOutlineView,heightOfRowByItem item: Any) -> CGFloat {
        return 30
    }

    func outlineView(_ outlineView: NSOutlineView,isGroupItem item: Any) -> Bool {
        return item is SidebarSection
    }

    func outlineView(_ outlineView: NSOutlineView,viewFor tableColumn: NSTableColumn?,item: Any) -> NSView? {
        let view = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "SidebarPlaylistCell"),owner: self) as! SidebarPlaylistCell
        view.wantsLayer = true
        view.textLabel.stringValue = (item as? SidebarSection)?.title ?? ""
        view.imgView.wantsLayer = true
        view.imgView.layer?.backgroundColor = NSColor.red.cgColor
        return view
    }
}

extension SidebarViewController {

   func layout() {
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(scrollView)
    
        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    
        scrollView.documentView = outlineView
    
        outlineView.headerView = nil
    
        outlineView.delegate = self
        outlineView.dataSource = self
         outlineView.intercellSpacing = NSSize(width: 0,height: 0)
        scrollView.hasverticalScroller = true
        scrollView.hasHorizontalScroller = false
        scrollView.wantsLayer = true
    
        view.layer?.backgroundColor = NSColor.blue.cgColor
    }
}


final class SidebarOutlineView: NSOutlineView {

    override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        let column: NSTableColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("col1"))
        column.isEditable = false
        column.minWidth = 0
        addTableColumn(column)
        outlineTableColumn = column
    
        register(NSNib(nibNamed: "SidebarPlaylistCell",bundle: nil),forIdentifier: NSUserInterfaceItemIdentifier(rawValue: "SidebarPlaylistCell"))
        selectionHighlightStyle = .sourceList
        indentationPerLevel = 6.0
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
}

enter image description here

解决方法

此行为可以由布尔标志 floatsGroupRows 控制,该标志默认设置为 true。所以通过添加:

outlineView.floatsGroupRows = false

你得到了想要的行为。

文档可以在这里找到: https://developer.apple.com/documentation/appkit/nstableview/1528624-floatsgrouprows?language=swift

一个布尔值,指示表格视图是否将分组的行绘制成浮动的。

快速测试

quick test

floatGroupRows 的含义

floatsGroupRows 的效果可以在动画图形中更好的看到。在滚动操作期间,当前 GroupItem 保持浮动在顶部:

scroll demo of floatsGroupRows