→ Swift Archive

[SwiftUI] 커스텀 글래스모피즘 구현하기

Swift librarian 2024. 1. 10. 23:33

글래스모피즘?

아주 간단하게 설명하면 UI 에 반투명 유리효과를 주는 것인데. SwiftUI 로 앱을 개발하다 보면 강제로(?) 만날 수 있다. 예를 들면 위는 NavigationTitle 을 생성하고 위로 스크롤 하면 타이틀 뒤로 가는 뷰는 살짝 흐릿하게 보이는 것을 볼 수 있다. 이것을 구현해 볼 것이다.

 

제공되는 Material 사용

아래와 같은 Rectangle 을 사용하여 overlay 시키면 간단하게 글래스모피즘을 적용할 수 있다. 종류도 ultraThin 부터 ultraThick 까지 5종류의 Material 을 고를 수 있다. 많은 애플 컴포넌트들이 Material 가 사용됨을 알 수 있다. 예를 들면 Alert 나 예시로 보여준 NavigationTitle 등등...

Rectangle()
   .foregroundStyle(.ultraThinMaterial)

Material 의 아쉬운점...

물론 애플에서 기본으로 제공하는 것이라 깔끔하고 좋지만... 아쉬운점이 두가지 정도 있다.

투명도를 조절하고 싶다

제공되는 것들은 애플이 "정해준" 투명도밖에 할 수 없다.

Hello, world! 가 미약하게라도 보고싶어!

색상을 지정할 수 없다

나는 위에 overlay 되는 것이 저런 연한 회색이아니라 파란색, 녹색 등등 다양한 색상을 원하는데 제공되는 것은 색상변경이 "불가능" 하다. 심지어 뒤에 뭐가 없더라도 thinMaterial 은 연한 회색, thickMaterial 은 거의 흰색(?) 을 띈다.

 

커스텀으로 만든 TransparentBlur

이러한 이유로 커스텀으로 만들게 되었다. 쨘! blur 로 흐릿함의 정도를 만들 수 있고, color 로 색상도 변경 가능하다!

struct TransparentBlurView: View {
    var blur: CGFloat = 6
    var color: Color = .white.opacity(0.2)
    
    var body: some View {
        TransparentBlur()
            .blur(radius: blur, opaque: true)
            .overlay {
                color
            }
    }
}

struct TransparentBlur: UIViewRepresentable {
    func makeUIView(context: Context) -> UIVisualEffectView {
        let view = UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterial))
        return view
    }
    
    func updateUIView(_ uiView: UIVisualEffectView, context: Context) {
        DispatchQueue.main.async {
            if let backdropLayer = uiView.layer.sublayers?.first {
                backdropLayer.filters = []
            }
        }
    }
}

사용 예시

아래와 같이 overlay 시켜주면 된다. (blur 는 6이 이상적이더라...)

        .overlay {
            TransparentBlurView(blur: 6, color: .green.opacity(0.2))
                .frame(height: 90)
                .ignoresSafeArea()
        }

쨘!