Кажется, что мой NSTableView отражает весь контент, который рисует строку.Я никогда не видел ничего подобного раньше и надеюсь, что у кого-нибудь есть совет, как решить эту проблему.Я уже посмотрел, но ничего не смог найти.Я также подал отчет об ошибке, но яблоко не ответило.
Первая идея, которая у меня есть: она должна иметь отношение к отключению NSTextField и NSPopUpButton при запуске.Они включаются только при нажатии на одну ячейку.И когда они включены, текст отображается правильно.Но я не хочу включать их при запуске, чтобы предотвратить изменение значений, случайно щелкнув одну ячейку.
Мой код выглядит нормально и скомпилирован без проблем.
Программа представляет собой простую базу данныхПрограмма, которая берет собственный созданный тип файла и читает его содержимое.Из содержимого он создает объекты базы данных, таблицы, столбца и ячейки во время выполнения для отображения содержимого базы данных.
Вот мой код NSTableView:
import Cocoa
class TableContentViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
@IBOutlet weak var tableContent: NSTableView!
var columnDragFrom:Int = -1
override func viewDidLoad() {
super.viewDidLoad()
tableContent.dataSource = self
tableContent.delegate = self
// Do view setup here.
tableContent.backgroundColor = NSColor(named: "darkColor")!
NotificationCenter.default.addObserver(self, selector: #selector(reloadData(_:)), name: .tableUpdated, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(cellSelection(_:)), name: .cellSelection, object: nil)
tableContent.selectionHighlightStyle = .none
}
@objc func cellSelection(_ notification: Notification) {
if let cell = notification.object as? NSTableCellView {
nxSelectionHandler.currentRow = tableContent.row(for: cell)
nxSelectionHandler.currentColumn = tableContent.column(for: cell)
nxSelectionHandler.highlightCell(sender: tableContent)
}
}
@objc func reloadData(_ notification: Notification) {
setupTable()
tableContent.reloadData()
}
func setupTable() {
tableContent.rowHeight = 30
while(tableContent.tableColumns.count > 0) {
tableContent.removeTableColumn(tableContent.tableColumns.last!)
}
if nxSelectionHandler.currentTable != nil {
for column in (nxSelectionHandler.currentTable?.nxColumns)! {
let newColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(rawValue: column.title))
newColumn.title = column.title
tableContent.addTableColumn(newColumn)
}
}
}
func numberOfRows(in tableView: NSTableView) -> Int {
if nxSelectionHandler.currentTable != nil {
var rowCounts:[Int] = []
for column in (nxSelectionHandler.currentTable?.nxColumns)! {
rowCounts.append(column.nxCells.count)
}
return rowCounts.max()!
}
return 0
}
func tableView(_ tableView: NSTableView, mouseDownInHeaderOf tableColumn: NSTableColumn) {
self.columnDragFrom = tableView.tableColumns.firstIndex(of: tableColumn)!
}
func tableView(_ tableView: NSTableView, didDrag tableColumn: NSTableColumn) {
nxSelectionHandler.currentTable?.nxColumns.swapAt(columnDragFrom, tableView.tableColumns.firstIndex(of: tableColumn)!)
tableView.reloadData()
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let column = tableView.tableColumns.firstIndex(of: tableColumn!)
if nxSelectionHandler.currentTable != nil {
let nxCell = nxSelectionHandler.currentTable?.nxColumns[column!].nxCells[row]
switch nxCell! {
case .nxString(let value):
var StringCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "nxString"), owner: self) as? StringCell
if StringCellView == nil {
tableView.register(NSNib(nibNamed: "StringCellNib", bundle: nil), forIdentifier: NSUserInterfaceItemIdentifier(rawValue: "nxString"))
StringCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "nxString"), owner: self) as? StringCell
}
StringCellView?.textField?.stringValue = value
return StringCellView
case .nxCheckbox(let state):
var CheckboxCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "nxCheckbox"), owner: self) as? CheckboxCell
if CheckboxCellView == nil {
tableView.register(NSNib(nibNamed: "CheckboxCellNib", bundle: nil), forIdentifier: NSUserInterfaceItemIdentifier("nxCheckbox"))
CheckboxCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "nxCheckbox"), owner: self) as? CheckboxCell
}
CheckboxCellView?.column = column!
CheckboxCellView?.row = row
CheckboxCellView?.checkbox.state = state
return CheckboxCellView
case .nxSelection(let selection, let options):
var SelectionCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "nxSelection"), owner: self) as? SelectionCell
if SelectionCellView == nil {
tableView.register(NSNib(nibNamed: "SelectionCellNib", bundle: nil), forIdentifier: NSUserInterfaceItemIdentifier(rawValue: "nxSelection"))
SelectionCellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "nxSelection"), owner: self) as? SelectionCell
}
SelectionCellView?.column = column!
SelectionCellView?.row = row
for option in options {
SelectionCellView?.selection.addItem(withTitle: option)
}
SelectionCellView?.selection.selectItem(at: selection)
return SelectionCellView
}
}
return nil
}
}
Все объекты, используемые в кодеТипы классов и ячейки загружаются из Nibs, где все ячейки имеют ограничения и отображаются правильно.Снимок экрана NSTableView, отображающего неправильное содержимое, можно увидеть ниже.
Код одной из пользовательских ячеек:
import Cocoa
class StringCell: NSTableCellView, NSTextFieldDelegate {
var isSelected: Bool = false {
didSet {
self.needsDisplay = true
}
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
// Drawing code here.
self.textField?.focusRingType = .none
self.textField?.textColor = NSColor.white
self.textField?.delegate = self
self.wantsLayer = true
self.layer?.borderWidth = 2
self.layer?.cornerRadius = 2
if isSelected {
self.layer?.borderColor = NSColor.systemBlue.cgColor
} else {
self.layer?.borderColor = NSColor.clear.cgColor
self.textField?.isEnabled = false
self.textField?.isEditable = false
}
}
override func mouseDown(with event: NSEvent) {
if self.isSelected {
self.textField?.isEditable = true
self.textField?.isEnabled = true
self.textField?.selectText(self)
} else {
self.isSelected = true
NotificationCenter.default.post(name: .cellSelection, object: self)
}
}
func controlTextDidEndEditing(_ obj: Notification) {
if let textField = obj.object as? NSTextField {
nxSelectionHandler.currentCell = nxCell.nxString(textField.stringValue)
}
}
}