Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Inner shadow in SwiftUI

Tags:

ios

swift

swiftui

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

like image 846
PrepareFor Avatar asked Feb 07 '20 13:02

PrepareFor


3 Answers

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: enter image description here

You can play around with the colors and the shadows to get exactly what you want but hopefully this helps!

like image 85
A.Cal Avatar answered Nov 19 '22 23:11

A.Cal


iOS 16+ only

For Buttons

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.

Here's my example using pawello2222's answer

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

RoundedRectangle Button

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

Circle Button

like image 2
zhangao88 Avatar answered Nov 19 '22 23:11

zhangao88


iOS 16+

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)
like image 1
pawello2222 Avatar answered Nov 19 '22 23:11

pawello2222