SwiftUI 圆位置 x 和 y

col*_*ole 2 ios swift swiftui

我无法找出正确的方法来找到要放置的 x 和 y 坐标以及Imageoverlay正在制作的进度视图的正确位置。我希望最终结果看起来像屏幕截图,只是不确定我会使用什么公式。至少可以说,我的数学能力很差。

GeometryReader { geometry in
    ZStack {
        Circle()
            .trim(from: 0.0, to: 0.5)
            .stroke(Color.blue, style: StrokeStyle(lineWidth: 5))
            .rotationEffect(.degrees(-180))
            .frame(width: geometry.size.width)
            .opacity(0.5)
            .overlay(Circle()
                        .trim(from: 0.0, to: CGFloat(configuration.fractionCompleted ?? 0) / 2)
                        .stroke(Color.blue, style: StrokeStyle(lineWidth: 5))
                        .rotationEffect(.degrees(-180))
                        .frame(width: geometry.size.width).overlay(
                            Circle()
                                .frame(width: 20, height: 20)
                                .position(x: 0, y: 0)
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Phi*_*hov 8

这里你只需要非常基本的几何形状

\n

\n

您需要获取C点坐标。按照这张图,就可以了(x, height / 2 - y)

\n

y了解这一点,您需要知道sin \xce\xb1 = CD/CA,就像ACD直角三角形一样。从哪里y = r * sin \xce\xb1

\n

因为x我们看一下同一个三角形,但采用 cos:cos \xce\xb1 = AD/CA, cos \xce\xb1 = (r-x)/r=>x = r - r * cos \xce\xb1 = r * (1 - cos \xce\xb1)

\n

您需要的最后一件事是\xce\xb1,这非常简单:半圆的最后一个点 if Pi,因此您只需将其乘以进度即可。

\n
struct ContentView: View {\n    @State\n    var progress: CGFloat = 0\n    \n    var body: some View {\n        GeometryReader { geometry in\n            let diameter = geometry.size.width\n            let radius = diameter / 2\n            let angle = progress * .pi\n            ZStack {\n                Circle()\n                    .trim(from: 0.0, to: 0.5)\n                    .stroke(Color.blue, style: StrokeStyle(lineWidth: 5))\n                    .rotationEffect(.degrees(-180))\n                    .frame(width: diameter)\n                    .opacity(0.5)\n                    .overlay(\n                        Circle()\n                            .trim(from: 0.0, to: progress / 2)\n                            .stroke(Color.blue, style: StrokeStyle(lineWidth: 5))\n                            .rotationEffect(.degrees(-180))\n                            .frame(width: diameter)\n                            .overlay(\n                                Circle()\n                                    .frame(width: 20, height: 20)\n                                    .position(\n                                        x: radius * (1 - cos(angle)),\n                                        y: geometry.size.height / 2 - radius * sin(angle)\n                                    )\n                            )\n                    )\n            }\n        }.onAppear {\n            Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in\n                withAnimation {\n                    progress += 0.04\n                }\n                if progress >= 1 {\n                    timer.invalidate()\n                }\n            }\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

\n