Macos Hig Designer
Design native macOS apps following Apple's Human Interface Guidelines and Liquid Glass design system. Use when building SwiftUI/AppKit macOS apps, validating designs, or implementing macOS-specific patterns.
安装 / 下载方式
TotalClaw CLI推荐
totalclaw install clawskills:soponcd~macos-hig-designercURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/clawskills%3Asoponcd~macos-hig-designer/file -o macos-hig-designer.mdGit 仓库获取源码
git clone https://github.com/openclaw/skills/commit/0c23fdfdd7fe2c7abb2a06a7d296a08333430e36# macOS HIG Designer
Design native macOS applications following Apple's Human Interface Guidelines with macOS Tahoe's Liquid Glass design system.
## Workflow Decision Tree
```
User Request
│
├─► "Review my macOS UI code"
│ └─► Run HIG Compliance Check (Section 11)
│ └─► Report violations with fixes
│
├─► "Modernize this macOS code"
│ └─► Identify deprecated APIs
│ └─► Apply Modern API Replacements (Section 10)
│
└─► "Build [feature] for macOS"
└─► Design with HIG principles first
└─► Implement with modern SwiftUI patterns
```
## 1. Design Principles (macOS Tahoe)
### Three Core Tenets
| Principle | Description | Implementation |
|-----------|-------------|----------------|
| **Hierarchy** | Visual layers through Liquid Glass translucency | Use `.glassEffect()`, materials, and depth |
| **Harmony** | Concentric alignment between hardware/software | Round corners, consistent radii, flowing shapes |
| **Consistency** | Platform conventions that adapt to context | Follow standard patterns, respect user preferences |
### Liquid Glass Philosophy
Liquid Glass combines transparency, reflection, refraction, and fluidity with a frosted aesthetic:
```swift
// macOS Tahoe Liquid Glass effect
.glassEffect() // Primary Liquid Glass material
.glassEffect(.regular.tinted) // Tinted variant (26.1+)
// Pre-Tahoe fallback
.background(.ultraThinMaterial)
.background(.regularMaterial)
.background(.thickMaterial)
```
**When to use Liquid Glass:**
- Sidebars, toolbars, and navigation chrome
- Floating panels and popovers
- Dock and widget backgrounds
- System-level UI elements
**When NOT to use:**
- Primary content areas (documents, media)
- Dense data displays (tables, lists with many items)
- Text-heavy interfaces where readability is critical
## 2. Navigation Patterns
### NavigationSplitView (Primary Pattern)
Three-column layout for document-based and content-heavy apps:
```swift
struct ContentView: View {
@State private var selection: Item.ID?
@State private var columnVisibility: NavigationSplitViewVisibility = .all
var body: some View {
NavigationSplitView(columnVisibility: $columnVisibility) {
// Sidebar (source list)
List(items, selection: $selection) { item in
NavigationLink(value: item) {
Label(item.title, systemImage: item.icon)
}
}
.navigationSplitViewColumnWidth(min: 180, ideal: 220, max: 300)
} content: {
// Content column (optional middle)
ContentListView(selection: selection)
} detail: {
// Detail view
DetailView(item: selectedItem)
}
}
}
```
### Sidebar Patterns
```swift
// Source list with sections
List(selection: $selection) {
Section("Library") {
ForEach(libraryItems) { item in
Label(item.name, systemImage: item.icon)
.tag(item)
}
}
Section("Collections") {
ForEach(collections) { collection in
Label(collection.name, systemImage: "folder")
.tag(collection)
.badge(collection.count)
}
}
}
.listStyle(.sidebar)
```
### Inspector Panel (Trailing Sidebar)
```swift
struct DocumentView: View {
@State private var showInspector = true
var body: some View {
MainContentView()
.inspector(isPresented: $showInspector) {
InspectorView()
.inspectorColumnWidth(min: 200, ideal: 250, max: 400)
}
.toolbar {
ToolbarItem {
Button {
showInspector.toggle()
} label: {
Label("Inspector", systemImage: "sidebar.trailing")
}
}
}
}
}
```
## 3. Window Management
### Window Configuration
```swift
@main
struct MyApp: App {
var body: some Scene {
// Main document window
WindowGroup {
ContentView()
}
.windowStyle(.automatic)
.windowToolbarStyle(.unified)
.defaultSize(width: 900, height: 600)
.defaultPosition(.center)
// Settings window
Settings {
SettingsView()
}
// Utility window
Window("Inspector", id: "inspector") {
InspectorWindow()
}
.windowStyle(.plain)
.windowResizability(.contentSize)
.defaultPosition(.topTrailing)
// Menu bar extra
MenuBarExtra("Status", systemImage: "circle.fill") {
StatusMenu()
}
.menuBarExtraStyle(.window)
}
}
```
### Window Styles
| Style | Use Case |
|-------|----------|
| `.automatic` | Standard app windows |
| `.hiddenTitleBar` | Content-focused (media players) |
| `.plain` | Utility windows, panels |
| `.unified` | Integrated toolbar appearance |
| `.unifiedCompact` | Compact toolbar height |
### Window State Restoration
```swift
WindowGroup {
ContentView()
}
.handlesExternalEvents(matching: Set(arrayLiteral: "main"))
.commands {
CommandGroup(replacing: .newItem) {
Button("New Document") {
// Handle new document
}
.keyboardShortcut("n")
}
}
```
### Document-Based Apps
```swift
@main
struct DocumentApp: App {
var body: some Scene {
DocumentGroup(newDocument: MyDocument()) { file in
DocumentView(document: file.$document)
}
.commands {
CommandGroup(after: .saveItem) {
Button("Export...") { }
.keyboardShortcut("e", modifiers: [.command, .shift])
}
}
}
}
struct MyDocument: FileDocument {
static var readableContentTypes: [UTType] { [.plainText] }
init(configuration: ReadConfiguration) throws { }
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { }
}
```
## 4. Toolbar & Menu Bar
### Toolbar Configuration
```swift
.toolbar {
// Leading items (macOS places these before title)
ToolbarItem(placement: .navigation) {
Button(action: goBack) {
Label("Back", systemImage: "chevron.left")
}
}
// Principal (centered)
ToolbarItem(placement: .principal) {
Picker("View Mode", selection: $viewMode) {
Label("Icons", systemImage: "square.grid.2x2").tag(ViewMode.icons)
Label("List", systemImage: "list.bullet").tag(ViewMode.list)
}
.pickerStyle(.segmented)
}
// Trailing items
ToolbarItemGroup(placement: .primaryAction) {
Button(action: share) {
Label("Share", systemImage: "square.and.arrow.up")
}
Button(action: toggleInspector) {
Label("Inspector", systemImage: "sidebar.trailing")
}
}
}
.toolbarRole(.editor) // or .browser, .automatic
```
### Custom Menu Bar
```swift
.commands {
// Replace existing menu group
CommandGroup(replacing: .newItem) {
Button("New Project") { }
.keyboardShortcut("n")
Button("New from Template...") { }
.keyboardShortcut("n", modifiers: [.command, .shift])
}
// Add to existing group
CommandGroup(after: .sidebar) {
Button("Toggle Inspector") { }
.keyboardShortcut("i", modifiers: [.command, .option])
}
// Custom menu
CommandMenu("Canvas") {
Button("Zoom In") { }
.keyboardShortcut("+")
Button("Zoom Out") { }
.keyboardShortcut("-")
Divider()
Button("Fit to Window") { }
.keyboardShortcut("0")
}
}
```
### Menu Bar Apps
```swift
MenuBarExtra("App Status", systemImage: statusIcon) {
VStack(alignment: .leading, spacing: 8) {
Text("Status: \(status)")
.font(.headline)
Divider()