可以在以下答案中找到用于弯曲文本的SwiftUI解决方案
SwiftUI: How to have equal spacing between letters in a curved text view?
(这是我的回答)。
该解决方案将圆半径作为参数,根据该参数计算角度。这是一个改编版本,它使用您的命名并将角度作为参数,从中计算半径。角度为0需要特殊处理,因为半径将是无穷大。
// Adaption of CurvedText, see
// https://stackoverflow.com/a/77280669/20386264
// for code comments and more explanation
struct CircularText: View {
let text: String
let arcAngle: Angle
var body: some View {
if arcAngle.radians == 0.0 {
textAsChars
} else {
textAsChars
.fixedSize()
.hidden()
.overlay {
GeometryReader { fullText in
let textWidth = fullText.size.width
let startAngle = -(arcAngle.radians / 2)
let radius = textWidth / arcAngle.radians
HStack(spacing: 0) {
ForEach(Array(text.enumerated()), id: \.offset) { index, character in
Text(String(character))
.hidden()
.overlay {
GeometryReader { charSpace in
let midX = charSpace.frame(in: .named("FullText")).midX
let fraction = midX / textWidth
let angle = startAngle + (fraction * arcAngle.radians)
let xOffset = (textWidth / 2) - midX
Text(String(character))
.offset(y: -radius)
.rotationEffect(.radians(angle))
.offset(x: xOffset, y: radius)
}
}
}
}
.fixedSize()
.frame(width: textWidth)
}
}
.coordinateSpace(name: "FullText")
}
}
private var textAsChars: some View {
HStack(spacing: 0) {
ForEach(Array(text.enumerated()), id: \.offset) { index, character in
Text(String(character))
}
}
}
}
示例用法:
struct CircularTextView: View {
@State private var arcDegrees: Double = 0
let text: String = "The quick brown fox jumps over the lazy dog"
var body: some View {
VStack {
CircularText(text: text, arcAngle: .degrees(arcDegrees))
.frame(height: 300)
.border(Color.gray.opacity(0.3))
Slider(value: $arcDegrees, in: -360...360, step: 1)
.padding(.horizontal)
Text("Arc Degrees: \(Int(arcDegrees))")
.font(.subheadline)
}
.padding()
}
}
请注意,a
GeometryReader
不需要,因为文本采用其自然宽度。