I'd like to make View's (Text, Button, etc) Inner shadow in SwiftUI
There is Outer shadow but there is no Inner shadow in SwiftUI
What I want to make is Neumorphism UI using SwiftUI
Image from "Neumorphism in user interfaces" by Michal Malewicz
I'd like to make button pressed UI
but I don't know where to start to make inner shadow
This is what I did to create an inner shadow like the one in the picture. I created it in another swiftui file and just called in in my main content view but you can display it however you'd like.
I created a Button in a ZStack only because I first recreated it with a rounded rectangle but I think this would would in a HStack or VStack as well just haven't tried them. To create the inner shadow I created an overlay and clipped the shadows to the shape.
ZStack{
Button(action: {}){
Image(systemName: "heart.fill")
.resizable()
.frame(width: 40, height: 40)
.padding(25)
.foregroundColor(Color(red: 52/255, green: 57/255, blue: 133/255))
.overlay(
RoundedRectangle(cornerRadius: 15)
.stroke(Color(red: 236/255, green: 234/255, blue: 235/255),
lineWidth: 4)
.shadow(color: Color(red: 192/255, green: 189/255, blue: 191/255),
radius: 3, x: 5, y: 5)
.clipShape(
RoundedRectangle(cornerRadius: 15)
)
.shadow(color: Color.white, radius: 2, x: -2, y: -2)
.clipShape(
RoundedRectangle(cornerRadius: 15)
)
)
.background(Color(red: 236/255, green: 234/255, blue: 235/255))
.cornerRadius(20)
}
The end result looked like this:
You can play around with the colors and the shadows to get exactly what you want but hopefully this helps!
You could use a SwiftUI shape as background.
Use .fill(.shadow(.inner(radius: 1, y: 1)))
for inner shadow.
The .foregroundColor
of the shape is the background color of the button.
For a RoundedRectangle Button same as the question
Button(action: {}){
Image(systemName: "heart.fill")
.resizable()
.frame(width: 40, height: 40)
.padding(25)
.foregroundColor(Color(red: 52/255, green: 57/255, blue: 133/255))
.background(
RoundedRectangle(cornerRadius: 20, style: .continuous)
.fill(
.shadow(.inner(color: Color(red: 197/255, green: 197/255, blue: 197/255),radius: 3, x:3, y: 3))
.shadow(.inner(color: .white, radius: 3, x: -3, y: -3))
)
.foregroundColor(Color(red: 236/255, green: 234/255, blue: 235/255)))
}
}
For a Circle Button
Button(action: {}){
Image(systemName: "heart.fill")
.resizable()
.frame(width: 40, height: 40)
.padding(25)
.foregroundColor(Color(red: 52/255, green: 57/255, blue: 133/255))
.background(
Circle()
.fill(
.shadow(.inner(color: Color(red: 197/255, green: 197/255, blue: 197/255),radius: 5, x:3, y: 3))
.shadow(.inner(color: .white, radius:5, x: -3, y: -3))
)
.foregroundColor(Color(red: 236/255, green: 234/255, blue: 235/255)))
}
There is now a new ShapeStyle
called shadow
:
From the documentation - the following example creates a circle filled with the current foreground style that uses an inner shadow:
Circle().fill(.shadow(.inner(radius: 1, y: 1)))
In most contexts the current style is the foreground, but not always. For example, when setting the value of the background style, that becomes the current implicit style.
Circle()
.fill(.shadow(.inner(radius: 1, y: 1)))
.foregroundStyle(.red)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With