【问题标题】:NSOutlineView spacing between items is incorrect项目之间的 NSOutlineView 间距不正确
【发布时间】:2021-04-03 06:37:29
【问题描述】:

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

var sections: [SidebarSection] = [
    SidebarSection(title: "Section 1", items: ["1", "2", "3", "4", "5"]),
    SidebarSection(title: "Section 2", items: ["1", "2"]),
    SidebarSection(title: "Section 3", items: ["1", "2"]), 
    SidebarSection(title: "Section 4", items: ["1", "2"]), 
    SidebarSection(title: "Section 5", items: ["1", "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)
    }
}

【问题讨论】:

  • SidebarPlaylistCell 视图中的约束是什么?行视图的运行时高度是多少?

标签: swift macos appkit


【解决方案1】:

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

outlineView.floatsGroupRows = false

你得到了想要的行为。

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

一个布尔值,指示表视图是否像浮动一样绘制分组行。

快速测试

floatGroupRows的含义

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

【讨论】:

  • 这到底是什么意思?该文档非常没用,我知道 bool 标志控制“表格视图是否像浮动一样绘制分组行。”但是“好像它们是浮动的”究竟是什么意思?
  • 由于 floatsGroupRows 的效果在动画图形中更容易看到,所以我在答案中添加了这个。