我正在尝试在 SwiftUI 中绘制弧线,正在练习,我想从苹果网站制作此视图(如图所示),其中展示了如何实现动态岛现场活动。
我尝试过使用路径,但我不确定如何只绘制圆弧而不是像我的代码那样绘制半圆。
这是使用
Path
的代码:
struct ArcShape: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
let center = CGPoint(x: rect.midX, y: rect.midY)
let radius: CGFloat = 100
let startAngle = Angle(degrees: 180)
let endAngle = Angle(degrees: 0)
path.addArc(center: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)
return path
}
}
这是一种更接近的方法,使用
Circle
并修剪它,但我不知道如何“捣碎它”并使其更平坦,并且还圆角,我尝试过使用.cornerRadius
并制作 frame
宽且不高,但我没有看到任何结果,只有圆圈调整为较小的尺寸frame
:
Circle()
.trim(from: 0.55, to: 0.95)
.stroke(.linearGradient(colors: [.blue, .cyan],
startPoint: .leading,
endPoint: .trailing), lineWidth: 5)
路径使用的角度从右侧零开始(罗盘方向的东方)并随着顺时针方向增加。
您创建了一条从 180 度(正西)开始,到 0 度(正东)逆时针绘制的弧。画了一个半圆。
如果您想绘制更少的圆,请在起始角度添加一些偏移,并从结束角度减去相同的量。因此,正如 Paulw11 建议的那样,尝试 180+40 = 220 度作为弧线的左侧(西侧),0-40 = -40 或 360-40 = 320 度作为弧线的右侧结束。
此代码:
struct ArcShape: Shape {
var radius: CGFloat // The circle radius to use. Bigger numbers make a flatter but bigger arc
var arcOffset: CGFloat // The number of degrees above the center to start the left and right of the arc.
func path(in rect: CGRect) -> Path {
var path = Path()
let center = CGPoint(x: rect.midX, y: rect.midY)
let startAngle = Angle(degrees: 180 + arcOffset)
let endAngle = Angle(degrees: 0 - arcOffset)
path.addArc(center: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)
return path
}
}
struct ContentView: View {
var body: some View {
// GeometryReader lets us learn things like the size of the screen
GeometryReader { proxy in
VStack(alignment: .center) {
Spacer()
.frame(height: 100)
let inset: CGFloat = 10
let frameSize = proxy.size.width - inset * 2
// Draw 2 arcs on top of each other.
ZStack {
// The first blue arc will be from
// 180-30 = 210° to
// 360-30 = 330°
ArcShape(radius: frameSize / 2 - 20, arcOffset: 30)
.stroke(style: StrokeStyle(lineWidth: 20, lineCap: .round))
.foregroundColor(Color(red: 0.2, green: 0.2, blue: 0.7))
.frame(width: frameSize, height: frameSize)
// The second cyan arc will be from
// 180-70 = 110° to
// 360-70 = 190°
ArcShape(radius: frameSize / 2 - 20, arcOffset: 70)
.stroke(style: StrokeStyle(lineWidth: 20, lineCap: .round))
.foregroundColor(.cyan)
.frame(width: frameSize, height: frameSize)
}
.border(Color.green, width: 1) //Remove if you don't want a border
.padding(.leading, inset)
}
}
}
}
#Preview {
ContentView()
}
产生如下所示的图像: