我已经在代码中成功创建了基于单元格的NSTableView。我想让单元格更有趣,我已经读过我需要创建一个基于视图的NSTableView。
我的教程如this。
我的UI的其余部分完全是代码。我一直试图为这个tableview做同样的事情而没有太多运气。
以下是我如何定义TableView - 我需要停止注册Nib,我不知道如何:
let nib = NSNib(nibNamed: "TransactionCellView", bundle: NSBundle.mainBundle())
tableOfTransactions.registerNib(nib!, forIdentifier: "TransactionCellView")
tableOfTransactions.headerView = nil
tableOfTransactions.setDelegate(self)
tableOfTransactions.setDataSource(self)
tableOfTransactions.reloadData()
以下是每个单元格的存根代码:
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView?{
var testCell = NSView()
testCell.frame = NSRect(x: 0, y: 0, width: 300, height: 200)
return testCell
}
如何实现这一点的任何指示或建议都将非常感谢!
答案 0 :(得分:7)
-tableView(_:viewForTableColumn:row:)
的实现应如下所示:
func tableView(tableView: NSTableView,
viewForTableColumn
tableColumn: NSTableColumn?,
row: Int) -> NSView? {
var retval: NSView?
if let spareView = tableView.makeViewWithIdentifier("CodeCreatedTableCellView",
owner: self) as? NSTableCellView {
// We can use an old cell - no need to do anything.
retval = spareView
} else {
// Create a text field for the cell
let textField = NSTextField()
textField.backgroundColor = NSColor.clearColor()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.bordered = false
textField.controlSize = NSControlSize.SmallControlSize
// Create a cell
let newCell = NSTableCellView()
newCell.identifier = "CodeCreatedTableCellView"
newCell.addSubview(textField)
newCell.textField = textField
// Constrain the text field within the cell
newCell.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat("H:|[textField]|",
options: [],
metrics: nil,
views: ["textField" : textField]))
newCell.addConstraints(
NSLayoutConstraint.constraintsWithVisualFormat("V:|[textField]|",
options: [],
metrics: nil,
views: ["textField" : textField]))
textField.bind(NSValueBinding,
toObject: newCell,
withKeyPath: "objectValue",
options: nil)
retval = newCell
}
return retval
}
如果您的表包含数百行,Cocoa将尝试重用已创建的视图,但不再显示在屏幕上。此代码段的第一部分使用NSTableView
方法查找此类视图。如果找不到,则需要从头开始创建一个。
如果您没有理由不这样做,则应使用NSTableCellView
的实例(或子类)作为您的观点。它并没有给NSView
增加太多,但它的一个关键特性是它保留了对视图所代表的模型的引用(由-tableView(_:objectValueForTableColumnRow:row:)
设置)。在此示例中,我使用此功能使用绑定设置文本字段的字符串值。
另一点需要注意的是,您应该为视图提供一个标识符,该标识符与您为视图所在的NSTableColumn
提供的标识符相匹配。这样做可以使您的表视图使用上面讨论的可重用视图功能。
答案 1 :(得分:1)
这在我尝试对没有IB和Nibs的滚动表进行编程时非常有用。这是我的玩具版本,已更新为Swift 4.2。
自定义单元格视图子类仅在这里让我看到单元格实际上已被重复使用,
import Cocoa
class DIYTableViewDataSource: NSObject, NSTableViewDataSource {
func numberOfRows(in tableView: NSTableView) -> Int {
return 25
}
}
class CustomTableCellView: NSTableCellView {
var count = 1
}
func createCell(_ id: NSUserInterfaceItemIdentifier) -> CustomTableCellView {
// Create a text field for the cell
let textField = NSTextField()
textField.backgroundColor = NSColor.clear
textField.translatesAutoresizingMaskIntoConstraints = false
textField.isBordered = false
// Create a cell
let cell = CustomTableCellView() // Doing this to see that cells get re-used
cell.identifier = id
cell.addSubview(textField)
cell.textField = textField
// Constrain the text field within the cell
textField.widthAnchor.constraint(equalTo: cell.widthAnchor).isActive = true
textField.heightAnchor.constraint(equalTo: cell.heightAnchor).isActive = true
textField.bind(NSBindingName.value, to: cell, withKeyPath: "objectValue", options: nil)
return cell
}
class DIYTableViewDelegate: NSObject, NSTableViewDelegate {
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let id = tableColumn!.identifier
var view = tableView.makeView(withIdentifier: id, owner: nil) as? CustomTableCellView
if view == nil {
view = createCell(id)
}
view!.textField!.stringValue = "\(id.rawValue) \(row) \(view!.count)"
view!.count += 1
return view
}
}
答案 2 :(得分:0)
斯威夫特 5
你需要实现 NSTableView 的委托方法。无需注册任何nib文件?
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let view = CustomView()
view.configure(with: row)
return view
}
只需创建自定义视图的实例(NSView 的子类)。 它看起来像这样:
class CustomView: NSView {
private let label = NSTextField()
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
setupView()
}
required init?(coder: NSCoder) {
fatalError("init coder has not been implemented")
}
func setupView() {
self.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
label.topAnchor.constraint(equalTo: self.topAnchor, constant: 8),
label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 8),
label.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 8),
label.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 8)
])
}
func configure(with row: Int) {
label.stringValue = String(describing: row + 1)
}
}