On macOS Sonoma (23A5312d) there are HTML table layout issues when using an NSAttributedString
in an NSTextView
.
Consider the following Swift code:
override func viewDidLoad() {
super.viewDidLoad()
let html = """
<table width="100%" border="1" style="color: white">
<tr>
<td align="left">Left</td>
<td align="right">Right</td>
</tr>
</table>
"""
let data = Data(html.utf8)
let definition = try! NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: NSNumber(value: String.Encoding.utf8.rawValue)], documentAttributes: nil)
let frameRect = NSRect(x: 100, y: 0, width: 300, height: 200)
let textView = NSTextView(frame: frameRect)
textView.textStorage?.setAttributedString(definition)
textView.backgroundColor = .clear
view.addSubview(textView)
}
On macOS Ventura, it appears like this:
On macOS Sonoma, it appears like this:
On mouse over, the HTML (albeit broken) appears:
This was reported to Apple as FB12800496, and they responded outlining that it was due to "downgrading to TextKit 1 for handling the table contents". They recommended using "TextKit1 NSTextView via init(usingTextLayoutManager:)", the following code resolves the issue of the HTML initially not appearing:
let textView = NSTextView(usingTextLayoutManager: false)
textView.frame = frameRect
Apple Feedback wrote that the layout issue is from "WebKit’s NSAttributedString translation" and that it's handled properly for "TextKit’s internal WebKit1 translator".
Is it possible to invoke the "WebKit1 translator"?
Update 2023-11-01
Following the "Opt out programmatically" instructions in Apple's What's new in TextKit and text views developer video to force TextKit 1 resulted in different layout issues:
It seems that only Apple can fix this, macOS 14.2 (23C64) fixes some TextKit issues but this example now looks like this: