使用 SwiftUI Shape 进行阴影偏移

Tom*_*m P 3 graphics ios swiftui

我正在尝试使用形状、几何读取器和路径在 SwiftUI 中绘制一个圆圈,我想要一个阴影位于圆圈的正下方,但阴影出现偏移,我似乎无法让它绘制在应该绘制的位置:

阴影偏移问题


struct ContentView: View {

    var body: some View {

         return  GeometryReader { geometry in

            VStack(alignment: .center) {
            BackgroundRing()
                .stroke(Color.red, style:  StrokeStyle(lineWidth: geometry.size.width < geometry.size.height ? geometry.size.width / 12.0 :  geometry.size.height / 12))
                .padding()
                .shadow(color: .gray, radius: 1.0, x: 0.0, y: 0.0)
            }
         }
    }
}

struct BackgroundRing : Shape {
     func path(in rect: CGRect) -> Path {
        var path: Path = Path()

                let radiusOfRing: CGFloat = (rect.width < rect.height ? rect.width/2 - rect.width / 12 : rect.height/2 - rect.height / 12)
        path.addRelativeArc(center: CGPoint(x: rect.width/2, y: rect.height/2),
                                radius: radiusOfRing,
                                startAngle: Angle(radians: 0.0),
                                delta: Angle(radians: Double.pi * 2.0 ))

        return path
    }
}




Run Code Online (Sandbox Code Playgroud)

Tom*_*m P 6

好的,我似乎已经成功解决了这个问题。宽度/高度与代码交互以计算阴影位置 - 阴影位置似乎来自框架尺寸而不是形状。

添加

.aspectRatio(contentMode: .fit)

解决问题

此外,.shadow 似乎自动将默认偏移设置为与半径相同的值,因此要获得 0.0 的实际偏移,您必须相对于半径设置它,如下所示:

.shadow(radius: 10.0, x: -10.0, y: -10.0)
Run Code Online (Sandbox Code Playgroud)

在我看来像是一个错误,但这个解决办法解决了它:

在此输入图像描述

import SwiftUI

struct ContentView: View {

    var body: some View {

         return  GeometryReader { geometry in

            VStack(alignment: .center) {
            BackgroundRing()
               .stroke(Color.red,
                        style:  StrokeStyle(lineWidth: geometry.size.width < geometry.size.height ? geometry.size.width / 12.0 :  geometry.size.height / 12))
                .shadow(radius: 30.0, x: -30.0, y: -30.0)
                .aspectRatio(contentMode: .fit)
            }
         }

    }
}

struct BackgroundRing : Shape {
     func path(in rect: CGRect) -> Path {
        var path: Path = Path()

                let radiusOfRing: CGFloat = (rect.width < rect.height ? rect.width/2 - rect.width / 12 : rect.height/2 - rect.height / 12)
        path.addRelativeArc(center: CGPoint(x: rect.width/2, y: rect.height/2), // <- this change solved the problem
                                radius: radiusOfRing,
                                startAngle: Angle(radians: 0.0),
                                delta: Angle(radians: Double.pi * 2.0 ))

        return path
    }
}

Run Code Online (Sandbox Code Playgroud)