Skip to content

0.4.0

Choose a tag to compare

@Mx-Iris Mx-Iris released this 06 Sep 00:55
· 7 commits to main since this release

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 — an NSBrowser whose columns lay out rows as views. Everything else about
    NSBrowser is unchanged: the same item data source methods, the same column and selection
    behaviour, the same public API. Rows are asked for from the delegate as NSViews, 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
    single NSDiffableDataSourceSectionSnapshot. 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 a Hashable struct works as it does everywhere else.

    Passing a stock NSBrowser is 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
    loadView returns. AppKit builds the column's clip view from that frame and never consults the Auto
    Layout fitting size, so a view made with NSView() plus a height constraint renders as no header.
  • rowHeight and 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. Setting rowHeight on 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:NO still animated moves. The inserts and removals were passed
    NSTableViewAnimationEffectNone, but moveItemAtIndex:inParent:toIndex:inParent: takes no
    animation argument and animates implicitly under whatever NSAnimationContext is 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