struct AchievementCircularView: View {
@State private var notchLenght: CGSize = .zero
var title: String
var body: some View {
GeometryReader { geometry in
let size = geometry.size
ZStack {
ArcShape(
//startAngle: .degrees(0),
length: notchLenght.width,
lineWidth: notchLenght.height,
gap: 8
)
.stroke(Color.black, style: StrokeStyle(lineWidth: 3, lineCap: .round))
.rotationEffect(.degrees(-90))
}
.frame(width: size.width, height: size.height)
.overlay(alignment: .top) {
CurvedText(text: title, radius: (size.width / 2))
.onGeometryChange(for: CGSize.self) { proxy in
proxy.size
} action: { size in
notchLenght = size
}
}
}
}
...
创建弧形包装标题
根据文本的大小,将绘制一个带有必要凹口的弧来显示文本。
private struct ArcShape: Shape {
var length: CGFloat // Length of the arc
var lineWidth: CGFloat
var gap: CGFloat = 0 // Gap to add leading and trailing spaces
func path(in rect: CGRect) -> Path {
var path = Path()
// Adjust the radius to account for the line width
let radius = min(rect.width, rect.height) / 2 - lineWidth / 2
let center = CGPoint(x: rect.midX, y: rect.midY)
let arcAngle = radius == 0 ? 0 : (length / radius)
let startAngle = -(arcAngle / 2)
// Calculate the circumference and angle ratio
let circumference = 2 * .pi * radius // Circumference of the circle
let angleRatio = length / circumference // Ratio of the length to the circumference
// Adjust the startAngle and endAngle to account for the gap
let gapAngle = Angle.radians(-(gap / circumference) * 2 * .pi)
let adjustedStartAngle = Angle.radians(startAngle) + gapAngle
let adjustedEndAngle = Angle.radians(startAngle) + .radians(angleRatio * 2 * .pi) - gapAngle
// Draw the arc
path.addArc(
center: center,
radius: radius,
startAngle: adjustedStartAngle,
endAngle: adjustedEndAngle,
clockwise: true
)
return path
}
}
SwiftUI 的弯曲文本解决方案可以在 SwiftUI 的答案中找到:如何在弯曲文本视图中使字母间距相等?(这是我的答案)。实际上,看起来你已经找到了这篇文章,因为你自己的答案似乎是基于该问题中的代码(或来自同一 OP 的后续问题)。但你没有
CurvedText
在答案中使用。徽章的其余部分可以用 来构建
ZStack
。要在显示标题的圆圈中创建间隙,请使用
.trim
缩短路径,然后.rotationEffect
将间隙移动到 12 点钟位置。间隙的大小是唯一稍微有点棘手的部分。如果您不喜欢使用固定的弧度分数,您可以尝试使用基于标签大小的角度近似值,或者您需要获取文本的实际弧度。
弧度角度在视图中是已知的
CurvedText
,因此您可能需要考虑调整该视图。请参阅如何确定 SwiftUI 中弯曲文本视图中第一个字符的角度?以获取使用类似调整的示例。最后,可以将弯曲的文本
ZStack
作为覆盖层添加到 。这样,它就不会影响 的大小ZStack
。要创建类似于 Apple Game Center 中看到的圆形成就视图,顶部有圆形文本,中间有弧形包装器标题,您可以使用 SwiftUI 构建自定义视图。
创建圆形文本视图
参见回答@Benzy Neez:CurvedText
创建弧形包装标题
根据文本的大小,将绘制一个带有必要凹口的弧来显示文本。
使用循环成就视图
您现在可以使用 AchievementCircularView 了。