Repository navigation
0.6.0
New
Hover and cursor interactions for any view. Both attach with addInteraction(_:).
NSCursorInteraction(cursor:)shows a cursor while the pointer is over the view. It takes part in
AppKit's own cursor updates, so a subview that manages its own cursor — a text view's I-beam, a split
view's divider — keeps it over its own area. Like every cursor AppKit manages, it changes only while the
view's window is key.NSHoverAppearanceInteractioncalls a handler with the view and whether it is hovered, each time that
changes. It handles what a plainNSTrackingArealeaves to you: a pointer already inside when the view
is attached or shown, a view hidden or removed while hovered, a table cell removed and re-added during
reuse, and — withactiveScopeset to.inKeyWindowor.inActiveApp— the window losing key status
or the app deactivating. A non-zeroanimationDurationruns the handler inside an animation; changes
made directly to the view's layer are not animated, so animatealphaValueinstead.
The UIGeometry.h helpers AppKit lacks, under UIKit's names and with UIKit's behaviour: string round
trips for CGAffineTransform, CGVector, NSEdgeInsets and NSDirectionalEdgeInsets (plus UIKit's
spellings for points, sizes and rects), NSValue boxing, keyed NSCoder coding, and
NSEdgeInsetsInsetRect. Swift gets UIKit's spellings — rect.inset(by:), NSCoder.string(for:),
NSCoder.cgAffineTransform(for:), NSValue(cgAffineTransform:), coder.encode(_:forKey:) — and .zero,
Equatable and Codable on both edge-inset types.
NSAction can be subclassed in Swift. Its designated initialiser init(identifier:handler:) is now
public (-initWithIdentifier:handler: in Objective-C). A subclass that declares an initialiser of its
own also implements required init?(coder:).
Fixes
NSBezierPath's UIKit-style shapes changed once MapKit was loaded. MapKit, PencilKit and AnnotationKit
define some of the same NSBezierPath selectors, and opening a context menu loads all three (observed on
macOS 26 and 27). From then on rounded rectangles lost UIKit's continuous corners, quadratic curves were
stored as cubics and arcs could differ slightly — from Swift as well. The members no longer live on
NSBezierPath's method list, so no framework can take them over; see Breaking. Present since 0.5.0.
Configured buttons carried state between updates. After its first click a button kept the accent tint
for good, and a button that had been disabled stayed grey once enabled again. A key equivalent or
destructive flag you set on the button yourself was cleared at its first state change; a role now takes
back only what it wrote. An update that changes nothing no longer invalidates the button's intrinsic
size; it used to do so six times, twelve per click. Present in every earlier release.
imageColorTransformer broke symbol sizing. The symbol was redrawn into a bitmap, so
preferredSymbolConfigurationForImage stopped sizing it — an image-only button with a 40 pt star came out
41 points wide instead of 69. A symbol image now stays a symbol and takes the colour as its palette
colour; the same goes for alternateImageColorTransformer.
Secure archives of actions and menus came back nil. Archiving with requiresSecureCoding failed for
an NSContentUnavailableConfiguration whose button properties held a primaryAction or a menu, and for
every NSViewAccessoryPopUpMenu. NSAction now adopts NSSecureCoding and archives as UIAction does:
the identifier is kept and the handler is not, so a decoded action does nothing when performed;
NSDocumentLaunchAction also keeps its title, subtitle, image and tint. AppKit's NSMenu does not adopt
NSSecureCoding, so a secure archive leaves menus out and a pop-up menu accessory decoded from one has an
empty menu. Archives made without secure coding keep the menu.
Breaking
- Objective-C reaches the
UIBezierPathmembers throughcompatibility. TheNSBezierPath (PathConstruction)and(Drawing)categories and their headers are gone;NSRectCornerand the new
property are in<AppKitPlus/NSBezierPath+Compatibility.h>, which the umbrella header imports. Write
[path.compatibility addLineToPoint:point]for[path addLineToPoint:point], and
[NSBezierPath.compatibility bezierPathWithRoundedRect:rect cornerRadius:radius]for the class
factories. Swift source is unchanged —NSBezierPath(roundedRect:cornerRadius:),path.addLine(to:). NSActionis the Objective-C class in Swift, not a struct. Pass identifiers as
NSAction.Identifier("open"becomes.init("open")), callremoveAction(identifiedBy:)for
removeAction(forIdentifier:), and name the handler typeNSActionHandlerforNSAction.Handler.
NSAction { _ in },addAction(_:),removeAction(_:)andprimaryActionread as before.
NSDocumentLaunchAction's inheritedidentifierandhandlerare now typedNSAction.Identifier?and
NSActionHandler.- Delete your own
EquatableorCodableconformance forNSEdgeInsetsorNSDirectionalEdgeInsets.
The framework now declares both, and the compiler reports a second one as redundant.
Compatibility
Added: NSCursorInteraction, NSHoverAppearanceInteraction (with NSHoverAppearanceHandler and
NSHoverAppearanceActiveScope), the NSGeometryAdditions.h functions and its NSValue and NSCoder
categories, NSBezierPath.compatibility (NSBezierPathCompatibility, NSBezierPathCompatibilityFactory)
and -[NSAction initWithIdentifier:handler:]. Code built against 0.5.0 that uses NSAction from Swift, or
the UIBezierPath members from either language, must be recompiled: the struct's symbols and the 13
category methods are gone from the binary. Nothing else public was removed. The minimum deployment target
stays macOS 12.0.
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.6.0")Artifact
| Platform | macOS 12.0+ |
| Architectures | arm64, arm64e, x86_64 |
| Built with | Xcode 27.0 Build version 27A266a |
| SHA-256 | 6c1d0b5db3307b9ef0142d8e454b8e03b5ec886aa2d7d1ce001a464bedabfdcc |