Autosizing text field: NSCell.cellSize(forBounds:) doesn't respect wrapped text unless using attributed string

I'm trying to implement a text field in a table view that automatically adjusts its height to fit the contained text. My current implementation adjusts its intrinsicContentSize in textDidChange(_:). Unfortunately, NSCell.cellSize(forBounds:) doesn't seem to return the correct height unless setting attributedStringValue and allowsEditingTextAttributes = true for the NSTextField.

Is this expected, or is there a workaround?

Here is the code:

class ViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {
    
    var asdf = "asdf fjdskalöf öf fjkldösa jfklödsa kfljsaödkfj klsdajf kldöasj flkjsdöa fkljasö flkjsa öj "

    override func loadView() {
        view = NSView(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
        let scrollView = NSScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        let tableView = NSTableView()
        tableView.usesAutomaticRowHeights = true
        tableView.addTableColumn(NSTableColumn())
        tableView.dataSource = self
        tableView.delegate = self
        scrollView.documentView = tableView
        view.addSubview(scrollView)
        NSLayoutConstraint.activate([scrollView.topAnchor.constraint(equalTo: view.topAnchor), scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor)])
    }
    
    func numberOfRows(in tableView: NSTableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        let view = NSTableCellView()
        let text = AutoSizingTextField()
        text.translatesAutoresizingMaskIntoConstraints = false
        text.cell?.wraps = true
//        uncommenting the next 2 lines and commenting out the line after them solves the issue
//        text.attributedStringValue = NSAttributedString(string: asdf, attributes: [.font: text.font!, .foregroundColor: NSColor.labelColor])
//        text.allowsEditingTextAttributes = true
        text.stringValue = asdf
        view.addSubview(text)
        NSLayoutConstraint.activate([text.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), text.topAnchor.constraint(equalTo: view.topAnchor, constant: 20), text.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20), text.widthAnchor.constraint(equalToConstant: 200)])
        return view
    }

}

class AutoSizingTextField: NSTextField {
    
    override var intrinsicContentSize: NSSize {
        var size = super.intrinsicContentSize
        guard let cell = cell else {
            return size
        }
        var frame = frame
        frame.size.height = .infinity
        size.height = cell.cellSize(forBounds: frame).height
        NSLog("intrinsicContentSize \(size)")
        return size
    }
    
    override func textDidChange(_ notification: Notification) {
        super.textDidChange(notification)
        invalidateIntrinsicContentSize()
        needsLayout = true
        layoutSubtreeIfNeeded()
    }
    
    override func layout() {
        invalidateIntrinsicContentSize()
        super.layout()
    }
    
}
Autosizing text field: NSCell.cellSize(forBounds:) doesn't respect wrapped text unless using attributed string
 
 
Q