【问题标题】:Columns added programmatically to NSTableView not recognised in Delegate以编程方式添加到 NSTableView 的列在 Delegate 中无法识别
【发布时间】:2023-03-04 00:01:01
【问题描述】:

我可能会迷失在一杯水中,但我似乎无法向 NSTableView 添加列,然后在 NSTableViewDelegate 中识别这些列。我在 IB 中创建了一个包含一列的表,并为该列提供了一个字符串标识符。我在 View Controller 中添加其他列:

 override func viewDidLoad() {
        super.viewDidLoad()

        for columnIndex in 0..<blotter!.singleOutput[0].parameter.count  {

            let tmpParam = blotter!.singleOutput[0].parameter[columnIndex]
            let column = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(rawValue: tmpParam.columnID))
            column.title = tmpParam.label
            column.width = CGFloat(80)
            column.minWidth = CGFloat(40)
            column.maxWidth = CGFloat(120)
            blotterOutputTable.addTableColumn(column)

            }

        blotterOutputTable.delegate = self
        blotterOutputTable.dataSource = self
        blotterOutputTable.target = self

        blotterOutputTable.reloadData()

    }

NSTableViewDataSource 返回正确的行数。我遇到的问题出在 NSTableViewDelegate 中:

extension OutputsViewController: NSTableViewDelegate {

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {

        var text: String = ""
        var cellIdentifier: String = ""

        guard let item = blotter?.singleOutput[row] else {   return nil  }

        // 1. LABELS COLUMN
        // ================

        if tableColumn?.identifier.rawValue == "dealColumn" {

            let myParameter = item.parameter.index(where: {$0.columnID == "BBTickColumn"})

            text =  item.parameter[myParameter!].value as! String               
            cellIdentifier = "dealColumn"

            if let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: cellIdentifier), owner: nil) as? NSTableCellView {

                cell.textField?.stringValue = text                  
                return cell
                }

            else {    return nil  }

            }   // END OF LABLES COLUMN (FIRST ONE)




        else {     // THIS IS WHERE THE PROBLEM IS

            let myParameter = item.parameter.index(where: {$0.columnID  ==  tableColumn?.identifier.rawValue } )
            let (_, valueAsText) = item.parameter[myParameter!].interfaceItems()
            text = valueAsText

            cellIdentifier = item.parameter[myParameter!].columnID


            if let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: cellIdentifier), owner: nil) as? NSTableCellView {

                cell.textField?.stringValue = text
                return cell
                }

            else {    return nil  }  // DEBUGGER PARAMETER ARE FROM HERE

            }      
        }

}

第一列是我在 IB 中创建的带有标识符的列。这样可行。我遇到的问题出在 else 语句中(它不检查列标识符)。以下是我在单元格创建失败后停止程序时在调试器窗口中看到的参数

tableView   NSTableView 0x000000010ebf9df0
tableColumn NSTableColumn?  0x0000600000895770
row Int 0
self    DataBaseManager.OutputsViewController   0x0000600000102b50
text    String  "FLAT"  
cellIdentifier  String  "directionColumn"   
item    DataBaseManager.BlotterOutputs  0x000060000002c240
myParameter Array.Index?    0
valueAsText String  "FLAT"  
cell    (null)  (null)  (null)
tableColumn NSTableColumn?  0x0000600000895770
tableColumn?.identifier NSUserInterfaceItemIdentifier?  some
_rawValue   _NSContiguousString "directionColumn"   0x000060000104d200
Swift._SwiftNativeNSString  _SwiftNativeNSString    
_core   _StringCore 

您可以看到 cellIdentifier 和 tableColumn?.identifier.rawvalue 是相同的字符串(应该如此)。我无法理解为什么不创建单元格。任何帮助都非常受欢迎,如果不清楚,请告诉我。谢谢

【问题讨论】:

  • Storyboard/XIB 中的 tableview 是否包含 ID 为“directionColumn”的单元格视图?
  • 感谢您的回复 Willeke。答案是不。只有第一列在 IB(“dealColumn”)中。所有其他列都添加到 viewDidLoad() 中。它们的标识符位于具有 columnID 属性的类(参数)中。它被用作新创建列的标识符。调试器显示directionColumn,因为这是创建的第一列(因此我停止程序进行调试)。我有大约 50 列要创建,因此我不想将它们全部放在 IB 中而是以编程方式添加它们。
  • 我看过它,但似乎无法让它工作。具体来说,我修改了 viewDidLoad() 以包含笔尖线:
  • 但是在线上让 myCellViewNib = butterOutputTable.registeredNibsByIdentifier!["dealColumn"] 得到错误消息:Cannot subscript a value of type '[NSUserInterfaceItemIdentifier : NSNib]' with an index of type 'String' .抱歉,如果这是微不足道的,但我不是专业的开发人员,我没有很多经验。谢谢

标签: swift cocoa nstableview tablecolumn


【解决方案1】:

必须在此代码中注册 nib 标识符:

import Cocoa

class MultiColumnTable: NSViewController, NSTableViewDataSource, NSTableViewDelegate {

    var list = [[String]](), header=[String]()
    var tableView : NSTableView? = nil
    var nColumns : Int = 0

    func genID(col : Int) -> NSUserInterfaceItemIdentifier { // generate column ID
        return NSUserInterfaceItemIdentifier(rawValue: String(format: "Col%d", col))
    }

    func setContent(header: [String], list : [[String]]) {
        self.header = header
        self.list = list
        self.nColumns = list[0].count

        if tableView != nil {
            tableView?.reloadData()
        }
    }

    func numberOfRows(in tableView: NSTableView) -> Int {

        func createColumns() {
            func addColumn(col:Int, header:String) {
                let tableColumn = NSTableColumn(identifier: genID(col: col))
                tableColumn.headerCell.title = header
                self.tableView!.addTableColumn(tableColumn)
            }

            // create columns and register them in NIB
            // IB: tableColumn[0] identifier ( NSTableColumn to "Col0" )

            if let myCellViewNib = tableView.registeredNibsByIdentifier![NSUserInterfaceItemIdentifier(rawValue: "Col0")] {

                for col in 0..<nColumns { // table should have 1 col in IB w/Ident 'Col0'
                    addColumn(col: col, header: header[col])
                    tableView.register(myCellViewNib, forIdentifier:  genID(col: col))  // register the above Nib for the newly added tableColumn
                }
                tableView.removeTableColumn(tableView.tableColumns[0])  // remove the original Col0
            }
        }

        self.tableView = tableView
        createColumns()

        return list.count
    }

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {

        let column = tableView.tableColumns.firstIndex(of: tableColumn!)!
        tableColumn?.headerCell.title=header[column];


        if let cell = tableView.makeView(withIdentifier: (tableColumn?.identifier)!, owner: self) as? NSTableCellView {

            cell.textField?.stringValue = list[row][column]
            cell.textField?.textColor = NSColor.blue
            return cell
        }
        return nil
    }

    func tableViewSelectionDidChange(_ notification: Notification) {
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-06
    • 2017-02-03
    • 1970-01-01
    • 2013-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多