-2

My NSTableView seems to be mirroring all content which draws a String. I have never seen something like this before and hope somebody has a tip on how to solve this Problem. I already looked it up, but couldn't find anything. I also filed a bug report, but apple didn't respond.

First idea, that I have: It must have something to do with the NSTextField and NSPopUpButton being disabled at start. They are only enabled as soon as you click one cell. And when they are enabled the text gets displayed the right way. But I don't want to enable them at start to prevent changing values by accidentally clicking one cell.

My Code seems to be fine and compiled without problems.

The Program is a simple Database Program which takes an own created file type and reads its content. From the content it creates Database, Table, Column and cell objects at runtime to display the database content.

Here is my NSTableView Code:

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
    }
}

The objects used in the Code are all class types and cells are loaded from Nibs, where the cells all have constraints and are displayed the right way. A Screenshot of the NSTableView displaying the content wrong can be seen below.

Code of one of the custom cells:

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)
        }
    }

}

Screenshot

seb.l95
  • 1
  • 1
  • Please provide a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). – Willeke Feb 13 '19 at 12:24

1 Answers1

-2

Yeah, that's weird. Did you check if you have any active content filters in the View Effects inspector?

View Effects inspector

  • No active content filters.. I did check on every object. Didn't even know what content filters were until now – seb.l95 Feb 13 '19 at 15:52
  • Whats also weird is, that now every time I try to make a screenshot, the text is displayed the right way. When I restart the Program everything is mirrored again. As soon as I start the screenshot program on the mac, it is displayed right again. – seb.l95 Feb 13 '19 at 15:58