ios SwiftUI圆圈位置x和y

9wbgstp7  于 2023-02-17  发布在  iOS
关注(0)|答案(1)|浏览(153)

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

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

tp5buhyn

tp5buhyn1#

这里你只需要基本的几何学

你需要得到C点的坐标。按照这个图片,它将是(x, height / 2 - y)
要得到y,你需要知道sin α = CD/CA,因为ACD是一个直角三角形。
对于x,我们看一下相同的三角形,但取cos:cos α = AD/CAcos α = (r-x)/r =〉x = r - r * cos α = r * (1 - cos α)
您最不需要的就是α,它非常简单:如果Pi是半圆的最后一个点,所以你只需要把它乘以进度。

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

相关问题