What's the right way to put some text vertically centered in a NSTableView's row?
Asked Answered
G

2

11

My OS X app has a NSTableView with larger row height:

myTableView.rowSizeStyle = .large

I try to put some text in it but I found that the text I put in cannot be vertically centered.

Please see the code below. I have three columns and the first two use NSTextField and NSTextView to put some text. The third one is a check box button.

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {

    if (tableColumn?.identifier == "Column1") {

        let field = NSTextField()
        field.stringValue = "someText"
        field.isBordered = false
        field.isEditable = false
        field.backgroundColor = NSColor.red
        return field
    } else if (tableColumn?.identifier == "Column2") {

        let field = NSTextView()
        field.string = "someText"
        field.backgroundColor = NSColor.green
        return field
    } else if (tableColumn?.identifier == "Column3") {

        let field = NSButton()
        field.setButtonType(NSSwitchButton)
        field.title = "check me"
        return field
    }

    return nil
}

My code is pretty much based on Apple's document: "Creating and Configuring an NSTextField Cell".

Here is the result:

enter image description here

As you can see, the texts in the first two columns are not vertically centered while the check box is vertically centered automatically.

When using func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? just like the Apple document has shown, what is the right way to put text so that it can be vertically centered?

EDIT: For some reason, I don't use Interface Builder. So the question sticks to coding the UI programatically.

Geriatric answered 22/6, 2017 at 11:55 Comment(2)
@EricAya I will give it a try, but is it the common way for everyone who wants to do the same? It sounds more complicated than I thought because there should be a lot of people encountering the same issue.Geriatric
@EricAya It's weird that if you ever design an OS X app with NSTableView, wouldn't you run into the same issue?Geriatric
T
6

Simple solution:

Do not create the UI elements in code, do it in Interface Builder. The linked Apple document states:

The most likely situation is that you’ll have designed a cell in Interface Builder and will want to fetch it and then populate the values in that cell

  • For the NSTextView column delete the predefined table cell view and drag an NSTextView instance in the column. Resize the view and add missing AutoLayout constraints.
  • For the second vertically aligned column use the predefined table cell view and add constraints Align Center X and Align Center Y to the NSTextField object.
  • For the checkbox column delete the NSTextField instance in the predefined table cell view, drag a checkbox into the view and add also Align Center Y and the other missing constraints.

It's highly recommended to use Cocoa Bindings to connect the table view to the data source.

This screenshot below uses no code at all except the method

func numberOfRows(in tableView: NSTableView) -> Int {
    return 10
}

enter image description here

Edit:

Alternatively for Column1 – the NSTextField column – wrap the text field in an NSTableCellView instance and specify a frame, for example (a switch statement is swiftier and tableColumn can only be nil if the table view uses also sections / group rows):

   switch tableColumn!.identifier {

    case "Column1":
        let cellView = NSTableCellView()
        // the value for y: in the frame should be row.height / 2 - textField.height / 2
        let field = NSTextField(frame: NSRect(x:0.0, y:10.0, width:tableColumn!.width, height:17.0))
        field.stringValue = "someText"
        field.isBordered = false
        field.isEditable = false
        field.backgroundColor = NSColor.red
        cellView.addSubview(field)
        return cellView

    case "Column2":

        ...

    default: return nil

    }

Note:

Consider that the text in the NSTextView column can only be centered within the text view via NSAttributedString or you have to specify a frame for the enclosing scroll view.

PS: It's so so so much easier in Interface Builder – SCNR.

Tilton answered 24/6, 2017 at 15:26 Comment(2)
well, if using IB, I know how to solve this problem. I have some reason not using IB, so my question really just sticks to coding the UI programatically.Geriatric
Well, then add the AutoLayout constraints programmatically, tooTilton
D
-3

First of all do not create objects pragmatically and if you want to do make a class inherited from TabelviewCell and all of your cell code place in here. After that you must check constrains for cell and feilds you are trying to manage.

It will work fine if you simple add fields on in stroyboard and put constraints on them . try label and make it multiline after fixing horizontal width of it.

Disservice answered 29/6, 2017 at 10:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.