macos-hig-designer

安装量: 43
排名: #17034

安装

npx skills add https://github.com/designnotdrum/skills --skill macos-hig-designer

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: // 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: 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 // 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) 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 @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 WindowGroup { ContentView ( ) } . handlesExternalEvents ( matching : Set ( arrayLiteral : "main" ) ) . commands { CommandGroup ( replacing : . newItem ) { Button ( "New Document" ) { // Handle new document } . keyboardShortcut ( "n" ) } } Document-Based Apps @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 . 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 . 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 MenuBarExtra ( "App Status" , systemImage : statusIcon ) { VStack ( alignment : . leading , spacing : 8 ) { Text ( "Status: ( status ) " ) . font ( . headline ) Divider ( ) Button ( "Open Main Window" ) { openWindow ( id : "main" ) } Button ( "Quit" ) { NSApplication . shared . terminate ( nil ) } . keyboardShortcut ( "q" ) } . padding ( ) } . menuBarExtraStyle ( . window ) // or .menu for simple dropdown 5. Keyboard Shortcuts Standard macOS Shortcuts Always implement these when applicable: Action Shortcut Implementation New ⌘N .keyboardShortcut("n") Open ⌘O .keyboardShortcut("o") Save ⌘S .keyboardShortcut("s") Close ⌘W .keyboardShortcut("w") Undo ⌘Z .keyboardShortcut("z") Redo ⇧⌘Z .keyboardShortcut("z", modifiers: [.command, .shift]) Cut ⌘X .keyboardShortcut("x") Copy ⌘C .keyboardShortcut("c") Paste ⌘V .keyboardShortcut("v") Select All ⌘A .keyboardShortcut("a") Find ⌘F .keyboardShortcut("f") Preferences ⌘, .keyboardShortcut(",") Hide ⌘H System handled Quit ⌘Q System handled Custom Shortcuts Button ( "Toggle Sidebar" ) { toggleSidebar ( ) } . keyboardShortcut ( "s" , modifiers : [ . command , . control ] ) // Function keys Button ( "Refresh" ) { } . keyboardShortcut ( KeyEquivalent . init ( Character ( UnicodeScalar ( NSF5FunctionKey ) ! ) ) ) // Arrow keys Button ( "Next" ) { } . keyboardShortcut ( . rightArrow ) 6. Components with Liquid Glass Control Sizing Size Shape Use Case Mini Rounded rect Compact toolbars, dense UIs Small Rounded rect Secondary controls, sidebars Regular Rounded rect Primary controls (default) Large Capsule Prominent actions Extra Large Capsule + Glass Hero CTAs, onboarding // Size modifiers Button ( "Action" ) { } . controlSize ( . mini ) // Smallest . controlSize ( . small ) // Compact . controlSize ( . regular ) // Default . controlSize ( . large ) // Prominent . controlSize ( . extraLarge ) // Hero (macOS 15+) Buttons // Primary action (prominent) Button ( "Save Changes" ) { } . buttonStyle ( . borderedProminent ) . controlSize ( . large ) // Secondary action Button ( "Cancel" ) { } . buttonStyle ( . bordered ) // Tertiary/link style Button ( "Learn More" ) { } . buttonStyle ( . plain ) . foregroundStyle ( . link ) // Destructive Button ( "Delete" , role : . destructive ) { } . buttonStyle ( . bordered ) // Toolbar button Button { } label : { Label ( "Add" , systemImage : "plus" ) } . buttonStyle ( . borderless ) Text Fields // Standard text field TextField ( "Search" , text : $query ) . textFieldStyle ( . roundedBorder ) // Search field with tokens TextField ( "Search" , text : $query ) . searchable ( text : $query , tokens : $tokens ) { token in Label ( token . name , systemImage : token . icon ) } // Secure field SecureField ( "Password" , text : $password ) . textFieldStyle ( . roundedBorder ) Tables Table ( items , selection : $selection ) { TableColumn ( "Name" , value : \ . name ) . width ( min : 100 , ideal : 150 ) TableColumn ( "Date" ) { item in Text ( item . date , format : . dateTime ) } . width ( 100 ) TableColumn ( "Status" ) { item in StatusBadge ( status : item . status ) } . width ( 80 ) } . tableStyle ( . inset ( alternatesRowBackgrounds : true ) ) . contextMenu ( forSelectionType : Item . ID . self ) { selection in Button ( "Open" ) { } Button ( "Delete" , role : . destructive ) { } } Popovers and Sheets // Popover Button ( "Info" ) { showPopover = true } . popover ( isPresented : $showPopover , arrowEdge : . bottom ) { InfoView ( ) . frame ( width : 300 , height : 200 ) . padding ( ) } // Sheet . sheet ( isPresented : $showSheet ) { SheetContent ( ) . frame ( minWidth : 400 , minHeight : 300 ) } // Alert . alert ( "Delete Item?" , isPresented : $showAlert ) { Button ( "Cancel" , role : . cancel ) { } Button ( "Delete" , role : . destructive ) { deleteItem ( ) } } message : { Text ( "This action cannot be undone." ) } 7. Typography & Colors System Typography // Semantic styles (preferred) Text ( "Title" ) . font ( . largeTitle ) // 26pt bold Text ( "Headline" ) . font ( . headline ) // 13pt semibold Text ( "Subheadline" ) . font ( . subheadline ) // 11pt regular Text ( "Body" ) . font ( . body ) // 13pt regular Text ( "Callout" ) . font ( . callout ) // 12pt regular Text ( "Caption" ) . font ( . caption ) // 10pt regular Text ( "Caption 2" ) . font ( . caption2 ) // 10pt regular // Monospaced for code Text ( "let x = 1" ) . font ( . system ( . body , design : . monospaced ) ) Semantic Colors // Foreground . foregroundStyle ( . primary ) // Primary text . foregroundStyle ( . secondary ) // Secondary text . foregroundStyle ( . tertiary ) // Tertiary text . foregroundStyle ( . quaternary ) // Quaternary text // Backgrounds . background ( . background ) // Window background . background ( . regularMaterial ) // Translucent material // Accent colors . tint ( . accentColor ) // App accent color . foregroundStyle ( . link ) // Clickable links // Semantic colors Color . red // System red (adapts to light/dark) Color . blue // System blue Vibrancy and Materials // Materials (adapt to background content) . background ( . ultraThinMaterial ) // Most transparent . background ( . thinMaterial ) . background ( . regularMaterial ) // Default . background ( . thickMaterial ) . background ( . ultraThickMaterial ) // Least transparent // Vibrancy in sidebars List { } . listStyle ( . sidebar ) . scrollContentBackground ( . hidden ) . background ( . ultraThinMaterial ) 8. Spacing & Layout 8-Point Grid System // Standard spacing values VStack ( spacing : 8 ) { } // Standard VStack ( spacing : 16 ) { } // Section spacing VStack ( spacing : 20 ) { } // Group spacing // Padding . padding ( 8 ) // Tight . padding ( 12 ) // Standard . padding ( 16 ) // Comfortable . padding ( 20 ) // Spacious // Content margins . contentMargins ( 16 ) // Uniform margins . contentMargins ( . horizontal , 20 ) // Horizontal only Safe Areas // Respect toolbar safe area . safeAreaInset ( edge : . top ) { ToolbarContent ( ) } // Ignore safe area for backgrounds . ignoresSafeArea ( . container , edges : . top ) // Content that should avoid toolbar . safeAreaPadding ( . top ) Minimum Touch/Click Targets // Minimum 44x44 points for clickable elements Button { } label : { Image ( systemName : "gear" ) } . frame ( minWidth : 44 , minHeight : 44 ) // Use contentShape for larger hit areas RoundedRectangle ( cornerRadius : 8 ) . frame ( width : 200 , height : 100 ) . contentShape ( Rectangle ( ) ) . onTapGesture { } Adaptive Layouts // Responsive to window size GeometryReader { geometry in if geometry . size . width

