I have seen various questions about this but none seem to answer using inner and drop shadows in a SwiftUI View.
Let’s say one has a view (which I am representing with the Shape subclass RoundRectangle
. Because it’s a Shape, I can trivially add inner and drop shadows like this:
#Preview {
VStack {
RoundedRectangle(cornerRadius: 10)
// inner shadow
.fill(.shadow(.inner(color: .white, radius: 1, y: -1)))
.frame(width: .infinity, height: 100)
// drop shadow
.shadow(radius: 10)
Spacer()
}
.background(.yellow)
.padding()
}
The code above produces this:
Now, what if one had a Text
view? The drop shadow can be trivially applied but not so the inner one because Text
is not a Shape
and .fill cannot be called. I have seen solutions that use .overlay
but these assume a Shape like Rectangle
. Also, they assume the Shape’s color is non-clear (e.g. .red or .blue).
#Preview {
VStack {
Text("View")
.background(.blue)
.overlay(alignment: .center) {
Rectangle()
.fill(.shadow(.inner(color: .white, radius: 1, y: -1)))
}
.frame(width: .infinity, height: 100)
Spacer()
}
.background(.yellow)
.padding()
}
In fact, overlay in this specific code does not really work:
So, how can one apply that .fill(.shadow(.inner(radius:)))
to create the inner shadow, assuming any SwiftUI view?
Try adding the inner shadow to the blue background instead.
BTW, .infinity
is not valid as a width
(there are errors in the console), but you can use it for maxWidth
.
Text("View")
.background(
.blue
.shadow(.inner(color: .white, radius: 1, y: -1))
)
.frame(maxWidth: .infinity)
.frame(height: 100)