1

In iOS projects I do something like that:

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 30

and have nicely resizing cells.

What should I do to reproduce the same behaviour in macOS project?


Ok, func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat.

Should I configure my SubView (cell view) (that actually is NSView) twice...

In both methods - heightOfRow and viewFor tableColumn?

I heard about reusing of cells, but can it be done without nibs?

Anyway, if I doing so I get not quite the intended result.

Delegate/Datasource:

let items = ["second label",
             "second label with alotoftext alotof...", // long line
             "second label"]

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

func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
    let cell = SubView(text: items[row])
    cell.layoutSubtreeIfNeeded()
    return cell.frame.size.height
}

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
    return SubView(text: items[row])
}

SubView:

init(text: String) {
    super.init(frame: CGRect.zero)

    let text1 = NSTextField(labelWithString: "first label")
    let text2 = NSTextField(labelWithString: text)

    text2.lineBreakMode = .byWordWrapping
    text2.setContentCompressionResistancePriority(100, for: .horizontal)

    self.addSubview(text1)
    self.addSubview(text2)

    text1 <- [Top(5), Left(5), Right(5)]
    text2 <- [Top(0).to(text1, .bottom), Left(5), Right(5), Bottom(5)]

}

Last two lines are EasyPeasy constraints.

So, result is: wrong

Where is my mistake?


And just one more question: what should I do to make cells grow/decrease vertically to fit all subviews inside of them accordingly to resizing width of tableView?

Oh, seem to have realized.

Just added the observer:

name: NSNotification.Name.NSViewFrameDidChange,
object: self.scrollView

And

let vr = scrollView.contentView.visibleRect
let indexes = tableView.rows(in: vr).toRange()!
tableView.noteHeightOfRows(withIndexesChanged: IndexSet(integersIn: indexes))

in selector method.


Yep. The same view (SubView) works perfect without tableView.

But I still have the above-described problem with wrong-sized cellViews.

P.S.: Sorry for my english, I hope everything is clear.

  • Ok, so your problem is that the cells dont fit the height of the text? – mangerlahn Nov 19 '16 at 16:41
  • @mangerlahn yes, cells much larger than they're should be. Suppose, I have two labels in NSView, that I use as viewFor tableColumn. I want that NSview to fit height of this two labels. – Роман Елизаров Nov 19 '16 at 16:50
  • This NSView (SubView) works exactly as I expect outside of tableView (custom view on another view controller, there are screenshots above). But the same view, when it is in tableView, for some reason has much larger height. – Роман Елизаров Nov 19 '16 at 16:58
  • @mangerlahn I wanna get the same behaviour that you can see here: https://www.dropbox.com/s/iq7je72cig69ng5/cell.mov?dl=0 but with multiple cells in the tableView – Роман Елизаров Nov 19 '16 at 17:23

2 Answers2

1

On macOS it is a little more difficult, but not really hard to do. There is an excellent answer on this by corbin dunn, the author of NSTableView here.

To put it in a nutshell:
You need to know the size of your cell and return that value in

func tableView(NSTableView, heightOfRow: Int)

which is a method from NSTableViewDelegate.

Update 20.11.2016:

You are almost there! The view you create has no width set. So I guess that the view itself assumes that it is much narrower than the tableView and therefore higher.

func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
    let cell = SubView(text: items[row])
    cell.frame.size.width = tableView.frame.size.width
    cell.layoutSubtreeIfNeeded()
    return cell.frame.size.height
}

I have not tested this code but it should be it.

Community
  • 1
  • 1
mangerlahn
  • 4,746
  • 2
  • 26
  • 50
0

I've added my solution (in Swift 3, with view-based NSTableView and Auto-Layout) here: View-based NSTableView with rows that have dynamic heights

Hope that helps you to solve this problem.

Community
  • 1
  • 1
JanApotheker
  • 1,746
  • 1
  • 17
  • 23