iOS 26 Liquid Glass 대응 — 시스템 컴포넌트만 쓰는 전략과 그 이유

iOS 26 Liquid Glass란

iOS 26에서 Apple은 Liquid Glass라는 새로운 디자인 언어를 도입했습니다. 반투명 유리 소재가 시스템 전체 UI에 적용되며, TabView, NavigationStack, .sheet 등 시스템 컴포넌트에 자동으로 Glass 효과가 들어갑니다.

핵심 원칙: 직접 구현하지 말고 시스템 컴포넌트 사용

// ❌ 커스텀 헤더 — iOS 26에서 Liquid Glass 미적용
private var headerView: some View {
    HStack {
        Button { } label: {
            Image(systemName: "person.crop.circle.fill")
                .frame(width: 40, height: 40)
                .background(Circle().fill(Color.systemBackground))  // ❌ 수동 배경
                .shadow(color: .black.opacity(0.1), radius: 8)      // ❌ 수동 그림자
        }
    }
}

// ✅ NavigationStack + .toolbar — 자동 Liquid Glass
NavigationStack {
    ContentView()
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .topBarLeading) {
                Button { } label: {
                    Image(systemName: "person.crop.circle.fill")
                        .font(.system(size: 26))
                        .foregroundStyle(IVENTColor.primary(for: gender))
                }
            }
            ToolbarItem(placement: .principal) { titleView }
            ToolbarItemGroup(placement: .topBarTrailing) {
                Button { } label: { Image(systemName: "magnifyingglass") }
                Button { } label: { Image(systemName: "plus") }
            }
        }
}

자동으로 Glass가 적용되는 컴포넌트

  • TabView + .tabItem — 탭 바
  • NavigationStack + .toolbar — 네비게이션 바
  • .sheet, .fullScreenCover — 시트
  • .alert, .confirmationDialog — 다이얼로그
  • Toggle, Slider, Picker — 컨트롤

커스텀 카드에 Glass 적용: liquidGlass() 모디파이어

// LiquidGlassModifier.swift
extension View {
    @ViewBuilder
    func liquidGlass(opacity: Double = 0.5,
                     cornerRadius: CGFloat = 28,
                     tintColor: Color = Color(uiColor: .systemBackground)) -> some View {
        if #available(iOS 26.0, *) {
            self.glassEffect(.regular.tint(tintColor), in: .rect(cornerRadius: cornerRadius))
        } else {
            self.modifier(LiquidGlassModifier(opacity: opacity,
                                               cornerRadius: cornerRadius,
                                               tintColor: tintColor))
        }
    }
}

// iOS 25 이하 fallback
struct LiquidGlassModifier: ViewModifier {
    var opacity: Double = 0.5
    var cornerRadius: CGFloat = 28
    var tintColor: Color

    func body(content: Content) -> some View {
        content
            .background(
                ZStack {
                    RoundedRectangle(cornerRadius: cornerRadius)
                        .fill(tintColor.opacity(opacity))
                        .background(.ultraThinMaterial)
                    RoundedRectangle(cornerRadius: cornerRadius)
                        .stroke(
                            LinearGradient(
                                colors: [.white.opacity(0.8), .white.opacity(0.1)],
                                startPoint: .topLeading,
                                endPoint: .bottomTrailing
                            ),
                            lineWidth: 0.5
                        )
                }
            )
            .clipShape(RoundedRectangle(cornerRadius: cornerRadius))
            .shadow(color: .black.opacity(0.06), radius: 15, x: 0, y: 8)
    }
}

여러 Glass 버튼 묶기: GlassEffectContainer

// iOS 26에서 glass-on-glass 중복 방지
if #available(iOS 26.0, *) {
    GlassEffectContainer(spacing: 8) {
        Button("필터") { }.glassEffect()
        Button("정렬") { }.glassEffect()
    }
}

교훈

iOS 26 Liquid Glass 대응의 핵심은 “직접 만들지 말 것”입니다. 시스템 컴포넌트를 사용하면 Apple이 자동으로 Glass 효과를 적용합니다. 커스텀이 필요한 카드·플로팅 패널에는 liquidGlass() 모디파이어로 버전 분기를 한 곳에서 처리합니다.

글쓴이

admin

https://ivent-admin.storyqbe.top/ 를 운영하고 있는 강프로입니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다