'How to make inner shadow in SwiftUI?
How can I use Inner Shadow on a Rectangle()?
        Rectangle()
        .foregroundColor(.green)
        .frame(width: 400, height: 300)
I can only manage to do an Outer Shadow using .shadow

I'm looking for something like this
Solution 1:[1]
For this problem, I built a modifier for the View protocol and a extension, like below
View+innerShadow.swift
import SwiftUI
extension View {
    func innerShadow(color: Color, radius: CGFloat = 0.1) -> some View {
        modifier(InnerShadow(color: color, radius: min(max(0, radius), 1)))
    }
}
private struct InnerShadow: ViewModifier {
    var color: Color = .gray
    var radius: CGFloat = 0.1
    private var colors: [Color] {
        [color.opacity(0.75), color.opacity(0.0), .clear]
    }
    func body(content: Content) -> some View {
        GeometryReader { geo in
            content
                .overlay(LinearGradient(gradient: Gradient(colors: self.colors), startPoint: .top, endPoint: .bottom)
                    .frame(height: self.radius * self.minSide(geo)),
                         alignment: .top)
                .overlay(LinearGradient(gradient: Gradient(colors: self.colors), startPoint: .bottom, endPoint: .top)
                    .frame(height: self.radius * self.minSide(geo)),
                         alignment: .bottom)
                .overlay(LinearGradient(gradient: Gradient(colors: self.colors), startPoint: .leading, endPoint: .trailing)
                    .frame(width: self.radius * self.minSide(geo)),
                         alignment: .leading)
                .overlay(LinearGradient(gradient: Gradient(colors: self.colors), startPoint: .trailing, endPoint: .leading)
                    .frame(width: self.radius * self.minSide(geo)),
                         alignment: .trailing)
        }
    }
    func minSide(_ geo: GeometryProxy) -> CGFloat {
        CGFloat(3) * min(geo.size.width, geo.size.height) / 2
    }
}
And, for the inner shadow, you just need to add .innerShadow(color:radius)
ContentView.swift
import SwiftUI
struct ContentView: View {
    var body: some View {
        Rectangle()
            .foregroundColor(.green)
            .frame(width: 400, height: 300)
            .innerShadow(color: Color.black.opacity(0.3), radius: 0.05)
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Solution 2:[2]
If you want to add shadow only to any specific side.
private struct InnerShadow: ViewModifier {
    var color: Color = .gray
    var topToBottomRadius = 0.0
    var bottomToTopRadius = 0.0
    var leadingToTrailingRadius = 0.0
    var trailingToLeadingRadius = 0.0
    private var colors: [Color] {
        [color.opacity(0.75), color.opacity(0.0), .clear]
    }
    func body(content: Content) -> some View {
        GeometryReader { geo in
            content
                .overlay(LinearGradient(gradient: Gradient(colors: self.colors), startPoint: .top, endPoint: .bottom)
                    .frame(height: self.topToBottomRadius * self.minSide(geo)),
                         alignment: .top)
                .overlay(LinearGradient(gradient: Gradient(colors: self.colors), startPoint: .bottom, endPoint: .top)
                    .frame(height: self.bottomToTopRadius * self.minSide(geo)),
                         alignment: .bottom)
                .overlay(LinearGradient(gradient: Gradient(colors: self.colors), startPoint: .leading, endPoint: .trailing)
                    .frame(width: self.leadingToTrailingRadius * self.minSide(geo)),
                         alignment: .leading)
                .overlay(LinearGradient(gradient: Gradient(colors: self.colors), startPoint: .trailing, endPoint: .leading)
                    .frame(width: self.trailingToLeadingRadius * self.minSide(geo)),
                         alignment: .trailing)
        }
    }
    func minSide(_ geo: GeometryProxy) -> CGFloat {
        CGFloat(3) * min(geo.size.width, geo.size.height) / 2
    }
    }
    extension View {
    func innerShadow(color: Color, topRadius: CGFloat = 0.0, bottomRadius: CGFloat = 0.0, leftRadius: CGFloat = 0.0, rightRadius: CGFloat = 0.0) -> some View {
        modifier(InnerShadow(color: color, topToBottomRadius: min(max(0, topRadius), 1), bottomToTopRadius: min(max(0, bottomRadius), 1), leadingToTrailingRadius: min(max(0, leftRadius), 1), trailingToLeadingRadius:min(max(0, rightRadius), 1)))
    }
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source | 
|---|---|
| Solution 1 | Ailton Vieira Pinto Filho | 
| Solution 2 | Dharman | 
