SwiftUI弧形底部栏实现问题:代码生成效果不够圆润
弧形底部栏圆润度优化方案
我想要实现一个弧形底部栏,但用下面的代码生成的弧形效果不够圆润,相关代码及效果如下:
struct customShape: Shape { var xAxis : CGFloat var animatableData: CGFloat{ get { return xAxis} set { xAxis = newValue} } func path(in rect: CGRect) -> Path { return Path { path in path.move(to: CGPoint(x: 0, y: 0)) path.addLine(to: CGPoint(x: rect.width, y: 0)) path.addLine(to: CGPoint(x: rect.width, y: rect.height)) path.addLine(to: CGPoint(x: 0, y: rect.height)) let center = xAxis path.move(to: CGPoint(x: center - 43, y: 0)) let to1 = CGPoint(x: center, y: 50) let center1 = CGPoint(x: center - 30, y: 0) let center2 = CGPoint(x: center - 46, y: 42) let to2 = CGPoint(x: center + 52, y: 0) let center3 = CGPoint(x: center + 57, y: 47) let center4 = CGPoint(x: center + 35, y: 0) path.addCurve(to: to1, control1: center1, control2: center2) path.addCurve(to: to2, control1: center3, control2: center4) } } }
效果展示:
优化方案
原代码的问题在于贝塞尔曲线的控制点设置缺乏对称逻辑,导致弧度衔接生硬。这里提供两种优化方式:
方式一:使用圆弧API直接绘制(最推荐)
用addArc可以生成标准的圆润圆弧,无需手动调整控制点:
struct CustomShape: Shape { var xAxis: CGFloat var animatableData: CGFloat { get { xAxis } set { xAxis = newValue } } func path(in rect: CGRect) -> Path { Path { path in // 绘制底部栏的基础矩形 path.move(to: .zero) path.addLine(to: CGPoint(x: rect.width, y: 0)) path.addLine(to: CGPoint(x: rect.width, y: rect.height)) path.addLine(to: CGPoint(x: 0, y: rect.height)) path.closeSubpath() // 绘制中间的圆润弧形 let arcRadius: CGFloat = 40 // 可根据需求调整半径 let arcCenter = CGPoint(x: xAxis, y: 0) // 从左侧端点开始,逆时针绘制半圆 path.move(to: CGPoint(x: xAxis - arcRadius, y: 0)) path.addArc(center: arcCenter, radius: arcRadius, startAngle: .pi, endAngle: 0, clockwise: false) } } }
方式二:优化贝塞尔曲线控制点
如果坚持用贝塞尔曲线,需要让控制点与起点、终点保持对称的几何关系,保证曲线平滑:
struct CustomShape: Shape { var xAxis: CGFloat var animatableData: CGFloat { get { xAxis } set { xAxis = newValue } } func path(in rect: CGRect) -> Path { Path { path in // 绘制底部栏基础矩形 path.move(to: .zero) path.addLine(to: CGPoint(x: rect.width, y: 0)) path.addLine(to: CGPoint(x: rect.width, y: rect.height)) path.addLine(to: CGPoint(x: 0, y: rect.height)) let center = xAxis let arcWidth: CGFloat = 80 // 弧形总宽度 let arcDepth: CGFloat = 40 // 弧形凹陷深度 // 左侧曲线:从左端点到最低点 path.move(to: CGPoint(x: center - arcWidth/2, y: 0)) path.addCurve( to: CGPoint(x: center, y: arcDepth), control1: CGPoint(x: center - arcWidth/2 + arcDepth*0.7, y: 0), control2: CGPoint(x: center, y: arcDepth*0.7) ) // 右侧曲线:从最低点到右端点 path.addCurve( to: CGPoint(x: center + arcWidth/2, y: 0), control1: CGPoint(x: center, y: arcDepth*0.7), control2: CGPoint(x: center + arcWidth/2 - arcDepth*0.7, y: 0) ) } } }
两种方式都能让弧形更圆润,其中方式一的圆弧API能保证绝对的平滑度,调整半径就能快速适配需求。
内容的提问来源于stack exchange,提问作者Priyanka Vasant
相关产品推荐
相关产品推荐

