Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
87 views
in Technique[技术] by (71.8m points)

nstablecolumn - How to add columns in Cocoa NSTableView?

I want to show data in NSTableView. The number of columns is unspecified (could be any from 1 to ?? depending on the data), so I can't use Interface Builder.
So I initialize (with IB) my table to 1 column, and thereafter add new columns as required (then remove the no-longer needed 0-th column). To each added column I provide a unique identifier. So far so good.
I implement the tableView(-:viewForTableColumn:row) function, as shown below, but the makeViewWithIdentifier returns nil. What's the matter ?
If I detect the nil return, I create an instance of NSTableCellView with the proper identifier. But the data do not show in the table. What could be wrong ?

The code is below (with unnecessary lines removed) :

import Cocoa
class MyViewController: NSViewController {

@IBOutlet weak var dataTable: NSTableView!
}
var donnees: DataFrame = DataFrame()    // Some table-like data with unspecified number of columns

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    initData()      // get the actual data

    //      Make the ad-hoc number of columns
    if donnees.nbCol > 0 {
        for k in 0..<donnees.nbCol {
            let newColumn = NSTableColumn(identifier: idArray[k])       // idArray : [String] of unique identifiers
            dataTable.addTableColumn(newColumn)
        }
    }
    dataTable.removeTableColumn(dataTable.tableColumns[0])  // remove the original column, now unnecessary
}  
}  
extension MyViewController : NSTableViewDataSource {
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
    return self.donnees.nbRow
}  
}  
extension MyViewController : NSTableViewDelegate {
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
    let columnID = tableColumn!.identifier
    var cellView: NSTableCellView
    let cellViewTmp = tableView.makeViewWithIdentifier(columnID, owner: self)
    if cellViewTmp == nil {     // then create a new NSTableCellView instance
        cellView = NSTableCellView(frame: NSRect(x: 0, y: 0, width:  (tableColumn?.width)!, height: 20))
        cellView.identifier = columnID
        print("CellView créé pour id (columnID) au rang (row)")
    } else {
        cellView = cellViewTmp as! NSTableCellView
    }
    cellView.textField?.stringValue = "AAA"
    return cellView
}  
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Bingo ! Thanks to Willeke I rewrote my code as follows :

var donnees: DataFrame = DataFrame()    // Some table-like data with unspecified number of columns

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    initData()      // get the actual data
    self.setTableColumns() // and prepare the columns accordingly
}
    func setTableColumns() {
    // In Interface Builder I've prepared a cell view in the 0-th tableColumn and set the identifier of this NSTableColumn to "ModelCellView"
        let myCellViewNib = dataTable.registeredNibsByIdentifier!["ModelCellView"]   // I save the cellView's Nib
    //      Make the ad-hoc number of columns
        if donnees.nbCol > 0 {
            for k in 0..<donnees.nbCol {
                let newColumn = NSTableColumn(identifier: idArray[k])       // idArray : [String] of unique identifiers
                dataTable.addTableColumn(newColumn)
                dataTable.registerNib(myCellViewNib, forIdentifier: newColumn.identifier)  // I register the above Nib for the newly added tableColumn
            }
            dataTable.removeTableColumn(dataTable.tableColumns[0])  // remove the original column, now unnecessary
        }
    }

extension MyViewController : NSTableViewDataSource {
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
    return self.donnees.nbRow
}  
extension MyViewController : NSTableViewDelegate {
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
    let columnID = tableColumn!.identifier
    let cellView = tableView.makeViewWithIdentifier(columnID, owner: self) as! NSTableCellView
    cellView.textField?.stringValue = "theActualCellData"
    return cellView
}  

And it works perfectly as intended. Again, thanks to Willeke.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...