Repository navigation
0.4.0
New
View-based browser columns, and a diffable data source for NSBrowser
AppKit has shipped diffable data sources for NSTableView and NSCollectionView since 10.15, and
this framework added the NSOutlineView one; NSBrowser was the last list class without one. It was
also the only one still drawing rows with NSCell, which ruled out Auto Layout, hosted SwiftUI and
this framework's own content configurations inside a browser row.
-
NSViewBasedBrowser— anNSBrowserwhose columns lay out rows as views. Everything else about
NSBrowseris unchanged: the same item data source methods, the same column and selection
behaviour, the same public API. Rows are asked for from the delegate asNSViews, through the new
NSViewBasedBrowserDelegate(browser:viewForItem:atRow:inColumn:, plus optional row-view and
disclosure-indicator methods). This is the arrangement Finder's column view uses. -
NSBrowserDiffableDataSource<ItemIdentifierType>— describes the whole browsable tree with a
singleNSDiffableDataSourceSectionSnapshot. A browser is a plain tree, so there is no section
layer. It installs itself as the browser's delegate and forwards everything it does not answer to a
delegate of your own, so column titles, sizing and drag-and-drop keep working. A Swift overlay gives
it the usual generic identifier, so aHashablestruct works as it does everywhere else.Passing a stock
NSBrowseris supported: the tree is still published, rows are simply drawn by
cells and the cell provider is never called.
Snapshots are applied with -[NSBrowser reloadColumn:] rather than row-level animation. That is a
deliberate choice, not a stub: AppKit's own item-based column reload restores the selection by item
identity and closes the columns after one whose selection can no longer be restored, both of which
row-level updates would have to reimplement. animatingDifferences is accepted for symmetry and
currently has no effect, so adopting animation later will not change any signature.
Two contracts are easy to get wrong and are documented on the API itself:
- A column header view controller must carry its height in the view's frame by the time
loadViewreturns. AppKit builds the column's clip view from that frame and never consults the Auto
Layout fitting size, so a view made withNSView()plus a height constraint renders as no header. rowHeightand the item-based lookups (itemAtRow:inColumn:,parentForItemsInColumn:,
isLeafItem:,selectionIndexPath) only work once the data source is installed — that is what puts
the browser into item mode. SettingrowHeighton a freshly constructed browser raises.
On any OS where AppKit stops vending the private column-controller class this builds on, columns fall
back to cells rather than failing to launch; NSViewBasedBrowser.isViewBasedColumnSupported reports
which you are getting.
Fixes
applySnapshot:animatingDifferences:NOstill animated moves. The inserts and removals were passed
NSTableViewAnimationEffectNone, butmoveItemAtIndex:inParent:toIndex:inParent:takes no
animation argument and animates implicitly under whateverNSAnimationContextis current — a probe
measured a row view's presentation layer travelling for about 0.3 s in an apply that was supposed to
be instant. Both apply paths now wrap their moves in a zero-duration animation group, the AppKit
counterpart of what UIKit does for its own non-animated apply. Affects both outline data sources.
Compatibility
Everything above is additive. No API was removed, renamed or changed, and no type layout moved, so
existing binaries keep working.
Warning
AppKitPlus is in testing. No API or ABI stability is promised.
Any release may remove classes, change type layouts, or change protocol requirements, with no
deprecation period. Pin an exact version and read these notes before upgrading.
Installation
.package(url: "https://github.com/AppKitSupportProgram/AppKitPlus-Release", from: "0.4.0")Artifact
| Platform | macOS 12.0+ |
| Architectures | arm64, arm64e, x86_64 |
| Built with | Xcode 26.6 Build version 17F113 |
| SHA-256 | 3db462403d5567a416842247f1d61cd2bb9392648a41b4aaef099853899ddba4 |