Re: Auto-sized table cells, for macOS
Re: Auto-sized table cells, for macOS
- Subject: Re: Auto-sized table cells, for macOS
- From: Daryle Walker <email@hidden>
- Date: Sat, 18 Mar 2017 02:18:11 -0400
—
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com
> On Mar 17, 2017, at 2:24 PM, Quincey Morris <email@hidden> wrote:
>
> On Mar 17, 2017, at 01:45 , Daryle Walker <email@hidden <mailto:email@hidden>> wrote:
>>
>> I made my first attempt after reading <http://stackoverflow.com/a/32332743/1010226 <http://stackoverflow.com/a/32332743/1010226>>:
>>
>>> // Increase the row height to fit all the text (instead of the first line).
>>> func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
>>> precondition(tableView === self.headerTableView)
>>>
>>> var height = tableView.rowHeight
>>> let nameColumn = tableView.tableColumn(withIdentifier: Names.nameColumnIdentifier)!
>>> let bodyColumn = tableView.tableColumn(withIdentifier: Names.bodyColumnIdentifier)!
>>> let field = (self.headerArrayController.arrangedObjects as! NSArray).object(at: row) as! RawHeaderField
>>> let attributes = [NSFontAttributeName: NSFont.systemFont(ofSize: 0)]
>>> let nameString = NSAttributedString(string: field.name, attributes: attributes)
>>> let bodyString = NSAttributedString(string: field.body, attributes: attributes)
>>> for (string, column) in [(nameString, nameColumn), (bodyString, bodyColumn)] {
>>> let frame = NSRect(x: 0.0, y: 0.0, width: column.width, height: .greatestFiniteMagnitude)
>>> let view = NSTextView(frame: frame)
>>> view.textStorage?.setAttributedString(string)
>>> view.isHorizontallyResizable = false
>>> view.sizeToFit()
>>> height = max(height, view.frame.size.height /*+ 20*/)
>>> }
>>>
>>> return height
>>> }
>
> This isn’t what you want, for two entirely separate reasons.
>
> 1. Assuming you’re using view-based table views (and if you’re not, you really should be), then you don’t want the height of the text, you want the height of the cell (NSTableCellView) that contains your text in a subview. The whole point is that you leverage autolayout to get the NSTableCellView to compute the text height for you. Furthermore, the text is placed *within* the cell, so the height of the NSTableCellView may be bigger than the height of the text, or (in general) the cell might contain other views that need to be taken into account.
>
> 2. You shouldn’t be using a NSTextView, but a NSTextField. A text view typically is placed within a fixed height frame, wrapped in a scroll view, so the concept of an intrinsic height is problematic. What is your actual cell structure, text view or text field?
It’s whatever NSTableCellView uses as a default, so… NSTextField.
…
I just tried something from a recent post by Jeremy Hughes:
//=====
class WrappingTextField: NSTextField {
override var intrinsicContentSize: NSSize {
guard let cell = self.cell, cell.wraps else { return super.intrinsicContentSize }
self.validateEditing()
return cell.cellSize(forBounds: NSRect(x: 0, y: 0, width: self.bounds.width, height: .greatestFiniteMagnitude))
}
override func textDidChange(_ notification: Notification) {
super.textDidChange(notification)
self.invalidateIntrinsicContentSize()
}
}
//=====
I put this class as the table-cell’s type and took out the table delegate but kept the constraints of the text field to match those of the cell. No change (so far). I did debug printouts to the Xcode console, and there are changes. All the sizes from “super" are “(-1.0, 17.0)”, but the new sizes vary in widths and height. The table isn’t using the new values, though.
>> But it only establishes the row heights once, at start but never after any resizes (column or whole-table).
>
> As I said before, you have to watch for column width changes and recalculate your heights accordingly. There is no automatic way of handling variable heights on the Mac that matches the way it can be done on iOS.
>
>> It still is short on some long lines. (Is it because I use word-wrap, instead of by character, for that column?) Also, I hard-coded the font to match what the table has. Is there any way to read what the cell template has? (“NSTableView.view(something)” can generate a view for a given row and column, but Apple specifically barred it (with an assert/exception) during this method.)
>
> Using autolayout on the cell as a whole will avoid all of these issues for the text in particular. You’ll get the metrics as implied by the way your text field is configured.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden