옵션
집집 Skill 기타 liquid-glass-design

liquid-glass-design

affaan-m/ECC affaan-m/ECC

SwiftUI, UIKit 및 WidgetKit을 사용하여 동적 유리 소재, 블러, 반사 및 상호작용형 모핑 기능을 통해 iOS 26 이상용 Apple의 Liquid Glass 디자인 시스템을 구현합니다.

...모든 것을 확장하십시오
7
업데이트 된 시간 2026년 10월 12일

리퀴드 글라스 디자인 시스템 (iOS 26)

애플의 ‘리퀴드 글라스’를 구현하기 위한 패턴 — 리퀴드 글라스는 뒤쪽의 콘텐츠를 흐릿하게 만들고, 주변 콘텐츠의 색상과 빛을 반사하며, 터치 및 포인터 상호작용에 반응하는 동적 소재입니다. SwiftUI, UIKit 및 WidgetKit 통합을 다룹니다.

활성화 시점

  • 새로운 디자인 언어를 적용하여 iOS 26 이상용 앱을 구축하거나 업데이트할 때
  • 유리 스타일의 버튼, 카드, 툴바 또는 컨테이너를 구현할 때
  • 유리 요소 간 모핑 전환 효과 생성 시
  • 위젯에 리퀴드 글라스 효과 적용
  • 기존 블러/머티리얼 효과를 새로운 리퀴드 글라스 API로 마이그레이션할 때

핵심 패턴 — SwiftUI

기본 유리 효과

어떤 뷰에든 리퀴드 글래스를 추가하는 가장 간단한 방법:

Text("Hello, World!")
    .font(.title)
    .padding()
    .glassEffect()  // 기본값: 일반 변형, 캡슐 모양

모양 및 색조 사용자 정의

Text("Hello, World!")
    .font(.title)
    .padding()
    .glassEffect(.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 16.0))

주요 사용자 정의 옵션:

  • .regular — 표준 유리 효과
  • .tint(Color) — 눈에 띄게 하기 위해 색상 틴트 추가
  • .interactive() — 터치 및 포인터 상호작용에 반응
  • 도형: .capsule (기본값), .rect(cornerRadius:), .circle

유리 버튼 스타일

Button("Click Me") { /* 동작 */ }
    .buttonStyle(.glass)

Button("Important") { /* 동작 */ }
    .buttonStyle(.glassProminent)

여러 요소를 위한 GlassEffectContainer

성능 및 모핑 효과를 위해 여러 글라스 뷰를 항상 컨테이너로 감싸야 합니다:

GlassEffectContainer(spacing: 40.0) {
    HStack(spacing: 40.0) {
        Image(systemName: "scribble.variable")
            .frame(width: 80.0, height: 80.0)
            .font(.system(size: 36))
            .glassEffect()

        Image(systemName: "eraser.fill")
            .frame(width: 80.0, height: 80.0)
            .font(.system(size: 36))
            .glassEffect()
    }
}

spacing 매개변수는 합쳐지는 거리를 제어합니다. 서로 가까운 요소일수록 유리 모양이 서로 더 잘 어우러집니다.

글라스 효과 결합

glassEffectUnion을 사용하여 여러 뷰를 하나의 유리 모양으로 결합할 수 있습니다:

@Namespace private var namespace

GlassEffectContainer(spacing: 20.0) {
    HStack(spacing: 20.0) {
        ForEach(symbolSet.indices, id: \.self) { item in
            Image(systemName: symbolSet[item])
                .frame(width: 80.0, height: 80.0)
                .glassEffect()
                .glassEffectUnion(id: item < 2 ? "group1" : "group2", namespace: namespace)
        }
    }
}

모핑 전환

유리 요소가 나타나거나 사라질 때 부드러운 모핑 효과를 생성합니다:

@State private var isExpanded = false
@Namespace private var namespace

GlassEffectContainer(spacing: 40.0) {
    HStack(spacing: 40.0) {
        Image(systemName: "scribble.variable")
            .frame(width: 80.0, height: 80.0)
            .glassEffect()
            .glassEffectID("pencil", in: namespace)

        if isExpanded {
            Image(systemName: "eraser.fill")
                .frame(width: 80.0, height: 80.0)
                .glassEffect()
                .glassEffectID("eraser", in: namespace)
        }
    }
}

Button("Toggle") {
    withAnimation { isExpanded.toggle() }
}
.buttonStyle(.glass)

사이드바 아래로 가로 스크롤 확장

가로 스크롤 콘텐츠가 사이드바나 인스펙터 아래로 확장되도록 하려면, ScrollView 콘텐츠가 컨테이너의 앞쪽/뒤쪽 가장자리에 닿도록 해야 합니다. 레이아웃이 가장자리에 닿을 경우 시스템이 자동으로 사이드바 아래 스크롤 동작을 처리하므로, 별도의 수정자가 필요하지 않습니다.

핵심 패턴 — UIKit

기본 UIGlassEffect

let glassEffect = UIGlassEffect()
glassEffect.tintColor = UIColor.systemBlue.withAlphaComponent(0.3)
glassEffect.isInteractive = true

let visualEffectView = UIVisualEffectView(effect: glassEffect)
visualEffectView.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.layer.cornerRadius = 20
visualEffectView.clipsToBounds = true

view.addSubview(visualEffectView)
NSLayoutConstraint.activate([
    visualEffectView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    visualEffectView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    visualEffectView.widthAnchor.constraint(equalToConstant: 200),
    visualEffectView.heightAnchor.constraint(equalToConstant: 120)
])

// contentView에 콘텐츠 추가
let label = UILabel()
label.text = "Liquid Glass"
label.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.contentView.addSubview(label)
NSLayoutConstraint.activate([
    label.centerXAnchor.constraint(equalTo: visualEffectView.contentView.centerXAnchor),
    label.centerYAnchor.constraint(equalTo: visualEffectView.contentView.centerYAnchor)
])

여러 요소에 적용되는 UIGlassContainerEffect

let containerEffect = UIGlassContainerEffect()
containerEffect.spacing = 40.0

let containerView = UIVisualEffectView(effect: containerEffect)

let firstGlass = UIVisualEffectView(effect: UIGlassEffect())
let secondGlass = UIVisualEffectView(effect: UIGlassEffect())

containerView.contentView.addSubview(firstGlass)
containerView.contentView.addSubview(secondGlass)

스크롤 가장자리 효과

scrollView.topEdgeEffect.style = .automatic
scrollView.bottomEdgeEffect.style = .hard
scrollView.leftEdgeEffect.isHidden = true

툴바 글래스 통합

let favoriteButton = UIBarButtonItem(image: UIImage(systemName: "heart"), style: .plain, target: self, action: #selector(favoriteAction))
favoriteButton.hidesSharedBackground = true  // 공유 글래스 배경 비활성화

핵심 패턴 — WidgetKit

렌더링 모드 감지

struct MyWidgetView: View {
    @Environment(\.widgetRenderingMode) var renderingMode

    var body: some View {
        if renderingMode == .accented {
            // 틴트 모드: 흰색 틴트가 적용된 테마형 유리 배경
        } else {
            // 풀 컬러 모드: 표준 외관
        }
    }
}

시각적 계층 구조를 위한 액센트 그룹

HStack {
    VStack(alignment: .leading) {
        Text("Title")
            .widgetAccentable()  // 액센트 그룹
        Text("Subtitle")
            // 기본 그룹 (기본값)
    }
    Image(systemName: "star.fill")
        .widgetAccentable()  // 강조 그룹
}

강조 모드에서의 이미지 렌더링

Image("myImage")
    .widgetAccentedRenderingMode(.monochrome)

컨테이너 배경

VStack { /* 콘텐츠 */ }
    .containerBackground(for: .widget) {
        Color.blue.opacity(0.2)
    }

주요 디자인 결정 사항

결정 사항 근거
GlassEffectContainer 래핑 성능 최적화, 유리 요소 간의 모핑 효과 구현
간격 매개변수 병합 거리를 제어합니다 — 요소가 블렌딩되려면 얼마나 가까워야 하는지 미세 조정
@Namespace + glassEffectID 뷰 계층 구조 변경 시 부드러운 모핑 전환을 지원합니다
interactive() 수정자 터치/포인터 반응에 대한 명시적 활성화 — 모든 유리 요소가 반응할 필요는 없음
UIKit의 UIGlassContainerEffect 일관성을 위해 SwiftUI와 동일한 컨테이너 패턴을 사용합니다
위젯의 액센트 렌더링 모드 사용자가 색상이 적용된 홈 화면을 선택하면 시스템에서 색상이 적용된 유리를 적용합니다

모범 사례

  • 여러 형제 뷰에 유리 효과를 적용할 때는항상 GlassEffectContainer를 사용하십시오. 모핑이 가능해지며 렌더링 성능이 향상됩니다
  • 다른 외관 수정자(frame, font, padding)를적용한 후에 .glassEffect()를 적용하세요
  • .interactive()는 사용자 상호작용에 반응하는 요소(버튼, 토글 가능한 항목)에만사용하십시오
  • 컨테이너 내간격을 신중하게 설정하여 유리 효과가 언제 합쳐질지 제어하십시오
  • 뷰 계층 구조를 변경할 때는 withAnimation을 사용하여 부드러운 모핑 전환을 구현하십시오
  • 라이트 모드, 다크 모드, 액센트/틴트 모드 등다양한 외관 환경에서 테스트하십시오
  • 접근성 대비를 확보하십시오 — 유리 위의 텍스트는 가독성이 유지되어야 합니다

피해야 할 안티패턴

  • GlassEffectContainer 없이 여러 개의 독립적인 .glassEffect() 뷰를 사용하는 것
  • 유리 효과를 지나치게 중첩하는 경우 — 성능 저하 및 시각적 명확성 저하를 초래합니다
  • 모든 뷰에 유리 효과를 적용하는 것 — 상호작용 요소, 툴바 및 카드에만 제한적으로 사용해야 함
  • 모서리 반경을 사용할 때 UIKit에서 clipsToBounds = true를 설정하는 것을 잊는 경우
  • 위젯에서 악센트 렌더링 모드를 무시하는 경우 — 홈 화면의 색조 적용된 외관이 깨짐
  • 글라스 뒤에 불투명한 배경을 사용하는 경우 — 반투명 효과가 무효화됩니다

사용 시점

  • 새로운 iOS 26 디자인을 적용한 내비게이션 바, 툴바 및 탭 바
  • 플로팅 액션 버튼 및 카드 스타일 컨테이너
  • 시각적 깊이와 터치 피드백이 필요한 상호작용형 컨트롤
  • 시스템의 ‘리퀴드 글라스(Liquid Glass)’ 디자인과 통합되어야 하는 위젯
  • 관련된 UI 상태 간의 모핑 전환 효과
GitHub에서 보기
---
name: liquid-glass-design
description: Implement Apple's Liquid Glass design system for iOS 26+ with dynamic glass materials, blur, reflection, and interactive morphing in SwiftUI, UIKit, and WidgetKit.
---

# Liquid Glass Design System (iOS 26)

Patterns for implementing Apple's Liquid Glass — a dynamic material that blurs content behind it, reflects color and light from surrounding content, and reacts to touch and pointer interactions. Covers SwiftUI, UIKit, and WidgetKit integration.

## When to Activate

- Building or updating apps for iOS 26+ with the new design language
- Implementing glass-style buttons, cards, toolbars, or containers
- Creating morphing transitions between glass elements
- Applying Liquid Glass effects to widgets
- Migrating existing blur/material effects to the new Liquid Glass API

## Core Pattern — SwiftUI

### Basic Glass Effect

The simplest way to add Liquid Glass to any view:

```swift
Text("Hello, World!")
    .font(.title)
    .padding()
    .glassEffect()  // Default: regular variant, capsule shape
```

### Customizing Shape and Tint

```swift
Text("Hello, World!")
    .font(.title)
    .padding()
    .glassEffect(.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 16.0))
```

Key customization options:
- `.regular` — standard glass effect
- `.tint(Color)` — add color tint for prominence
- `.interactive()` — react to touch and pointer interactions
- Shape: `.capsule` (default), `.rect(cornerRadius:)`, `.circle`

### Glass Button Styles

```swift
Button("Click Me") { /* action */ }
    .buttonStyle(.glass)

Button("Important") { /* action */ }
    .buttonStyle(.glassProminent)
```

### GlassEffectContainer for Multiple Elements

Always wrap multiple glass views in a container for performance and morphing:

```swift
GlassEffectContainer(spacing: 40.0) {
    HStack(spacing: 40.0) {
        Image(systemName: "scribble.variable")
            .frame(width: 80.0, height: 80.0)
            .font(.system(size: 36))
            .glassEffect()

        Image(systemName: "eraser.fill")
            .frame(width: 80.0, height: 80.0)
            .font(.system(size: 36))
            .glassEffect()
    }
}
```

The `spacing` parameter controls merge distance — closer elements blend their glass shapes together.

### Uniting Glass Effects

Combine multiple views into a single glass shape with `glassEffectUnion`:

```swift
@Namespace private var namespace

GlassEffectContainer(spacing: 20.0) {
    HStack(spacing: 20.0) {
        ForEach(symbolSet.indices, id: \.self) { item in
            Image(systemName: symbolSet[item])
                .frame(width: 80.0, height: 80.0)
                .glassEffect()
                .glassEffectUnion(id: item < 2 ? "group1" : "group2", namespace: namespace)
        }
    }
}
```

### Morphing Transitions

Create smooth morphing when glass elements appear/disappear:

```swift
@State private var isExpanded = false
@Namespace private var namespace

GlassEffectContainer(spacing: 40.0) {
    HStack(spacing: 40.0) {
        Image(systemName: "scribble.variable")
            .frame(width: 80.0, height: 80.0)
            .glassEffect()
            .glassEffectID("pencil", in: namespace)

        if isExpanded {
            Image(systemName: "eraser.fill")
                .frame(width: 80.0, height: 80.0)
                .glassEffect()
                .glassEffectID("eraser", in: namespace)
        }
    }
}

Button("Toggle") {
    withAnimation { isExpanded.toggle() }
}
.buttonStyle(.glass)
```

### Extending Horizontal Scrolling Under Sidebar

To allow horizontal scroll content to extend under a sidebar or inspector, ensure the `ScrollView` content reaches the leading/trailing edges of the container. The system automatically handles the under-sidebar scrolling behavior when the layout extends to the edges — no additional modifier is needed.

## Core Pattern — UIKit

### Basic UIGlassEffect

```swift
let glassEffect = UIGlassEffect()
glassEffect.tintColor = UIColor.systemBlue.withAlphaComponent(0.3)
glassEffect.isInteractive = true

let visualEffectView = UIVisualEffectView(effect: glassEffect)
visualEffectView.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.layer.cornerRadius = 20
visualEffectView.clipsToBounds = true

view.addSubview(visualEffectView)
NSLayoutConstraint.activate([
    visualEffectView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    visualEffectView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    visualEffectView.widthAnchor.constraint(equalToConstant: 200),
    visualEffectView.heightAnchor.constraint(equalToConstant: 120)
])

// Add content to contentView
let label = UILabel()
label.text = "Liquid Glass"
label.translatesAutoresizingMaskIntoConstraints = false
visualEffectView.contentView.addSubview(label)
NSLayoutConstraint.activate([
    label.centerXAnchor.constraint(equalTo: visualEffectView.contentView.centerXAnchor),
    label.centerYAnchor.constraint(equalTo: visualEffectView.contentView.centerYAnchor)
])
```

### UIGlassContainerEffect for Multiple Elements

```swift
let containerEffect = UIGlassContainerEffect()
containerEffect.spacing = 40.0

let containerView = UIVisualEffectView(effect: containerEffect)

let firstGlass = UIVisualEffectView(effect: UIGlassEffect())
let secondGlass = UIVisualEffectView(effect: UIGlassEffect())

containerView.contentView.addSubview(firstGlass)
containerView.contentView.addSubview(secondGlass)
```

### Scroll Edge Effects

```swift
scrollView.topEdgeEffect.style = .automatic
scrollView.bottomEdgeEffect.style = .hard
scrollView.leftEdgeEffect.isHidden = true
```

### Toolbar Glass Integration

```swift
let favoriteButton = UIBarButtonItem(image: UIImage(systemName: "heart"), style: .plain, target: self, action: #selector(favoriteAction))
favoriteButton.hidesSharedBackground = true  // Opt out of shared glass background
```

## Core Pattern — WidgetKit

### Rendering Mode Detection

```swift
struct MyWidgetView: View {
    @Environment(\.widgetRenderingMode) var renderingMode

    var body: some View {
        if renderingMode == .accented {
            // Tinted mode: white-tinted, themed glass background
        } else {
            // Full color mode: standard appearance
        }
    }
}
```

### Accent Groups for Visual Hierarchy

```swift
HStack {
    VStack(alignment: .leading) {
        Text("Title")
            .widgetAccentable()  // Accent group
        Text("Subtitle")
            // Primary group (default)
    }
    Image(systemName: "star.fill")
        .widgetAccentable()  // Accent group
}
```

### Image Rendering in Accented Mode

```swift
Image("myImage")
    .widgetAccentedRenderingMode(.monochrome)
```

### Container Background

```swift
VStack { /* content */ }
    .containerBackground(for: .widget) {
        Color.blue.opacity(0.2)
    }
```

## Key Design Decisions

| Decision | Rationale |
|----------|-----------|
| GlassEffectContainer wrapping | Performance optimization, enables morphing between glass elements |
| `spacing` parameter | Controls merge distance — fine-tune how close elements must be to blend |
| `@Namespace` + `glassEffectID` | Enables smooth morphing transitions on view hierarchy changes |
| `interactive()` modifier | Explicit opt-in for touch/pointer reactions — not all glass should respond |
| UIGlassContainerEffect in UIKit | Same container pattern as SwiftUI for consistency |
| Accented rendering mode in widgets | System applies tinted glass when user selects tinted Home Screen |

## Best Practices

- **Always use GlassEffectContainer** when applying glass to multiple sibling views — it enables morphing and improves rendering performance
- **Apply `.glassEffect()` after** other appearance modifiers (frame, font, padding)
- **Use `.interactive()`** only on elements that respond to user interaction (buttons, toggleable items)
- **Choose spacing carefully** in containers to control when glass effects merge
- **Use `withAnimation`** when changing view hierarchies to enable smooth morphing transitions
- **Test across appearances** — light mode, dark mode, and accented/tinted modes
- **Ensure accessibility contrast** — text on glass must remain readable

## Anti-Patterns to Avoid

- Using multiple standalone `.glassEffect()` views without a GlassEffectContainer
- Nesting too many glass effects — degrades performance and visual clarity
- Applying glass to every view — reserve for interactive elements, toolbars, and cards
- Forgetting `clipsToBounds = true` in UIKit when using corner radii
- Ignoring accented rendering mode in widgets — breaks tinted Home Screen appearance
- Using opaque backgrounds behind glass — defeats the translucency effect

## When to Use

- Navigation bars, toolbars, and tab bars with the new iOS 26 design
- Floating action buttons and card-style containers
- Interactive controls that need visual depth and touch feedback
- Widgets that should integrate with the system's Liquid Glass appearance
- Morphing transitions between related UI states

모든 파일

1개 파일

liquid-glass-design 설치

스킬 파일을 다운로드하여 .claude/skills/ 디렉터리에 압축을 풀어주세요.

ZIP 다운로드

저장소를 클론하고 스킬 파일을 프로젝트에 복사하세요.

git clone https://github.com/affaan-m/ECC/tree/main/skills/liquid-glass-design # Copy SKILL.md to your .claude/skills/ directory

복사 복사
빠른 설정: 스킬 폴더를 .claude/skills/로 복사하세요. Claude가 해당 스킬을 자동으로 감지하여 사용합니다.
저장소 affaan-m/ECC

관련 스킬

v4-new-features
업데이트 된 시간 2026년 8월 4일
multica-creating-agents
업데이트 된 시간 2026년 8월 12일
pixijs-application
업데이트 된 시간 2026년 8월 4일
tilemaps
업데이트 된 시간 2026년 8월 4일
OR