How to add Shadow to a View in SwiftUI

swiftui Aug 24, 2024
Shadow in SwiftUI

Shadows are a great addition to SwiftUI views as it enhances the appearance of a view by giving a depth effect to it. This article covers how to add shadow to multiple type of views in SwiftUI.

Table of Contents

  1. Shadow in SwiftUI
  2. How to add Drop and Inner Shadows in SwiftUI
  3. Button Shadow SwiftUI

 

Shadow in SwiftUI

You can add a shadow to any of the SwiftUI views like Text, Image, Shape etc. You simply have to use a SwiftUI modifier .shadow on the view. This modifier takes 4 parameters:

  1. radius: The radius parameter defines how much blur the edge of the shadow will be. If you pass in a large value, that means the blur effect will be high.
  2. color: The color of the shadow. The default value is semi-transparent black.
  3. x: It defines the change in position of the shadow along x-axis, relative to the view it is applied to. The default value of x is 0.
  4. y: It defines the change in position of the shadow along x-axis, relative to the view it is applied to. The default value of y is also 0.

Let's see how to apply shadow to an image in SwiftUI.

struct ContentView: View {
    var body: some View {
        VStack {
            Image("profile")
                .resizable()
                .frame(width: 200, height: 200)
                .padding(20)
                .shadow(color: .pink, radius: 10, x: 10, y: 10)
                
              ProfileView()
        }
    }
}

If a positive value is passed to x, the shadow shifts to the left and a negative value shifts the shadow to the right. Similarly, a positive value of y shifts the shadow upwards and a negative value shifts the shadow downwards.

Result:

 

How to add Drop and Inner Shadows in SwiftUI

To add an outer shadow to a shape view, you can directly use the .shadow modifier as discussed above.

But what if, you want to give an inner shadow to the shape or an outer shadow that is more dark and sharp as compared to the one provided with the .shadow modifier.

With iOS 16.0+, this became achievable with the introduction of ShadowStyle with two specific functions drop(color:radius:x:y:) and inner(color:radius:x:y:).

Drop Shadow in SwiftUI

To add a drop shadow style, you can either use .fill or .foregroundStyle modifiers which takes a parameter of type ShapeStyle. The ShapeStyle protocol has another function .shadow which further requires a parameter of type ShadowStyle.

(.fill(ShapeStyle.shadow(ShadowStyle)))
(.foregroundStyle(ShapeStyle.shadow(ShadowStyle)))

Let's say you want to create a circle outside the profile image and give drop shadow to it. In this case, you'll have to use the ShadowStyle as .drop.

struct InnerAndDropShadow: View {
    var body: some View {
        VStack {
            ZStack {
                Circle()
                    .fill(.pink.shadow(.drop(color: .pink, radius: 10)))
                    .frame(width: 220, height: 220)
                
                Image("profile")
                    .resizable()
                    .frame(width: 200, height: 200)
                    .padding(20)
            }
            ProfileView()
        }
    }
}

Result:

Click here to download the complete project

Inner Shadow in SwiftUI

To give an inner shadow, use the ShadowStyle as .inner.

Circle()
    .fill(.pink.shadow(.inner(color: .black, radius: 10)))
    .frame(width: 220, height: 220)

Result:

 

Button Shadow SwiftUI

Applying shadow to a button is a common task in app development, yet it's an area where many developers often encounter challenges.

Let's see what happens when you apply a shadow to a button in SwiftUI.

Button(action: {}, label: {
    Text("Follow")
        .bold()
        .foregroundStyle(.white)
        .frame(width: 300, height: 50)
        .background(
            RoundedRectangle(cornerRadius: 10)
                .foregroundStyle(.pink)
        )
})
.shadow(color: .black, radius: 10, x: 5, y: 5)

Result:

As you can see, the shadow is given not just to the outer boundary but also to the inner text. However, what you might need is just the shadow on the outer boundary of the button.

There are primarily two ways to resolve it. The first one is to apply the shadow to the RoundedRectangleinstead of applying it to the entire button component. This will ensure that the shadow is only added to the boundary and not to the text.

RoundedRectangle(cornerRadius: 10)
    .foregroundStyle(.pink)
    .shadow(color: .black, radius: 10, x: 5, y: 5)

Result:

Click here to download the complete project

The second approach is to use compositingGroup modifier which groups the button and it's child views as a single view. This is how it makes sure that the shadow modifier is applied to the view as a whole and not to each of it's subviews separately.

Button(action: {}, label: {
    Text("Hello World")
        .font(.title)
        .foregroundColor(.blue)
        .padding(25)
        .background(
            RoundedRectangle(cornerRadius: 25.0)
                .foregroundStyle(.white)
        )
})
.compositingGroup()
.shadow(color: .black, radius: 10, x: 10, y: 10)

Result:

Click here to download the complete project

Where to go next?

Congratulations, you have successfully learned how to add shadow to a SwiftUI view, drop and inner shadows and also how to properly implemnet shadow to a button in SwiftUI.

We would highly recommend you to learn about more advance concepts in SwiftUI like ProgressView, Custom Shapes and Charts.

Signup now to get notified about our
FREE iOS Workshops!