mica
mica

Reputation: 4308

NSTableview inside NSPopover looks different as standalone

I created a class ListView, that is a very simple Tableview.

If I instantiate it with IB everything looks fine. The same if I instantiate it programmatically.

If I instantiate it programmatically inside a NSPopover, I get a light grey background for every row of my table.

enter image description here

Where does this come from?

Here the code:

class ViewController: NSViewController {
    let popover = NSPopover()

    @IBOutlet weak var label: NSTextField!
    @IBAction func bu1(_ sender: Any) { 
        popover.show(relativeTo: label.visibleRect, of: label, preferredEdge: NSRectEdge.maxY)
    }

    override func viewDidLoad() { 
        super.viewDidLoad()

        let scrollListView = NSScrollView()
        let listView = ListView(frame: NSRect(x:100, y: 100, width: 100, height: 100))
        scrollListView.documentView = listView

        let viewController = NSViewController()
        viewController.view = scrollListView

        popover.appearance = NSAppearance(named: NSAppearance.Name.vibrantLight)
        popover.animates = false
        popover.contentViewController = viewController
    }
}

class ListView: NSTableView, NSTableViewDataSource, NSTableViewDelegate { 
    private var list = ["Tom","Jack","Susi"]

    required init?(coder: NSCoder) { 
        super.init(coder: coder)
        setup()
    }

    override init(frame frameRect: NSRect) { 
        super.init(frame: frameRect)
        setup()
    }

    private func setup() { 
        selectionHighlightStyle = NSTableView.SelectionHighlightStyle.regular
        rowSizeStyle = NSTableView.RowSizeStyle.small
        intercellSpacing = NSMakeSize(10.0, 0.0)
        headerView = nil
        target = self

        backgroundColor = NSColor.white
        for column in tableColumns { 
            removeTableColumn(column)
        }
        let column1 = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(rawValue: "text"))
        column1.isEditable = false
        column1.width = 200
        addTableColumn(column1)

        delegate = self
        dataSource = self

        self.reloadData()
    }

    func numberOfRows(in tableView: NSTableView) -> Int { 
        return list.count
    }

    func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? { 
        return NSTableRowView()
    }

    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        var cellView = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "MyView"), owner: self) as? NSTableCellView
        if cellView == nil { 
            cellView = NSTableCellView(frame: NSZeroRect)
            let textField = NSTextField(frame: NSZeroRect)
            textField.isBezeled = false
            textField.drawsBackground = false
            textField.isEditable = false
            textField.isSelectable = false
            cellView!.addSubview(textField)
            cellView!.textField = textField
            cellView!.identifier = NSUserInterfaceItemIdentifier(rawValue: "MyView")
        }
        cellView!.textField!.stringValue = list[row]

        return cellView
    }
}

Upvotes: 5

Views: 888

Answers (2)

alexkaessner
alexkaessner

Reputation: 2908

I recently came across this problem and couldn't find a satisfying solution.

The way I managed to do it now is wrapping the NSTableView inside an NSEffectView and set the state to inactive, view as pointed out here: https://christiantietze.de/posts/2017/06/nssplitviewcontroller-visual-effects/ (I have done this in IB)

It does work fine for the normal/aqua appearance. Sadly in the dark appearance the TableView section headers are transparent for some reason. I'm curious to see how it will look on Mojave with the system wide dark mode.

Upvotes: 1

Loeribas
Loeribas

Reputation: 11

I have the same problem. The issue appears in fact in all items I place inside a NSPopover. Setting the appearance to aqua, popover.appearance = NSAppearance(named: NSAppearance.Name.aqua), resolves the issue a bit. But now the popover isn't updated when you change between light and dark mode...

Upvotes: 0

Related Questions