编辑:代码示例中的破折号大小 10 是任意的。破折号的大小是任何看起来合适的大小。
假设在 SwiftUI 中,您想要一个具有虚线轮廓的自定义列表项 - 用作“添加项提示”。
所以你使用这样的描边边框:
struct ContentView: View {
let items:[String] = ["a","b","c"]
@State var itemsEmpty = false
var body: some View {
Text("toggle").onTapGesture {
itemsEmpty.toggle()
}
VStack {
Spacer()
if !itemsEmpty {
List{
ForEach(items, id: \.self) {item in
Text(item)
}
}
} else {
// The "list item hint" view
List{
Text("ADD")
.listRowBackground(
RoundedRectangle(cornerSize: CGSize(width: 15, height: 15))
.strokeBorder(style: StrokeStyle(lineWidth: 4, dash: [10]))
)
}
}
Spacer()
}
.padding()
}
}
结果如下:
this Apple sample 中使用了相同的技术,但这对我来说并不满意,因为线条(可以理解)分布不均匀,并且我们在环绕点处得到了令人讨厌的截断。
我能想到的解决这个问题的唯一(也不能令人满意)的方法是:
A) 使用两个镜像形状来创建 View ...(但这仍然会导致截断...只是这次是对称截断)。
B) 制作某种“太阳光线”径向渐变并堆叠两个圆角矩形,给人一种虚线轮廓的错觉......(但这些线的“头和尾”不会是垂直于轮廓路径,因为“太阳光线”全部源自单个点)
C) 使用方圆的参数方程(方圆是因为如果是矩形,超椭圆在我看来就像废话)(需要将其切成两半并像豪华轿车一样拉伸(stretch))并从中创建一条路径,然后绘制沿着该路径以断续线的形式使用 t = 2 * (pi)/某个除数来建立分辨率。这样做的问题是修改后的(豪华轿车式)形状将是分段函数,因此不能由 t 驱动。另外,即使可能,破折号的大小也不会是规则的,因为一些明显的原因我无法用语言表达。
这怎么办?
最佳答案
如果笔画的长度(形状的周长)是破折号大小的整数倍,则破折号不会被截断。
因此,需要根据周长动态调整破折号的大小。请参阅this和 this分别用于查找参数曲线和非参数曲线的弧长。如果这太难集成,还可以考虑计算形状的基础 CGPath
中每个 CGPathElement
的长度。请参阅this gist (尽管它是用 Swift 2 编写的),或 this repo了解如何执行此操作。
对于带有圆角半径的圆角矩形,只需将直线部分和圆形部分的长度相加即可。
.listRowBackground(
GeometryReader { geo in
let strokeWidth: CGFloat = 4
let radius: CGFloat = 15
let insettedDiameter = radius * 2 - strokeWidth
let desiredDash: CGFloat = 10
// note that we need to take the inset of strokeBorder into account
// or just use stroke instead of strokeBorder to make this simpler
let perimeter = (geo.size.width - strokeWidth / 2 - insettedDiameter) * 2 + // horizontal straight edges
(geo.size.height - strokeWidth / 2 - insettedDiameter) * 2 + // vertical straight edges
(insettedDiameter * .pi) // the circular parts
// this finds the smallest adjustedDash such that
// - perimeter is an integer multiple of adjustedDash
// - adjustedDash > desiredDash
let floored = floor(perimeter / desiredDash)
let adjustedDash = (perimeter - desiredDash * floored) / floored + desiredDash
RoundedRectangle(cornerRadius: radius)
.strokeBorder(style: StrokeStyle(lineWidth: strokeWidth, dash: [adjustedDash]))
}
)
示例输出:
关于ios - 在 SwiftUI 中为圆角矩形创建均匀分布的虚线轮廓,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77740803/