如何在 SwiftUI 中制作内阴影?

Rod*_*azi 0 swiftui

如何在 Rectangle() 上使用内阴影?

        Rectangle()
        .foregroundColor(.green)
        .frame(width: 400, height: 300)
Run Code Online (Sandbox Code Playgroud)

我只能设法使用 .shadow 来做外部阴影

内心的阴影

我正在寻找这样的东西

Ail*_*lho 5

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

Run Code Online (Sandbox Code Playgroud)

并且,对于内部阴影,您只需添加.innerShadow(color:radius)

内容视图.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()
    }
}
Run Code Online (Sandbox Code Playgroud)