以编程方式将列添加到NSTableView

时间:2017-02-26 14:44:06

标签: swift cocoa nstableview

我正在尝试以编程方式将列添加到NSTableView,这是我用IB定义的视图的一部分,作为我想要重用的自定义视图控制器的一部分(我会为每个特定的自定义列使用)。

我正在使用数据源/委托来提供行/列值。我将代码简化为重现问题所需的最少代码。

该表显示了完全古怪的行为:我创建了1000行,但只显示了第17行(适合初始视图端口的那些行),其余部分(通过向下滚动可见)为空。当向上滚动时,即使是最初的那些现在也不见了。此外,行视图被剪裁。

以下是该行为的视频: https://www.youtube.com/watch?v=toRpIfp5A6w

对于那些无法播放视频的人来说,这是滚动中途的截图。请记住,该表应该有1000行。

Table view visual errors

这是我的代码。

的AppDelegate

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        let controller = TestViewController()
        self.window.contentView?.addSubview(controller.view)
        controller.view.translatesAutoresizingMaskIntoConstraints = false
        controller.view.heightAnchor.constraint(equalTo: self.window.contentView!.heightAnchor).isActive = true
        controller.view.widthAnchor.constraint(equalTo: self.window.contentView!.widthAnchor).isActive = true
        controller.view.trailingAnchor.constraint(equalTo: self.window.contentView!.trailingAnchor).isActive = true
    }

    func applicationWillTerminate(_ aNotification: Notification) {
    }
}

查看控制器

import Cocoa

class TestViewController: NSViewController {

    @IBOutlet weak var tableView: NSTableView!
    private var tableSource = TestTableSource()

    override func viewDidLoad() {
        super.viewDidLoad()
        let columns = self.tableView.tableColumns
        columns.forEach {
            self.tableView.removeTableColumn($0)
        }
        let column = NSTableColumn(identifier: "c1")
        column.title = "COL1"
        self.tableView.addTableColumn(column)
        self.tableView.delegate = self.tableSource
        self.tableView.dataSource = self.tableSource
        self.tableView.reloadData()
    }
}

class TestTableSource: NSObject, NSTableViewDelegate, NSTableViewDataSource {

    let array = (0..<1000).map { "row \($0)" }

    func numberOfRows(in tableView: NSTableView) -> Int {
        return array.count
    }

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {        
        guard tableColumn?.identifier == "c1" else { fatalError() }
        let view = NSTextField(string: array[row])
        return view
    }
}

在IB中查看控制器

这些是NSTableView设置 NSTableView settings

NSTableView settings 2

欢迎任何有关如何解决此问题的建议!

编辑:我忘了切换到基于视图。我上传了新截图。问题仍然存在。

1 个答案:

答案 0 :(得分:1)

已解决:表视图委托/数据源已立即解除分配,因为没有任何内容持有强引用。

由于委托是NSTableView中的弱属性,因此获取单元格值的任何进一步尝试都将失败。

长篇TestViewController被声明为范围变量,然后将其视图添加到视图层次结构中。但由于没有任何东西固定在这个视图控制器本身上,所以它立即被解除分配。由于视图控制器是持有委托/数据源的控制器,因此也将取消分配。

感谢@biappi帮助我解决这个问题。