Search code examples
macoscocoanscombobox

Why is NSComboBox content in the incorrect position?


I'm trying to layout an NSComboBox in a Mac app and I'm getting some weird behaviour. In reality I've got a view which has an NSComboBox as a subview along with some other subviews, but I've created a simple example to display the same issue I'm seeing.

For some reason, the text field isn't exactly vertically centered like I'd expect.

Here's my TestComboBox: NSComboBox with text slightly misalligned

Here's an Apple NSComboBox (note the text is vertically centered and there's a small amount of leading spacing before the highlight colour):

An example of Apple's NSComboBox

I've created a simple example to show the issue:

class TestComboBox: NSView {

    private let comboBox = NSComboBox(labelWithString: "")

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

        commonInit()
    }

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

        commonInit()
    }

    private func commonInit() {
        comboBox.isEditable = true
        addSubview(comboBox)
    }

    override func layout() {
        comboBox.sizeToFit()
        comboBox.frame = CGRect(x: 0, y: 0, width: bounds.width, height: comboBox.bounds.height)
    }
}

If you add the above view to a basic Mac app (Storyboard) and pin it to the view controller with the following constraints:

The constraints to set on the view to reproduce issue

I think I'm trying to layout the combo box correctly, but I'm not sure why it looks slightly different to the Apple example as they're both using NSComboBox!

Any guidance much appreciated!


Solution

  • The combo box is initialized with

    private let comboBox = NSComboBox(labelWithString: "")
    

    but init(labelWithString:) is a convenience initializer of NSTextField to create a label. Use init() instead:

    private let comboBox = NSComboBox()