提问人:Westsider 提问时间:10/18/2023 最后编辑:Benzy NeezWestsider 更新时间:10/18/2023 访问量:41
SwiftUI 自定义圆角 RectangleShape
SwiftUI Custom Rounded RectangleShape
问:
我按照苹果教程提出了这个,但对于我想做的事情来说,它似乎过于复杂,而且并不完全圆润。对我来说,这似乎也很难实施和维护。似乎有一种更简单的方法。谢谢你的想法。
struct HexagonParameters {
struct Segment {
let line: CGPoint
let curve: CGPoint
let control: CGPoint
}
static let adjustment: CGFloat = 0.085
static let topSholdHt = 0.13
static let botSholdHt = 0.87
static let segments = [
Segment( // top center
line: CGPoint(x: 0.80, y: topSholdHt), // top right
curve: CGPoint(x: 0.20, y: topSholdHt), // top left
control: CGPoint(x: 0.50, y: 0.00) // center / peak
),
Segment( // upper left
line: CGPoint(x: 0.05, y: 0.20),
curve: CGPoint(x: 0.00, y: 0.30),
control: CGPoint(x: 0.0, y: 0.23)
),
Segment( // lower left
line: CGPoint(x: 0.00, y: 0.70),
curve: CGPoint(x: 0.05, y: 0.80),
control: CGPoint(x: 0.00, y: 0.78)
),
Segment( // bottom center
line: CGPoint(x: 0.20, y: botSholdHt),
curve: CGPoint(x: 0.80, y: botSholdHt),
control: CGPoint(x: 0.50, y: 1.00)
),
Segment( // lower right
line: CGPoint(x: 0.95, y: 0.80),
curve: CGPoint(x: 1.00, y: 0.70),
control: CGPoint(x: 1.00, y: 0.78)
),
Segment(
line: CGPoint(x: 1.00, y: 0.30),
curve: CGPoint(x: 0.95, y: 0.20),
control: CGPoint(x: 1.00, y: 0.23)
)
]
}
结构是这样用的
struct ContentView: View {
var body: some View {
Path { path in
var width: CGFloat = 300.0
let height = width
path.move(
to: CGPoint(
x: width * 0.95,
y: height * 0.20
)
)
HexagonParameters.segments.forEach { segment in
path.addLine(
to: CGPoint(
x: width * segment.line.x,
y: height * segment.line.y
)
)
path.addQuadCurve(
to: CGPoint(
x: width * segment.curve.x,
y: height * segment.curve.y),
control: CGPoint(
x: width * segment.control.x,
y: height * segment.control.y
)
)
}
}
.stroke(style: StrokeStyle(lineWidth: 2))
.foregroundColor(Color.black)
.padding(.horizontal)
}
}
答:
1赞
Benzy Neez
10/18/2023
#1
正如我在评论中所说,看起来您自己解决了它,您的代码生成了问题中的形状。
但是,您说您的形状是:
不完美圆润
所以我想知道你是否在尝试实现一个更平滑的形状,在角落附近没有倒弧?
假设是这种情况,以下是如何解决它 自定义 .我不会说它比你原来的维护更简单,但至少它展示了一种不同的方法。Shape
struct Lozenge: Shape {
func path(in rect: CGRect) -> Path {
let cornerRadius = min(rect.size.width, rect.size.height) * 0.1
let middleHeight = rect.size.height * 0.15
let cornerAngleRadians = atan2(rect.size.width, rect.size.height - (2 * middleHeight))
let cornerAngleDegrees = cornerAngleRadians * 180 / Double.pi
var path = Path()
var x = rect.minX
var y = rect.minY + cornerRadius + middleHeight
path.move(to: CGPoint(x: x, y: y))
// Top-left corner
x += cornerRadius
path.addArc(
center: CGPoint(x: x, y: y),
radius: cornerRadius,
startAngle: .degrees(-180),
endAngle: .degrees(-180 + cornerAngleDegrees),
clockwise: false
)
// Middle bump on top
x = rect.maxX - cornerRadius + (cornerRadius * cos(cornerAngleRadians))
y = rect.minY + middleHeight + cornerRadius - (cornerRadius * sin(cornerAngleRadians))
path.addQuadCurve(
to: CGPoint(x: x, y: y),
control: CGPoint(x: rect.midX, y: rect.minY - middleHeight)
)
// Top-right corner
x = rect.maxX - cornerRadius
y = rect.minY + cornerRadius + middleHeight
path.addArc(
center: CGPoint(x: x, y: y),
radius: cornerRadius,
startAngle: .degrees(-cornerAngleDegrees),
endAngle: .degrees(0),
clockwise: false
)
// Bottom-right corner
y = rect.maxY - cornerRadius - middleHeight
path.addArc(
center: CGPoint(x: x, y: y),
radius: cornerRadius,
startAngle: .degrees(0),
endAngle: .degrees(cornerAngleDegrees),
clockwise: false
)
// Lower bump on bottom
x = rect.minX + cornerRadius - (cornerRadius * cos(cornerAngleRadians))
y = rect.maxY - middleHeight - cornerRadius + (cornerRadius * sin(cornerAngleRadians))
path.addQuadCurve(
to: CGPoint(x: x, y: y),
control: CGPoint(x: rect.midX, y: rect.maxY + middleHeight)
)
// Bottom-left corner
x = rect.minX + cornerRadius
y = rect.maxY - cornerRadius - middleHeight
path.addArc(
center: CGPoint(x: x, y: y),
radius: cornerRadius,
startAngle: .degrees(180 - cornerAngleDegrees),
endAngle: .degrees(180),
clockwise: false
)
path.closeSubpath()
return path
}
}
struct ContentView: View {
var body: some View {
Lozenge()
.stroke(lineWidth: 3)
.frame(width: 300, height: 250)
.background(.yellow)
}
}
评论
0赞
Westsider
10/18/2023
非常感谢。我试图弄清楚如何使用 addArc 做到这一点,但就是无法得到它。哇!我现在也能看到我哪里出了问题。
0赞
Westsider
10/18/2023
这是一个巨大的帮助 - 谢谢!!
0赞
Benzy Neez
10/18/2023
不客气😊 感谢您接受答案。
0赞
Benzy Neez
10/18/2023
@Westsider 将弧度转换为度数的公式中存在错误(使用 + 而不是 *)。现已更正。
0赞
Westsider
10/19/2023
啊 - 很棒的收获 - 比你!!
评论
Shape