本文介绍了如何从NSTableView中选择列和行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个基于NSTableView的视图.我尝试使用:let selectedRowNumber = tableViewMesos.selectedRowlet selectedColumnNumber = tableViewMesos.selectedColumn标识要保存到数组中的单元格视图中的textField:

I am writing a NSTableView based view. And I try to use:let selectedRowNumber = tableViewMesos.selectedRow andlet selectedColumnNumber = tableViewMesos.selectedColumn to identify the textField that is in the cell View that I want to save into my array:

taulaDeConsumsMesos[selectedColumnNumber].filesConsum![selectedRowNumber] = sender.doubleValue

但是这里出现一个问题,因为selectedColumnNumber的返回值是-1,这是任何列中任何选定行的未选择列的值.但是selectedRowNumber正确返回行的索引.

But a problem happens here, because the return value of selectedColumnNumber is -1 which is the value of non-selected Column for any row selected of any column.But the selectedRowNumberreturns the index of the row properly.

因此,当完成单元格中文本字段的编辑时,程序将崩溃.因为selectedColumnNumber为-1,超出了数组的限制.请参阅下面的代码,确定确切的位置.

So the program crashes when finishing the edition of a textfield in a cell. Because the selectedColumnNumber is -1 out of the limits of the array. See the code below to identify where this happens exactly.

你能帮我吗?我为此花了太多时间.我是OSX编程的新手,希望您能对我有所帮助.

Could you help me? I lost too many hours on this..I'm new on OSX programing I hope you could help me.

应用布局

这是完整的代码:

class BalancGlobalViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate{

@IBOutlet weak var tableViewMesos: NSTableView!

let mesos = ColumnaDeConsumsMes() // contains an array of doubles called .filesConsum that represent the rows that I want to show
let consum = ColumnaDeConsumsMes()

var taulaDeConsumsMesos = [ColumnaDeConsumsMes]() // array of arrays that represent the columns with rows in it that will be the tableView data

func setUpMesos(){ // init table columns
    mesos.filesConsum = [1, 2, 3, 4, 5, 6, 7, 8 , 9, 10, 11, 12, nil]
    consum.filesConsum = [100, 100, 100, nil, nil, nil, nil, nil , nil, nil, nil, nil, nil]
    taulaDeConsumsMesos.append(mesos)
    taulaDeConsumsMesos.append(consum)
}

func setUpGradient(){
   ...not important here
}

override func viewDidLoad() {
    super.viewDidLoad()

    setUpMesos()

    tableViewMesos.setDelegate(self)
    tableViewMesos.setDataSource(self)

    setUpGradient()

}

override func viewDidLayout() {
    super.viewDidLayout()

    setUpGradient()
}

@IBAction func alEditarUnTextFieldDeConsum(sender: NSTextField) { // this is the IBAction of the TextField of the Consum Column (see the image)

    let selectedRowNumber = tableViewMesos.selectedRow
    let selectedColumnNumber = tableViewMesos.selectedColumn

    print("SelectedRowNumber! =  \(selectedRowNumber)")
    print("SelectedColumnNumber! =  \(selectedColumnNumber)")
    // the selectedColumnNumber return always -1 except when clicking the header of the column, then return 0 or 1 depending on the column. But it should return 0 even when the user edit a row of the index 0 column !!!

    let numero = tableViewMesos.numberOfColumns
    print("numero de columnes: \(numero)") // returns 2

    if selectedRowNumber != -1 {      //-1 is returned when no row is selected in the TableView
        taulaDeConsumsMesos[selectedColumnNumber].filesConsum![selectedRowNumber] = sender.doubleValue  //try to save here the value edited by the user on my array of arrays of doubles
//here the program crashes! selectedColumnNumber = -1

        print("Sender! =  \(sender.doubleValue)") // the sender returns the information correctly
        //print("SelectedRowNumber! =  \(selectedRowNumber)") // this works too!

        reloadTaula()
    }

}

func tableViewSelectionDidChange(notification: NSNotification) {

    print("columna: \(tableViewMesos.selectedColumn)")
    print("row: \(tableViewMesos.selectedRow)")
    print("tag: \(tableViewMesos.selectedTag())")
}
// the tableViewMesos.selectedColumn return always -1 except when clicking the header of the colum, then return 0 or 1 depending on the column. But i should return 0 even when I edit a row of the index 0 column !!!

func reloadTaula() {
    tableViewMesos.reloadData()
}


// MARK: - Datasource

func numberOfRowsInTableView(tableView: NSTableView) -> Int {
    if (tableView.identifier == "TaulaMesos") {
        return 13
    }
}


// MARK: - Delegate

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

    var valorCela: Double
    var cellIdentifier:String=""

    if tableColumn == tableView.tableColumns[0] {
        if taulaDeConsumsMesos[0].filesConsum![row] == nil {
            return nil
        }else {
            valorCela = taulaDeConsumsMesos[0].filesConsum![row]!
            cellIdentifier = "MesCellID"
        }
    } else {
        if taulaDeConsumsMesos[1].filesConsum![row] == nil {
            return nil
        }else {
        valorCela = taulaDeConsumsMesos[1].filesConsum![row]!
        cellIdentifier = "ConsumCellID"
        }
    }
    if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: nil ) as? NSTableCellView {
        cell.textField?.doubleValue = valorCela
        return cell
    }
    return nil

}

}

推荐答案

表视图不支持选择单个单元格.两种样式的表格视图均支持选择行.基于旧式NSCell的表视图支持选择列,但是基于现代视图的表视图不再支持选择列.但是,从来没有selectedRowselectedColumn同时有效的情况.

Table views do not support selecting individual cells. Both styles of table view support selecting rows. Old-style NSCell-based table views support selecting columns, but modern view-based table views no longer support selecting columns. But it would never have been the case that both selectedRow and selectedColumn were valid at the same time.

10.7 AppKit发行说明中,引入了基于视图的表视图的地方:

From the 10.7 AppKit release notes, where view-based table views were introduced:

要获取其文本字段发送了操作的单元格的行和列,应使用tableViewMesos.rowForView(sender)tableViewMesos.columnForView(sender).请特别注意,并不能保证发送action方法的文本字段在选定的行中.因此,不要将其视为已选中.只是被用户操纵的那个.

To get the row and column of the cell whose text field sent the action, you should use tableViewMesos.rowForView(sender) and tableViewMesos.columnForView(sender). Note, especially, that there's nothing guaranteeing that the text field that's sending the action method is in a selected row. So, don't think of it as selected. It's just the one that's been manipulated by the user.

这篇关于如何从NSTableView中选择列和行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 06:11