在 SwiftUI 中带有均匀虚线边框的圆圈?
Circle with an evenly dotted border in SwiftUI?
我正在尝试创建一个可调整大小的按钮,它周围有一个均匀点缀的圆形边框。如果你简单地输入:
Circle()
.stroke(color, style: StrokeStyle(lineWidth: 3, lineCap: .butt, dash: [3, radius / 3.82]))
.frame(width: radius * 2, height: radius * 2)
如下图所示,圆点分布可能不均匀:
这是一个 related question 的解决方案,我尝试将其从 UIKit 改编为 SwiftUI 结构,但也失败了。
有人可以帮我找到一种方法来调整“破折号”值以创建依赖于半径的均匀虚线描边边框,或者改为创建自定义形状吗?
使用 circle with dash lines uiview
中的部分代码
我得到了适用于 Swiftui 的测试代码:
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@State var color = Color.blue
@State var radius = CGFloat(128)
@State var painted = CGFloat(6)
@State var unpainted = CGFloat(6)
let count: CGFloat = 30
let relativeDashLength: CGFloat = 0.25
var body: some View {
Circle()
.stroke(color, style: StrokeStyle(lineWidth: 3, lineCap: .butt, dash: [painted, unpainted]))
.frame(width: radius * 2, height: radius * 2)
.onAppear {
let dashLength = CGFloat(2 * .pi * radius) / count
painted = dashLength * relativeDashLength
unpainted = dashLength * (1 - relativeDashLength)
}
}
}
我在纯 SwiftUI 中有一个答案。我认为您 运行 的问题只是您正在绘制部分和跳过部分,您必须将两者都考虑在内。
所以,你需要想出周长,把它分成1个绘制的部分+1个未绘制的部分。绘制的部分只是您看起来不错的部分,因此未绘制的部分是减去绘制的部分的部分。然后,您将这两个值插入 StrokeStyle.dash 并得到均匀间隔的点。
import SwiftUI
struct ContentView: View {
let radius: CGFloat = 100
let pi = Double.pi
let dotCount = 10
let dotLength: CGFloat = 3
let spaceLength: CGFloat
init() {
let circumerence: CGFloat = CGFloat(2.0 * pi) * radius
spaceLength = circumerence / CGFloat(dotCount) - dotLength
}
var body: some View {
Circle()
.stroke(Color.blue, style: StrokeStyle(lineWidth: 2, lineCap: .butt, lineJoin: .miter, miterLimit: 0, dash: [dotLength, spaceLength], dashPhase: 0))
.frame(width: radius * 2, height: radius * 2)
}
}
我正在尝试创建一个可调整大小的按钮,它周围有一个均匀点缀的圆形边框。如果你简单地输入:
Circle()
.stroke(color, style: StrokeStyle(lineWidth: 3, lineCap: .butt, dash: [3, radius / 3.82]))
.frame(width: radius * 2, height: radius * 2)
如下图所示,圆点分布可能不均匀:
这是一个 related question 的解决方案,我尝试将其从 UIKit 改编为 SwiftUI 结构,但也失败了。
有人可以帮我找到一种方法来调整“破折号”值以创建依赖于半径的均匀虚线描边边框,或者改为创建自定义形状吗?
使用 circle with dash lines uiview
中的部分代码我得到了适用于 Swiftui 的测试代码:
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@State var color = Color.blue
@State var radius = CGFloat(128)
@State var painted = CGFloat(6)
@State var unpainted = CGFloat(6)
let count: CGFloat = 30
let relativeDashLength: CGFloat = 0.25
var body: some View {
Circle()
.stroke(color, style: StrokeStyle(lineWidth: 3, lineCap: .butt, dash: [painted, unpainted]))
.frame(width: radius * 2, height: radius * 2)
.onAppear {
let dashLength = CGFloat(2 * .pi * radius) / count
painted = dashLength * relativeDashLength
unpainted = dashLength * (1 - relativeDashLength)
}
}
}
我在纯 SwiftUI 中有一个答案。我认为您 运行 的问题只是您正在绘制部分和跳过部分,您必须将两者都考虑在内。
所以,你需要想出周长,把它分成1个绘制的部分+1个未绘制的部分。绘制的部分只是您看起来不错的部分,因此未绘制的部分是减去绘制的部分的部分。然后,您将这两个值插入 StrokeStyle.dash 并得到均匀间隔的点。
import SwiftUI
struct ContentView: View {
let radius: CGFloat = 100
let pi = Double.pi
let dotCount = 10
let dotLength: CGFloat = 3
let spaceLength: CGFloat
init() {
let circumerence: CGFloat = CGFloat(2.0 * pi) * radius
spaceLength = circumerence / CGFloat(dotCount) - dotLength
}
var body: some View {
Circle()
.stroke(Color.blue, style: StrokeStyle(lineWidth: 2, lineCap: .butt, lineJoin: .miter, miterLimit: 0, dash: [dotLength, spaceLength], dashPhase: 0))
.frame(width: radius * 2, height: radius * 2)
}
}