ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SwiftUI - compositingGroup
    SwiftUI 2024. 3. 28. 18:57

    안녕하세요. 그린입니다🍏

    이번 포스팅에서는 SwiftUI의 compositingGroup에 대해 알아보겠습니다 🙋🏻

     


    compositingGroup?

    compositingGroup은 SwiftUI에서 사용되는 뷰 모디파이어로 iOS 13 이상, 즉 SwiftUI를 쓰는 환경이라면 다 적용해볼 수 있어요!

    이름에서도 알 수 있듯이 뷰들을 합성된 그룹으로 합쳐 래핑해주는 역할을 가집니다.

     

    func compositingGroup() -> some View

     

    정의는 요러합니다.

    뷰를 반환하는 여느 뷰 모디파이어와 동일하니 어려울것이 없어요!

     

    compositingGroup은 뷰가 렌더링되기 전 해당 뷰의 상위 뷰들에서 발생하는 투명도 및 블렌드 모드같은 컴포지팅되는 효과들을 적용시켜줍니다.

    compositingGroup은 다시 정리하자면, 특정 뷰나 컴포넌트들의 시각적 효과를 그룹화하여 관리해주는 기능을 가집니다.

    특히, UI 개발을 하면서 여러 레이어나 컴포넌트들이 겹쳐질 때 각 요소들의 시각적인 효과들을 어떻게 합쳐줄지 결정하는것에 있어 효율적으로 관리할 수 있습니다.

     

    그렇기에, 해당 모디파이어는 상위 뷰에서 적용시켜 사용해야 합니다.

    왜냐하면, 해당 뷰에 렌더링되기 전에 미리 적용되어야 하기 때문이죠!

     

    그럼 공식문서에서 나온 예시를 볼까요?

     

    VStack {
      ZStack {
        Text("CompositingGroup")
          .foregroundColor(.black)
          .padding(20)
          .background(Color.red)
          
        Text("CompositingGroup")
          .blur(radius: 2)
      }
      .font(.largeTitle)
      .compositingGroup()
      .opacity(0.9)
    }

     

    해당 코드가 있을때 이렇게 보입니다.

     

     

    해당 예제를 보면 compositingGroup을 통해 효과 적용을 단계로 구분하여 처리하고 있습니다.

    즉, opacity를 VStack에 적용하고 내부에 있는 ZStack의 뷰중 두번째 하위 뷰에 blur를 적용하고 있습니다.

    그렇기에 opacity가 가장 바깥쪽 뷰로 적용이 제한되죠!

     

    조금 더 면밀히 살펴보면, compositingGroup은 시각적 효과를 레이어링하는 방식을 제어하고 있습니다.

    VStack에 적용된 투명도 효과는 ZStack 내부 뷰들에 적용되기전에 먼저 처리됩니다.

    효과 적용 순서를 구분하기에 투명도 효과는 VStack에만 적용되고 ZStack 내부 뷰들에는 영향을 미치지 않죠.

    그리고, ZStack 내부에선 블러 효과가 별도로 적용되는것이죠.

     

    이렇게, 시각적 효과를 좀 더 세밀하게 적용시켜주면서 특정 효과가 전체 구조에 영향을 미치는걸 방지해줄 수 있습니다.

     

    사실 저 해당 예제를 보면 compositingGroup의 쓰임이 크게 와닿지 않을 수 있습니다.


    그렇기에 조금 더 와닿는 어떻게 합성되어 사용되는지 예제를 볼까요?

     

    import SwiftUI
    
    struct ContentView: View {
      var body: some View {
        ZStack {
          Rectangle()
            .frame(width: 150, height: 150)
            .foregroundColor(.green)
          
          Rectangle()
            .frame(width: 150, height: 150)
            .foregroundColor(.yellow)
            .offset(x: 100)
        }
      }
    }

     

    지극히 평범한 두 사각형을 겹쳐 배치하는 코드가 있습니다.

    아래 초록 사각형이 위치하고 겹쳐져서 노란 사각형이 배치되겠죠?

     

     

    그런데 만약 이 ZStack에 투명도를 주면 어떻게 될까요?

     

    import SwiftUI
    
    struct ContentView: View {
      var body: some View {
        ZStack {
          Rectangle()
            .frame(width: 150, height: 150)
            .foregroundColor(.green)
          
          Rectangle()
            .frame(width: 150, height: 150)
            .foregroundColor(.yellow)
            .offset(x: 100)
        }
        .opacity(0.7)
      }
    }

     

     

    보는것과 같이 해당 하위 뷰에 개별적으로 적용되어 초록 사각형이 비치게 되죠.

     

    이런걸 의도할 수도 있지만, 전체적으로 비치지 않고 합쳐져서 투명도를 전체에 적용할때 compositingGroup을 사용할 수 있습니다.

     

    import SwiftUI
    
    struct ContentView: View {
      var body: some View {
        ZStack {
          Rectangle()
            .frame(width: 150, height: 150)
            .foregroundColor(.green)
          
          Rectangle()
            .frame(width: 150, height: 150)
            .foregroundColor(.yellow)
            .offset(x: 100)
        }
        .compositingGroup()
        .opacity(0.3)
      }
    }

     

     

    이렇게, 이제는 각 개별적으로 적용되어 비치는것이 아니라 해당 두 하위 사각형 뷰들이 합쳐진 ZStack에서 컴포지팅되어 합쳐져서 투명도가 적용됩니다.

     

    정리해보자면 compositingGroup을 이용함으로써 특정 하위 뷰에 독립적으로 효과를 적용하는것이 아닌 뷰 전체에 효과를 적용되도록 할 때 유용한 모디파이어입니다 👍


    마무리

    오랜만에 SwiftUI 뷰 모디파이어에 대해 알아보니까 역시 뷰 그리는게 제일 재밌네요!

    compositingGroup을 적절히 사용하여 시각 효과를 원하는 니즈에 맞게 구성할 수 있을것 같네요.

    다음번엔 한번 blendMode에 대해 알아볼까 합니다 🙋🏻

     


    레퍼런스

     

    compositingGroup() | Apple Developer Documentation

    Wraps this view in a compositing group.

    developer.apple.com

    'SwiftUI' 카테고리의 다른 글

    SwiftUI - ShareLink  (57) 2024.04.05
    SwiftUI - blendMode  (52) 2024.04.01
    SwiftUI - AppStorage  (77) 2024.03.07
    SwiftUI로 동적 뷰 레이아웃 구성하기  (85) 2024.01.18
    SwiftUI에서 shadow와 blur 사용하기  (79) 2024.01.08
Designed by Tistory.