2

How can I clip a shadow on a view that has transparent background using SwiftUI?

What I want to achieve is to have the possibility of getting the shadow clipped outside of the RoundedRectangle and not displaying shadow inside of it. (you can see that - "Text" has some black background, which is the shadow)

What I try to achieve: (done this using CSS) - the background inside have transparency enter image description here

My Result:

enter image description here

Text("Text") .multilineTextAlignment(.leading) .padding(EdgeInsets(top: 8, leading: 14, bottom: 8, trailing: 14)) .font(.system(size: 13, weight: .medium, design: .default)) .overlay(RoundedRectangle(cornerRadius: 10, style: .continuous) .fill(Color.init(Color.RGBColorSpace.sRGB, white: 1, opacity: 0.2)) .shadow(color: Color.black, radius: 6, x: 0, y: 3)).padding(30) 
0

5 Answers 5

7

The best solution I found, hope it will help someone :)

ZStack { RoundedRectangle(cornerRadius: 10) .shadow(color: .black.opacity(0.25), radius: 4, x: 0, y: 4) RoundedRectangle(cornerRadius: 10) .blendMode(.destinationOut) RoundedRectangle(cornerRadius: 10, style: .continuous) .fill(.green.opacity(0.5)) Text("Our Fancy Text") } .frame(width: 100, height: 50) .compositingGroup() 
Sign up to request clarification or add additional context in comments.

Comments

6

If it is Ok to also have a certain blur effect, you could use a view presenting a UIBlurEffect as the background for the text. You will still get a transparency effect but now with an opaque view that doesn't mess up the shadow.

Code:

ZStack { Color.blue Text("Hello, World!") .padding(7) .background(BlurView(style: .systemUltraThinMaterial)) .clipShape(RoundedRectangle(cornerRadius: 10.0)) .shadow(color: Color.black.opacity(0.5), radius: 6, x: 0, y: 3) } 

Result:

enter image description here

And BlurView is just a SwifUI wrapper around UIVisualEffectView

struct BlurView: UIViewRepresentable { typealias UIViewType = UIVisualEffectView let style: UIBlurEffect.Style init(style: UIBlurEffect.Style = .systemMaterial) { self.style = style } func makeUIView(context: Context) -> UIVisualEffectView { return UIVisualEffectView(effect: UIBlurEffect(style: style)) } func updateUIView(_ uiView: UIViewType, context: Context) { uiView.effect = UIBlurEffect(style: style) } } 

Comments

1

What worked for me was using an image of the desired shape as the background for the text.

ZStack{ Text("Begin") .background( Image("{Image Name}") .resizable() .opacity(0.1) .shadow(color: Color.black, radius: 8, x: -1, y: -1) ) } 

https://i.sstatic.net/y3rka.png

Comments

1

I recently faced this problem while working on a client project. We can place a RoundedRectangle, applied with the shadow and a white fill, along with the desired content's background color within a ZStack.

ZStack { RoundedRectangle(cornerRadius: 10, style: .continuous) .fill(Color(white: 1, opacity: 1)) .shadow(color: .black, radius: 6, x: 0, y: 3) Color.gray.opacity(0.4) .cornerRadius(10) Text("Content") } 

Comments

-4
struct ContentView: View { var body: some View { ZStack { Color.red.frame(width: 60, height: 30, alignment: .center) .cornerRadius(10) .shadow(color: Color.gray, radius: 1.0, x: CGFloat(4), y: CGFloat(4)) .overlay(Text("Text")) } } } 

Result:

enter image description here

For more read this page.

2 Comments

Actually, shadow is displayed in the background. How can I clip it? Add to redColor some trasnparency, I will get the exact same result as mine. The shadow is visible in the background
This answer does not fit for Views with transparent background, like the op asks

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.