skip to Main Content

I cannot figure out what compositingGroup() is. At first, I thought it is something like Merging layers in Photoshop. But it was not. Because .shadow() effects to the overlay and background views respectively even if I use .compositingGroup().

So far, I’ve found 2 differences when I use .compositingGroup()

  • Text doesn’t have shadows.
  • The shadow size of the overlay view is slightly smaller than the above one.

What is the purpose of compositingGroup?

struct ContentView: View {
    var body: some View {
        VStack(spacing: 50) {
            Text("Withoutncompositing")
                .font(.largeTitle)
                .bold()
                .padding()
                .foregroundColor(Color.white)
                .background(RoundedRectangle(cornerRadius: 30).fill(Color.red))
                .padding()
                .padding()
                .overlay(RoundedRectangle(cornerRadius: 30).stroke(lineWidth: 10))
                .shadow(color: .blue, radius: 5)

            Text("Withncompositing")
                .font(.largeTitle)
                .bold()
                .padding()
                .foregroundColor(Color.white)
                .background(RoundedRectangle(cornerRadius: 30).fill(Color.red))
                .padding()
                .padding()
                .overlay(RoundedRectangle(cornerRadius: 30).stroke(lineWidth: 10))
                .compositingGroup() // <--- I added .compositingGroup() here.
                .shadow(color: .blue, radius: 5)
        }
    }
}

enter image description here

3

Answers


  1. Use it when wanting to apply effects like opacity or shadow to a group of views and not each contained element by itself.

    Login or Signup to reply.
  2. This modifier makes the following modifiers be applied to the view as a whole and not to each particular subview separately

    Here’s an example to better illustrate this:

    struct ContentView: View {
        let circles: some View = ZStack {
            Circle()
                .frame(width: 100, height: 100)
                .foregroundColor(.red)
                .offset(y: -25)
    
            Circle()
                .frame(width: 100, height: 100)
                .foregroundColor(.blue)
                .offset(x: -25, y: 25)
    
            Circle()
                .frame(width: 100, height: 100)
                .foregroundColor(.green)
                .offset(x: 25, y: 25)
        }
    
        var body: some View {
            VStack(spacing: 100) {
                circles
    
                circles
                    .opacity(0.5)
    
                circles
                    .compositingGroup()
                    .opacity(0.5)
            }
        }
    }
    

    result

    So in your case the shadow is applied to the whole view rather than separately to the Text and overlaying RoundedRectangle

    Login or Signup to reply.
  3. It seems like that .shadow() modifier will add both inner and outer shadow. It means that if the view is not "solid", for example, it has a "hole", .shadow() will add shadow like this:

    RoundedRectangle(cornerRadius: 30)
        .stroke(lineWidth: 10)
        .frame(width: 300)
        .shadow(color: .blue, radius: 5)
    

    Click to see the image

    So, if you do not want the inner shadow, you need to make your view be "solid", like this:

     RoundedRectangle(cornerRadius: 30)
        .stroke(lineWidth: 10)
        .frame(width: 300)
        .background(RoundedRectangle(cornerRadius: 30).fill(.white))
        .shadow(color: .blue, radius: 5)
    

    Click to see the image

    However, something goes wrong again, the inner shadow doesn’t disappear.
    That’s because I forgot to apply the .compositingGroup() modifier.

    As @ramzesenok mentioned, .compositingGroup() makes the following modifiers be applied to the view as a whole and not to each particular subview separately.

    So, change the code a little bit:

    RoundedRectangle(cornerRadius: 30)
                    .stroke(lineWidth: 10)
                    .frame(width: 300)
                    .background(RoundedRectangle(cornerRadius: 30).fill(.white))
                    .compositingGroup()
                    .shadow(color: .blue, radius: 5)
    

    Click to see the image

    There is only outer shadow now.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search