user2848557
user2848557

Reputation: 1045

What is the purpose of .compositingGroup() in SwiftUI?

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()

What is the purpose of compositingGroup?

struct ContentView: View {
    var body: some View {
        VStack(spacing: 50) {
            Text("Without\ncompositing")
                .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("With\ncompositing")
                .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

Upvotes: 22

Views: 5575

Answers (3)

Chiaki
Chiaki

Reputation: 21

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.

Upvotes: 2

ramzesenok
ramzesenok

Reputation: 6941

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

Upvotes: 38

Anton Klymenko
Anton Klymenko

Reputation: 31

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

Upvotes: 3

Related Questions