Spatial SwiftUI: shadow modifier

Using shadows on 2D views to convey depth.

When used with offset or transform3DEffect, these shadows can add detail and depth to our views. In my opinion, shadows should only be used if the view has been pushed out from parent window. Otherwise they are unconvincing in the headset.

This example has three rectangles. The first has no offset, the second has a z offset of 50, and the third as a z offset of 100. We can just the slider to control the radius of the shadow. The shadow will appear sharper when this number is lower. If you look at the shadow for the third rectangle, you will notice that it is softer than the one for the second. visionOS is doing something to adjust the radius based on distance.

We can adjust the X and Y position of the shadow using the second slider. This could be useful if you want to give the impression your window is lit from a specific direction.

.shadow(radius: shadowRadius, x: direction, y: direction)

We can also provide a color for the shadow, but I find that often looks pretty bad on visionOS. I think it’s better to stick with the default color if your window uses a glass effect.

Watch the video demo

Example code

struct Example027: View {

    @State var shadowRadius: CGFloat = 6.0
    @State var direction: CGFloat = 0.0

    var body: some View {
        VStack(spacing: 24) {
            HStack {
                Slider(value: $shadowRadius,
                       in: 0...12,
                       minimumValueLabel: Image(systemName: "square.fill"),
                       maximumValueLabel: Image(systemName: "square.fill.on.square.fill"),
                       label: {
                    Text("Shadow")
                })

                Slider(value: $direction,
                       in: 0...100,
                       minimumValueLabel: Image(systemName: "square.fill"),
                       maximumValueLabel: Image(systemName: "square.fill.on.square.fill"),
                       label: {
                    Text("Direction")
                })
            }

            HStack(spacing: 24) {

                RoundedRectangle(cornerRadius: 12.0)
                    .foregroundStyle(.white)
                    .shadow(radius: shadowRadius, x: direction, y: direction)

                RoundedRectangle(cornerRadius: 12.0)
                    .foregroundStyle(.white)
                    .offset(z: 50)
                    .shadow(radius: shadowRadius, x: direction, y: direction)

                RoundedRectangle(cornerRadius: 12.0)
                    .foregroundStyle(.white)
                    .offset(z: 100)
                    .shadow(radius: shadowRadius, x: direction, y: direction)

            }
            .padding(12)
        }
        .padding(12)

    }
}

Support our work so we can continue to bring you new examples and articles.

Download the Xcode project with this and many more examples from Step Into Vision.
Some examples are provided as standalone Xcode projects. You can find those here.

Questions or feedback?