SwiftUI:如何在自定义环形分段形状上垂直居中文字
解决SwiftUI环形分段按钮文本居中+同步旋转问题
要实现CurvedButton内部文本精准垂直居中,且随按钮旋转同步调整方向,不用hacky的padding,我们可以直接基于你已有的CurvedButtonGeometry做扩展,用几何计算来定位和旋转文本。
1. 扩展几何工具类,封装中心位置和旋转角度
先给CurvedButtonGeometry加两个计算属性,帮我们快速拿到按钮的几何中心和文本需要的旋转角度:
extension CurvedButtonGeometry { // 环形按钮的几何中心:内外半径中间,角度范围的中间点 var buttonCenter: CGPoint { let midRadius = lerp(innerRadius, outerRadius, by: 0.5) let midAngle = lerp(data.start, data.end, by: 0.5) return CGPoint( x: center.x + CGFloat(cos(.degrees(midAngle))) * midRadius, y: center.y + CGFloat(sin(.degrees(midAngle))) * midRadius ) } // 文本旋转角度:让文本沿按钮弧度的切线方向正向显示 var textRotationAngle: Angle { let midAngle = lerp(data.start, data.end, by: 0.5) // 加90度是为了让文本垂直于弧度,保证可读方向正确 return .degrees(midAngle + 90) } }
2. 重构按钮视图,实现精准布局
修改你的CircularCVBControl,用GeometryReader获取按钮的布局帧,然后用上面的扩展属性来定位和旋转文本:
struct CircularCVBControl: View { var body: some View { Button {} label: { GeometryReader { geo in let buttonData = CurvedButtonData(position: .top) let geometry = CurvedButtonGeometry(curvedButtonData: buttonData, rect: geo.frame(in: .local)) CurvedButton(data: buttonData) .fill(.blue) .overlay( Text("Click me") .foregroundColor(.red) .position(geometry.buttonCenter) .rotationEffect(geometry.textRotationAngle) ) } .frame(width: 200, height: 200) // 根据需求调整按钮尺寸 } .buttonStyle(.plain) } }
3. 测试多位置适配
不管你把按钮位置改成.right、.bottom还是.left,文本都会自动居中,并且旋转到匹配按钮弧度的正确方向。比如右侧按钮的文本会垂直向上,底部按钮的文本会水平反向,完全符合环形控件的视觉逻辑。
为什么这个方案可行?
- 完全基于你已有的几何逻辑,没有硬编码padding,适配任何尺寸的按钮
- 位置计算用线性插值拿到环形的中间点,确保文本在分段的垂直(径向)和水平(弧向)都居中
- 旋转角度基于按钮的中间角度计算,保证文本方向始终和按钮弧度匹配,按钮位置变化时自动同步旋转
内容的提问来源于stack exchange,提问作者linus_hologram
相关产品推荐
相关产品推荐

