swiftiphoneswiftuishadowrectangles

How to Create a Shadow in SwiftUI Only at bottom


I'm trying to create a shadow effect in SwiftUI that only appears beneath the lower half of a rectangle. Current Code:

struct ContentView: View {
    var body: some View {
        Rectangle() 
            .fill(Color.blue) // Fill the rectangle with blue color
            .frame(width: 200, height: 100) // Set the rectangle's dimensions
            .shadow(radius: 10) // This applies shadow to the entire rectangle
    }
}

Problem: In the code above, the shadow is applied to the entire rectangle. However, I only want the shadow to show beneath the lower half of the rectangle.


Solution

  • You need to add the shadow as an overlay so it can be offset and then mask it.

    struct BottomShadow: View {
        var body: some View {
            Rectangle()
                .fill(Color.blue)
                .frame(width: 200, height: 100)
                .overlay(alignment: .bottom) {
                    Color.blue
                        .shadow(radius: 5, y: 5)
                        .mask{
                            Color.black
                                .offset(y: 15)
                        }
                }
       
            Spacer()
        }
    }
    
    #Preview {
        BottomShadow()
    }
    

    Resulting in this:

    enter image description here

    If you play with the size of the overlay, the values and order of the modifiers, you can also get creative:

    Rectangle()
                .fill(Color.blue)
                .frame(width: 200, height: 100)
                .overlay(alignment: .bottom) {
                    Color.blue
                        .frame(height: 5)
                        .mask{
                            Color.black
                                // .offset(y: 5)
                                // .padding(.top, 3) // <- modifiers here can be used for additional control
                        }
                        .shadow(radius: 3, y: 10)
                }
    

    This will give a shadow that can be somewhat in the air, but also slightly extends to the sides, rather than be clipped like the previous one.

    enter image description here