Install
$ agentstack add skill-vabole-apple-skills-ios-liquid-glass ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
iOS Liquid Glass Design
Create distinctive, Apple Design Award-worthy iOS applications using the Liquid Glass design system. This skill pushes beyond generic implementations toward memorable, polished interfaces that feel genuinely designed—not AI-generated.
When to Use
- Building new iOS screens, views, or components
- Implementing navigation (tabs, toolbars, sheets)
- Designing with Liquid Glass materials
- Creating app icons with Icon Composer
- Any SwiftUI/UIKit work targeting iOS 26+
Design Philosophy: Elevated, Not Average
Before writing code, commit to a distinctive aesthetic direction:
- Purpose: What problem does this interface solve? Who uses it?
- Tone: What feeling should it evoke? (calm, playful, premium, editorial, utilitarian, bold)
- Inspiration: Which Apple apps set the bar? (Notes, Weather, Health, Fitness, Apple TV)
- Differentiation: What makes this memorable? What's the "one thing" users will notice?
- Glass Philosophy: Is glass framing content or competing with it?
The Three Principles
| Principle | Description | |-----------|-------------| | Hierarchy | Controls float above content. Glass frames, never obscures. Content is king. | | Harmony | Software design aligns with hardware. Concentric corners. Fluid gestures. | | Consistency | Adapt fluidly across iPhone, iPad, Mac. Same identity, contextual expression. |
Anti-Patterns: What to Avoid
These are hallmarks of generic AI-generated iOS design:
- Boring solid backgrounds with no depth or atmosphere
- System fonts everywhere without typographic intention
- Cookie-cutter tab bars with no personality or purpose
- Purple/indigo gradients on white—the quintessential AI slop
- Flat, lifeless interactions without haptics or animation
- Glass on everything instead of intentional placement
- Ignoring the content layer by applying glass where it doesn't belong
- Generic card layouts without context-specific design
- Accessibility as afterthought instead of built-in from day one
Liquid Glass Core API
Basic Glass Effect
import SwiftUI
// Simple glass application
Text("Action")
.padding()
.glassEffect() // .regular variant, .capsule shape
// With explicit parameters
Button("Confirm") { }
.padding()
.glassEffect(.regular, in: RoundedRectangle(cornerRadius: 12), isEnabled: true)
Glass Variants
| Variant | Use Case | |---------|----------| | .regular | Toolbars, nav bars, tab bars, standard controls | | .clear | Floating controls over media (photos, maps, video) | | .identity | Conditional disable: glassEffect(isActive ? .regular : .identity) |
Glass Modifiers
// Semantic tinting (for primary actions only)
.glassEffect(.regular.tint(.accentColor))
// Interactive behaviors (scaling, shimmer, touch illumination)
.glassEffect(.regular.interactive())
// Combined
.glassEffect(.regular.tint(.blue).interactive())
Custom Shapes
// Standard shapes
.glassEffect(.regular, in: .capsule)
.glassEffect(.regular, in: .circle)
.glassEffect(.regular, in: RoundedRectangle(cornerRadius: 16))
// Container-concentric (matches device/container corners)
.glassEffect(.regular, in: .rect(cornerRadius: .containerConcentric))
GlassEffectContainer & Morphing
Container Setup
Glass cannot sample other glass. Use containers for multiple glass elements:
GlassEffectContainer(spacing: 30) {
HStack(spacing: 20) {
ForEach(actions) { action in
Button(action.title, systemImage: action.icon) { }
.frame(width: 44, height: 44)
.glassEffect(.regular.interactive())
}
}
}
Morphing Transitions
struct ExpandableActions: View {
@State private var isExpanded = false
@Namespace private var namespace
var body: some View {
GlassEffectContainer(spacing: 30) {
VStack(spacing: 30) {
if isExpanded {
ActionButton(icon: "rotate.right")
.glassEffectID("rotate", in: namespace)
}
HStack(spacing: 30) {
if isExpanded {
ActionButton(icon: "slider.horizontal.3")
.glassEffectID("adjust", in: namespace)
}
Button {
withAnimation(.bouncy) { isExpanded.toggle() }
} label: {
Image(systemName: isExpanded ? "xmark" : "plus")
.frame(width: 56, height: 56)
}
.glassEffect(.regular.tint(.accentColor).interactive())
.glassEffectID("toggle", in: namespace)
if isExpanded {
ActionButton(icon: "crop")
.glassEffectID("crop", in: namespace)
}
}
if isExpanded {
ActionButton(icon: "wand.and.stars")
.glassEffectID("enhance", in: namespace)
}
}
}
}
}
Navigation Patterns
Tab Bar (Floating)
TabView {
Tab("Home", systemImage: "house") {
HomeView()
}
Tab("Search", systemImage: "magnifyingglass") {
SearchView()
}
Tab("Profile", systemImage: "person") {
ProfileView()
}
}
// Tab bar now floats, reacts to background, collapses on scroll
Toolbar with Grouping
.toolbar {
ToolbarItemGroup(placement: .topBarTrailing) {
Button("Edit", systemImage: "pencil") { }
Button("Share", systemImage: "square.and.arrow.up") { }
}
ToolbarSpacer(.flexible, placement: .topBarTrailing)
ToolbarItem(placement: .topBarTrailing) {
Button("Done", systemImage: "checkmark") { }
.tint(.accentColor)
}
}
Sheets with Morphing
struct ContentView: View {
@State private var showSettings = false
@Namespace private var namespace
var body: some View {
NavigationStack {
ContentView()
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("Settings", systemImage: "gear") {
showSettings = true
}
.matchedTransitionSource(id: "settings", in: namespace)
}
}
.sheet(isPresented: $showSettings) {
SettingsView()
.navigationTransition(.zoom(sourceID: "settings", in: namespace))
.presentationDetents([.medium, .large])
}
}
}
}
Typography That Speaks
Don't default to system fonts everywhere. Create typographic hierarchy:
// Display fonts for headers
Text("Dashboard")
.font(.largeTitle.bold())
.foregroundStyle(.primary)
// Secondary information
Text("Last updated 5 min ago")
.font(.subheadline)
.foregroundStyle(.secondary)
// Consider custom fonts for brand identity
Text("Premium")
.font(.custom("PlayfairDisplay-Bold", size: 32))
Font Recommendations
| Use Case | Options | |----------|---------| | Display | SF Pro Display, New York, custom serif | | Body | SF Pro Text (system), custom sans | | Technical | SF Mono, custom monospace | | Editorial | New York, custom serif with character |
Color with Intention
System Integration
// Semantic colors that adapt
.foregroundStyle(.primary)
.foregroundStyle(.secondary)
.background(.background)
// Accent with purpose
.tint(.accentColor)
Dominant + Accent
Don't distribute color evenly. Choose:
- One dominant that defines the brand/mood
- Sharp accents for actions and highlights
- Neutral base for content readability
Dark Mode First
Dark mode often produces more distinctive results. Design dark, then adapt to light.
Animation Philosophy
Bouncy is the New Default
withAnimation(.bouncy) {
isExpanded.toggle()
}
// With parameters
withAnimation(.bouncy(duration: 0.5, extraBounce: 0.2)) {
state = newState
}
Key Animation Moments
| Moment | Treatment | |--------|-----------| | Button press | Scale to 0.95, spring back | | State change | Morph, don't swap | | List appear | Staggered fade-in | | Sheet present | Zoom from source | | Error | Shake with haptic |
SF Symbols Draw Animations
Image(systemName: "checkmark.circle")
.symbolEffect(.drawOn, value: isComplete)
Image(systemName: "heart.fill")
.symbolEffect(.bounce, value: isFavorite)
Haptics: The Invisible Polish
import UIKit
// Impact feedback
let generator = UIImpactFeedbackGenerator(style: .medium)
generator.impactOccurred()
// Selection feedback
let selection = UISelectionFeedbackGenerator()
selection.selectionChanged()
// Success/error
let notification = UINotificationFeedbackGenerator()
notification.notificationOccurred(.success)
When to Use Haptics
- Button presses (light impact)
- Toggle changes (selection changed)
- Pull to refresh (light impact)
- Error states (error notification)
- Success confirmations (success notification)
- Slider thumb movement (selection changed)
Accessibility: Built-In, Not Bolt-On
Automatic Glass Adaptations
Glass automatically adapts to:
- Reduce Transparency: More frosting
- Increase Contrast: Stark borders
- Reduce Motion: Tones down animation
Manual Checks
@Environment(\.accessibilityReduceTransparency) var reduceTransparency
@Environment(\.accessibilityReduceMotion) var reduceMotion
var animation: Animation? {
reduceMotion ? nil : .bouncy
}
Essentials
- Minimum 44x44pt touch targets
- Clear accessibility labels
- Dynamic Type support
- VoiceOver testing
Quality Checklist
Before considering UI complete:
- [ ] Glass applied only to navigation layer (not content)
- [ ] Haptics on all meaningful interactions
- [ ] Spring/bouncy animations (not linear)
- [ ] SF Symbols (not emojis or random icons)
- [ ] Dark mode tested and polished
- [ ] Typography hierarchy clear and intentional
- [ ] Colors are purposeful, not default blue
- [ ] Morphing transitions where applicable
- [ ] Loading states animated
- [ ] Empty states designed
- [ ] Error states helpful and styled
- [ ] Accessibility settings respected
Inspiration: Award-Winning Patterns
From 2025 Apple Design Award winners:
Delight
- Surprising interactions that reward exploration
- Meaningful animations that enhance understanding
- Playful details creating emotional connection
Innovation
- Novel use of Apple technologies
- Thoughtfully crafted yet accessible UI
- Real-time features that feel magical
Inclusivity
- VoiceOver support from day one
- Dynamic Type throughout
- Multiple input methods
Visuals
- Rich, detailed environments
- Consistent visual language
- Intentional depth and color
Reference
For official Apple documentation links, WWDC session IDs, and API quick reference tables, see [reference.md](reference.md).
The Mandate
Remember: The goal is an app worthy of an Apple Design Award—an app that feels genuinely designed, not generated. Every interface should have:
- A point of view - A clear aesthetic direction
- Intentional details - Nothing accidental
- Emotional resonance - Users feel something
- Technical excellence - Smooth, performant, accessible
Don't settle for "working." Push for memorable.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: vabole
- Source: vabole/apple-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.