AppKit UI patterns for LinkSwitch: layout with NSStackView, semantic colors, dynamic layer updates, card views, and accessibility. Use when building or editing NSViewController, NSView subclasses, or any UI code in this app.
This app is AppKit-only. No SwiftUI.
4 / 6 / 8 / 12 / 16 / 20 pt. Use NSStackView.spacing and constant offsets from this scale only; no arbitrary nudges.
| Use | Call |
|---|---|
| Section heading | .boldSystemFont(ofSize: NSFont.systemFontSize + 1) |
| Body / control | .systemFont(ofSize: NSFont.systemFontSize) |
| Secondary / caption | .systemFont(ofSize: NSFont.smallSystemFontSize) |
| Emphasis | .systemFont(ofSize: …, weight: .medium/.semibold) |
Always use semantic NSColor so dark mode works without extra code:
.labelColor, .secondaryLabelColor, .tertiaryLabelColorNSColor.separatorColorNSColor.controlAccentColor.withAlphaComponent(0.18)NSColor.controlBackgroundColor.systemOrange; errors: .systemRedNever assign cgColor in init. Override updateLayer() and assign there — AppKit calls it on appearance change:
override func updateLayer() {
super.updateLayer()
layer?.borderColor = NSColor.separatorColor.cgColor
}
Pattern used throughout: wantsLayer = true, cornerRadius = 10, borderWidth = 1, border color via updateLayer(). Content stack has 16 pt inset on all sides.
translatesAutoresizingMaskIntoConstraints = false on every view added with addSubview.widthAnchor.constraint(equalTo: …)).distribution = .fillEqually for side-by-side equal cards.NSView with low hugging priority) to push controls to opposite ends.NSImage(systemSymbolName: "checkmark.circle.fill", accessibilityDescription: nil)?
.withSymbolConfiguration(NSImage.SymbolConfiguration(pointSize: 28, weight: .regular))
Set contentTintColor on NSImageView for semantic tinting.
setAccessibilityIdentifier("preferences.<control>") on every interactive control.setAccessibilityLabel.cgColor values in init or draw (breaks dark mode).NSColor where a semantic color exists.layoutSubviews-style manual frame math; use Auto Layout constraints.