Search code examples
textswiftuioverlayrounded-cornersdropshadow

How do you add a drop shadow to a shape overlay without obscuring its text? SwiftUI


I have a text view whose visibility can be toggled. I want the text to appear over a RoundedRectangle that has a drop shadow.

The problem with overlaying a shape is that it must be opaque in order to cast a shadow, and as such it covers the text, as you can see in the following code snippet:

Text("Hello, world!")
    .font(.title)
    .foregroundColor(self.digitalOn ? Color.black : Color.white)
    .padding()
    .overlay(RoundedRectangle(cornerRadius: 10)
        .fill(Color.white)
        .shadow(color: Color.black.opacity(1), radius: 5, x: 10, y: 10)
    )
    .padding()

Seems crazy to me that there is no way to control the opacity or color of the text independently of the foreground. I assume I'm just approaching the problem in completely the wrong way. Can someone set me right?


Solution

  • Here is a solution (tested with Xcode 11.4)

    demo

    Text("Hello, world!")
        .font(.title)
        .foregroundColor(self.digitalOn ? Color.black : Color.white)
        .padding()
        .background(RoundedRectangle(cornerRadius: 10)
            .fill(Color.white)
        )
        .compositingGroup()     // << here !!
        .shadow(color: Color.black.opacity(1), radius: 5, x: 10, y: 10) // << shadow to all composition
        .padding()