600 { HStack { content } } else { VStack { content } } } // Grid that adapts LazyVGrid ( columns : [ GridItem ( . adaptive ( minimum : 150 , maximum : 250 ) ) ] , spacing : 16 ) { ForEach ( items ) { ItemView ( item : $0 ) } } 9. Accessibility VoiceOver // Labels and hints Button { } label : { Image ( systemName : "plus" ) } . accessibilityLabel ( "Add item" ) . accessibilityHint ( "Creates a new item in your library" ) // Grouping related elements VStack { Text ( item . title ) Text ( item . subtitle ) } . accessibilityElement ( children : . combine ) // Custom actions . accessibilityAction ( named : "Delete" ) { deleteItem ( ) } Keyboard Navigation // Focus management @FocusState private var focusedField : Field ? TextField ( "Name" , text : $name ) . focused ( $focusedField , equals : . name ) . onSubmit { focusedField = . email } // Focusable custom views . focusable ( ) . onMoveCommand { direction in handleArrowKey ( direction ) } Dynamic Type // Scales with user preference Text ( "Content" ) . dynamicTypeSize ( . large ... . accessibility3 ) // Fixed size when necessary (use sparingly) Text ( "Fixed" ) . dynamicTypeSize ( . large ) Reduce Motion @Environment ( \ . accessibilityReduceMotion ) var reduceMotion . animation ( reduceMotion ? . none : . spring ( ) , value : isExpanded ) // Alternative non-animated transitions . transaction { transaction in if reduceMotion { transaction . animation = nil } } High Contrast @Environment ( \ . colorSchemeContrast ) var contrast // Increase contrast when needed . foregroundStyle ( contrast == . increased ? . primary : . secondary ) 10. Modern API Replacements Deprecated → Modern Deprecated Modern Notes NavigationView NavigationSplitView / NavigationStack Split for macOS, Stack for simple flows .navigationViewStyle(.columns) NavigationSplitView Built-in column support List { }.listStyle(.sidebar) with NavigationLink NavigationSplitView sidebar Proper split view behavior .toolbar { ToolbarItem(...) } in detail .toolbar on NavigationSplitView Toolbar applies to correct scope NSWindowController WindowGroup / Window Pure SwiftUI window management NSMenu / NSMenuItem .commands { } / CommandMenu Declarative menus NSToolbar .toolbar { } SwiftUI toolbar API NSTouchBar .touchBar { } SwiftUI Touch Bar NSOpenPanel.begin() .fileImporter() SwiftUI file dialog NSSavePanel.begin() .fileExporter() SwiftUI save dialog .background(Color.clear) for materials .background(.regularMaterial) Proper material support Custom blur effects .glassEffect() (Tahoe) Native Liquid Glass AppKit Interop (When Needed) // Wrap AppKit view struct NSViewWrapper : NSViewRepresentable { func makeNSView ( context : Context ) -> NSView { // Create and configure NSView } func updateNSView ( _ nsView : NSView , context : Context ) { // Update when SwiftUI state changes } } // Access NSWindow . background ( WindowAccessor { window in window ? . titlebarAppearsTransparent = true } ) 11. Review Checklist Liquid Glass & Materials Sidebars use .glassEffect() or appropriate material Toolbars have translucent appearance Content areas remain clear (not overly translucent) Materials adapt properly to light/dark mode Fallback materials provided for pre-Tahoe Navigation & Windows NavigationSplitView used for multi-column layouts Sidebar has proper min/max width constraints Inspector panel available for detail/properties Window restoration configured Document-based apps use DocumentGroup Multiple window sizes tested Controls & Interaction Control sizes appropriate for context Primary actions use .borderedProminent Destructive actions properly marked with .destructive role Tables have context menus Popovers have appropriate sizing Keyboard & Shortcuts Standard shortcuts implemented (⌘N, ⌘S, ⌘W, etc.) Custom shortcuts don't conflict with system All interactive elements keyboard accessible Focus order logical Menu bar commands have shortcuts Accessibility All images have accessibility labels Custom controls have proper roles VoiceOver tested Keyboard navigation complete Reduce Motion respected High Contrast mode tested Platform Conventions App uses system appearance (not custom chrome) Settings in Preferences window (not separate) File dialogs use system sheets Drag and drop supported where expected Services menu integration (if applicable) Visual Polish 8-point grid alignment Consistent spacing throughout Semantic colors used (adapts to themes) Typography follows SF Pro guidelines Minimum 44pt touch targets Quick Reference: Control Shapes by Size ┌─────────────────────────────────────────────────────┐ │ Mini/Small/Medium │ Large/XLarge │ │ ┌──────────────────┐ │ ╭──────────────────╮ │ │ │ Rounded Rect │ │ │ Capsule │ │ │ └──────────────────┘ │ ╰──────────────────╯ │ │ │ │ │ Compact layouts │ Hero actions │ │ Toolbars, sidebars │ Onboarding, CTAs │ └─────────────────────────────────────────────────────┘ Quick Reference: Window Styles ┌─────────────────────────────────────────────────────┐ │ .automatic Standard window with titlebar │ │ .hiddenTitleBar Full content, titlebar hidden │ │ .plain No chrome, utility panels │ │ .unified Toolbar merges with titlebar │ │ .unifiedCompact Compact unified toolbar │ └─────────────────────────────────────────────────────┘ Quick Reference: Navigation Patterns ┌─────────────┬───────────────┬─────────────────────┐ │ Sidebar │ Content │ Detail │ │ │ │ │ │ Source │ List or │ Selected item │ │ List │ Grid │ properties │ │ │ │ │ │ Collections│ Items │ Inspector panel │ │ Folders │ Browse │ Edit view │ │ │ │ │ │ Min: 180 │ Flexible │ Min: 300 │ │ Max: 300 │ │ Ideal: 400+ │ └─────────────┴───────────────┴─────────────────────┘ NavigationSplitView (three-column)

返回排行榜