NSTableView With SwiftUI
Edvinas Byla (via Dave Verwer):
The [
LazyVGrid
] user experience isn’t great, but it’s still probably okayish for a version 1.0.0 release. The performance issues are less noticeable with fewer items unless you’re used to high-quality apps. But then there was this one thing that bugged me: the behavior of the context menu.On macOS, right-clicking an item usually selects it and shows the context menu. SwiftUI’s
.contextMenu
shows the menu but doesn’t select or give you any callback for selecting the item. This can be confusing because you don’t know if you’re seeing the menu for the right item.
You’re supposed to be able to use the contextual menu to interact with a list item without changing the selection.
Damn, did [
NSTableView
] feel buttery.[…]
But the main reason for this overhaul wasn’t just the scroll performance. It was also fixing that annoying context menu issue.
[…]
On top of all this, I managed to get rid of some extra code for keyboard navigation, clean up the layout mess, and now I can easily adjust and rearrange columns.
[…]
The remaining part of this post will go over some challenges and gotchas of replacing
LazyVGrid
withNSTableView
while still reusing SwiftUI views.
Lots of good stuff there about using SwiftUI views inside the column headers and table cells.
I don’t want the takeaway to be that SwiftUI is slow and AppKit is fast, or that SwiftUI on macOS isn’t ready for serious apps. In reality, the very complex template editor for this app is almost entirely written in SwiftUI, which handles it impressively well.
SwiftUI is part of the future, it is not “the” future. It is still unclear how sth basic like a text editor can work with the scalability constraints of SwiftUI. Or a List w/ more than 1k items. Everything becomes easier if you start to acknowledge that SwiftUI is a convenience extension to Cocoa, not a replacement in any way. And miraculously SwiftUI also allows super easy integration w/ Cocoa, making sure it is no either or 🙂
having a constant number of
View
s per row (i.e. noif
s) is one of the performance secrets recently explained at 16:25 here.Another is no sorting/filtering in body, e.g. it could be bounced through
onChange
and saved in another state
Previously:
- Mac Dialog in Auto Layout vs. SwiftUI
- Dragging From a List With SwiftUI
- AppKit vs. SwiftUI: Stable vs. Shiny
- SwiftUI Performance Gotchas
- SwiftUI in 2022
Update (2024-04-26): Greg Pierce:
SwiftUI Q: Is there a trick to get lazy generation of a context menu on a list row?
Update (2024-12-10): Stefan Pauwels:
SwiftUI
Table
has serious performance issues on macOS, where it should be at its most useful! :-(
7 Comments RSS · Twitter · Mastodon
It’s not really about “having a constant number of Views per row”. It’s about having a constant number of rows per ForEach element, and SwiftUI Each child of ForEach turns into a row. In the example used in the linked WWDC session (“Demystify SwiftUI performance”), each dog is a ForEach element, and using an if statement in the ForEach means each dog can turn into 0 or 1 views, which means 0 or 1 rows.
> SwiftUI is part of the future, it is not “the” future. It is still unclear how sth basic like a text editor can work with the scalability constraints of SwiftUI. Or a List w/ more than 1k items. Everything becomes easier if you start to acknowledge that SwiftUI is a convenience extension to Cocoa, not a replacement in any way. And miraculously SwiftUI also allows super easy integration w/ Cocoa, making sure it is no either or 🙂
Well, who made the bold declaration about what’s the future, what’s the past. Why say we’re building SwiftUI on top of a solid foundation of AppKit when it sounds cooler if you say we’re just gonna nuke that shit eventually and build on the ashes and you’re a fucking dumb dumb if you still make Appkit apps. I say to those who want a SwiftUI only future, be careful what you wish for. That means Apple is gonna keep all the good shit for themselves as private API (assuming they are capable of making good shit still). It’s hard to imagine why the Mac App Store gets like two news apps a month now.
@ObjC4Life Yes, the messaging has been awful and actively misleading.
So I was just looking around again to see whether I could find a good first-party Mac app using SwiftUI. I know Shortcuts is not good, so I opened Weather. The Tab loop and arrow key navigation don’t work properly, and the Settings window uses pop-down menus instead of pop-up menus.
Michael:
> You’re supposed to be able to use the contextual menu to interact with a list item without changing the selection.
Just to clarify:
While that's true (easy to test in Finder: Select several items, then right-click on a different one, which keeps the original selection), it still needs to give feedback about the context, which the Finder does by highlighting the clicked item, for instance. Right?
> The Tab loop and arrow key navigation don’t work properly, and the Settings window uses pop-down menus instead of pop-up menus.
In System Settings to connect to a Wifi network you just don’t select the table view cell like you’d expect. Instead they hide the “Connect” button until you hover over the table view cell. Who would even think to do something so dumb? In AppKit implementing on hover is kind of a pain but it probably should be that way.
@ObjC4Life They do that in the new Screen Sharing app, too. It also no longer works with LaunchBar, and the checkbox state indicators in the View menu don’t work.