如何使用自定义视单元创建 NSTableview
How to create a NSTableview with custom viewcells
我尝试了很多不同的方法来创建带有自定义 NSTableCellView 的 NSTableview,但我无法让它工作。问题是,我该怎么做呢?
这是我尝试的最后一件事:
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
var cellIdentifier: String = ""
if tableColumn == tableView.tableColumns[0] {
cellIdentifier = "CellID"
if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self ) as? MyTableCellView {
cell.identifier = cellIdentifier
// array is an array that contains NSView with layers with different colors
cell.myView = array[row]
return cell
}
}
return nil
}
添加标签后:
完整代码:
class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
tableview.setDelegate(self)
tableview.setDataSource(self)
let view = NSView(frame: NSRect(x: 0, y: 0, width: 200, height: 200))
view.layer?.backgroundColor = NSColor.blueColor().CGColor
array.append(view)
let view2 = NSView(frame: NSRect(x: 0, y: 0, width: 200, height: 200))
view2.layer?.backgroundColor = NSColor.greenColor().CGColor
array.append(view2)
array2label.append("bu")
array2label.append("buu")
tableview.reloadData()
// Do any additional setup after loading the view.
}
override func viewWillAppear() {
//tableview.reloadData()
laView.layer?.backgroundColor = NSColor.greenColor().CGColor
}
@IBOutlet weak var laView: NSView!
@IBOutlet weak var tableview: NSTableView!
var array = [NSView]()
var array2label = [String]()// = ["bu","buu"]
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
if (tableView.identifier == "Taula") {
return array.count
//return taulaGrafics.count
} else {
return 0
}
}
@IBOutlet weak var viewDeProva: NSView!
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
print ( "Preparem la TableView" )
var cellIdentifier: String = ""
if tableColumn == tableView.tableColumns[0] {
cellIdentifier = "CellID"
if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self ) as? MyTableCellView {
print ( "aqui" )
print(array)
print(array2label)
cell.identifier = cellIdentifier
cell.myView = array[row]
cell.label.stringValue = array2label[row]
return cell
}
}
return nil
}
@IBAction func afegir(sender: NSButton) {
let view = NSView(frame: NSRect(x: 0, y: 0, width: 200, height: 200))
view.layer?.backgroundColor = NSColor.yellowColor().CGColor
array.append(view)
array2label.append("buLabel")
tableview.reloadData()
}
@IBAction func treure(sender: NSButton) {
array.removeLast()
tableview.reloadData()
}
}
if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self ) as? MyTableCellView {
print ( "aqui" )
print(array)
print(array2label)
cell.identifier = cellIdentifier
cell.myView = array[row]
cell.myView.wantsLayer = true
cell.label.stringValue = array2label[row]
return cell
}
通过此更改,视图显示预期的颜色:
class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
print("DidLoad")
tableview.setDelegate(self)
tableview.setDataSource(self)
}
override func viewWillAppear() {
print("WillAppear")
array.append(NSColor.blueColor().CGColor)
array2label.append("buIni")
tableview.reloadData()
laView.layer?.backgroundColor = NSColor.greenColor().CGColor
}
@IBOutlet weak var laView: NSView!
@IBOutlet weak var tableview: NSTableView!
var array = [CGColor]()
var array2label = [String]()
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
if (tableView.identifier == "Taula") {
return array.count
//return taulaGrafics.count
} else {
return 0
}
}
@IBOutlet weak var viewDeProva: NSView!
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
print ( "Preparem la TableView" )
var cellIdentifier: String = ""
if tableColumn == tableView.tableColumns[0] {
cellIdentifier = "CellID"
if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self ) as? MyTableCellView {
print ( "Here" )
print(array)
print(array2label)
cell.identifier = cellIdentifier
cell.myView.layer?.backgroundColor = array[row]
cell.label.stringValue = array2label[row]
return cell
}
}
return nil
}
@IBAction func afegir(sender: NSButton) {
let color = NSColor.yellowColor().CGColor
array.append(color)
array2label.append("buLabel")
tableview.reloadData()
}
@IBAction func treure(sender: NSButton) {
array.removeLast()
array2label.removeLast()
tableview.reloadData()
}
}
问题是 NSTableViewCell 中的 NSView 不能被另一个视图替换,因为你所做的就是改变原型单元格。因此,如果您替换视图,NSTableViewCell 无法识别 NewView 层(我不确定 100% 为什么)。看起来只是共享了一些信息。
那么,我们怎样才能将信息传递给 tableview 单元格呢?我们如何在那里显示图层?好吧,答案是只需修改添加到界面生成器或其子类上的原型单元 NSTableCellView
(如我的情况,请参见单元下方)。在 viewForTableColumn
函数中修改其内容,但不修改 NSView!。在这段代码中看到:
if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self ) as? MyTableCellView {
cell.identifier = cellIdentifier // that is to identify the cell
cell.myView.layer?.backgroundColor = array[row] // see that the array contains CGCOLORS not NSViews
// The program was not showing the colors because the
// view copied doesn't copy its layer, or at least
// doesn't show it.
// Even though, if you say: *******---This is incorrect:
cell.myView = arrayOfNSViews[row] //the program will
// crash when removing 2 rows, myView = nil !!!!.
// That is because when you remove the item of the array
// somehow you are removing myView too, because it make a
// copy or a reference to it (Not sure what exactly).
// Here continues the correct program: ******---
cell.label.stringValue = array2label[row]
return cell
}
另请参阅在 textField 案例中:cell.label.stringValue = array2label[row]
,您更改文本字段的字符串值,而不是整个 NSTextfield
。
所以大家记住并重复我的话:"I'm not going to change the view of the cell, just its properties"。我只花了 4 天就发现了...
这是承诺的 NStableCellView:
class MyTableCellView: NSTableCellView {
@IBOutlet weak var myView: NSView!
@IBOutlet weak var label: NSTextField!
}
视图层次结构的一张图片:
我尝试了很多不同的方法来创建带有自定义 NSTableCellView 的 NSTableview,但我无法让它工作。问题是,我该怎么做呢?
这是我尝试的最后一件事:
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
var cellIdentifier: String = ""
if tableColumn == tableView.tableColumns[0] {
cellIdentifier = "CellID"
if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self ) as? MyTableCellView {
cell.identifier = cellIdentifier
// array is an array that contains NSView with layers with different colors
cell.myView = array[row]
return cell
}
}
return nil
}
添加标签后:
完整代码:
class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
tableview.setDelegate(self)
tableview.setDataSource(self)
let view = NSView(frame: NSRect(x: 0, y: 0, width: 200, height: 200))
view.layer?.backgroundColor = NSColor.blueColor().CGColor
array.append(view)
let view2 = NSView(frame: NSRect(x: 0, y: 0, width: 200, height: 200))
view2.layer?.backgroundColor = NSColor.greenColor().CGColor
array.append(view2)
array2label.append("bu")
array2label.append("buu")
tableview.reloadData()
// Do any additional setup after loading the view.
}
override func viewWillAppear() {
//tableview.reloadData()
laView.layer?.backgroundColor = NSColor.greenColor().CGColor
}
@IBOutlet weak var laView: NSView!
@IBOutlet weak var tableview: NSTableView!
var array = [NSView]()
var array2label = [String]()// = ["bu","buu"]
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
if (tableView.identifier == "Taula") {
return array.count
//return taulaGrafics.count
} else {
return 0
}
}
@IBOutlet weak var viewDeProva: NSView!
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
print ( "Preparem la TableView" )
var cellIdentifier: String = ""
if tableColumn == tableView.tableColumns[0] {
cellIdentifier = "CellID"
if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self ) as? MyTableCellView {
print ( "aqui" )
print(array)
print(array2label)
cell.identifier = cellIdentifier
cell.myView = array[row]
cell.label.stringValue = array2label[row]
return cell
}
}
return nil
}
@IBAction func afegir(sender: NSButton) {
let view = NSView(frame: NSRect(x: 0, y: 0, width: 200, height: 200))
view.layer?.backgroundColor = NSColor.yellowColor().CGColor
array.append(view)
array2label.append("buLabel")
tableview.reloadData()
}
@IBAction func treure(sender: NSButton) {
array.removeLast()
tableview.reloadData()
}
}
if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self ) as? MyTableCellView {
print ( "aqui" )
print(array)
print(array2label)
cell.identifier = cellIdentifier
cell.myView = array[row]
cell.myView.wantsLayer = true
cell.label.stringValue = array2label[row]
return cell
}
通过此更改,视图显示预期的颜色:
class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
print("DidLoad")
tableview.setDelegate(self)
tableview.setDataSource(self)
}
override func viewWillAppear() {
print("WillAppear")
array.append(NSColor.blueColor().CGColor)
array2label.append("buIni")
tableview.reloadData()
laView.layer?.backgroundColor = NSColor.greenColor().CGColor
}
@IBOutlet weak var laView: NSView!
@IBOutlet weak var tableview: NSTableView!
var array = [CGColor]()
var array2label = [String]()
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
if (tableView.identifier == "Taula") {
return array.count
//return taulaGrafics.count
} else {
return 0
}
}
@IBOutlet weak var viewDeProva: NSView!
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {
print ( "Preparem la TableView" )
var cellIdentifier: String = ""
if tableColumn == tableView.tableColumns[0] {
cellIdentifier = "CellID"
if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self ) as? MyTableCellView {
print ( "Here" )
print(array)
print(array2label)
cell.identifier = cellIdentifier
cell.myView.layer?.backgroundColor = array[row]
cell.label.stringValue = array2label[row]
return cell
}
}
return nil
}
@IBAction func afegir(sender: NSButton) {
let color = NSColor.yellowColor().CGColor
array.append(color)
array2label.append("buLabel")
tableview.reloadData()
}
@IBAction func treure(sender: NSButton) {
array.removeLast()
array2label.removeLast()
tableview.reloadData()
}
}
问题是 NSTableViewCell 中的 NSView 不能被另一个视图替换,因为你所做的就是改变原型单元格。因此,如果您替换视图,NSTableViewCell 无法识别 NewView 层(我不确定 100% 为什么)。看起来只是共享了一些信息。
那么,我们怎样才能将信息传递给 tableview 单元格呢?我们如何在那里显示图层?好吧,答案是只需修改添加到界面生成器或其子类上的原型单元 NSTableCellView
(如我的情况,请参见单元下方)。在 viewForTableColumn
函数中修改其内容,但不修改 NSView!。在这段代码中看到:
if let cell = tableView.makeViewWithIdentifier(cellIdentifier, owner: self ) as? MyTableCellView {
cell.identifier = cellIdentifier // that is to identify the cell
cell.myView.layer?.backgroundColor = array[row] // see that the array contains CGCOLORS not NSViews
// The program was not showing the colors because the
// view copied doesn't copy its layer, or at least
// doesn't show it.
// Even though, if you say: *******---This is incorrect:
cell.myView = arrayOfNSViews[row] //the program will
// crash when removing 2 rows, myView = nil !!!!.
// That is because when you remove the item of the array
// somehow you are removing myView too, because it make a
// copy or a reference to it (Not sure what exactly).
// Here continues the correct program: ******---
cell.label.stringValue = array2label[row]
return cell
}
另请参阅在 textField 案例中:cell.label.stringValue = array2label[row]
,您更改文本字段的字符串值,而不是整个 NSTextfield
。
所以大家记住并重复我的话:"I'm not going to change the view of the cell, just its properties"。我只花了 4 天就发现了...
这是承诺的 NStableCellView:
class MyTableCellView: NSTableCellView {
@IBOutlet weak var myView: NSView!
@IBOutlet weak var label: NSTextField!
}
视图层次结构的一张图片: