SwiftUI实现中间带顶部弧形的自定义TabBar求助
SwiftUI自定义TabBar中间按钮两侧弧形修正方案
实现方式确认
你当前采用隐藏原生TabBar+自定义Shape绘制TabBar背景+Overlay添加按钮/文字的思路完全正确,这种方案非常适合实现非标准样式的TabBar,能灵活控制所有UI细节,比修改原生TabBar的限制少很多,放心用就行。
中间弧形问题修正
你的核心问题出在TabBarShape的路径绘制逻辑上,尤其是中间按钮两侧的弧形参数计算错误。下面是修正后的完整TabBarShape代码,关键修改点已标注:
struct TabBarShape: Shape { private enum Constants { static let cornerRadius: CGFloat = 20 static let buttonRadius: CGFloat = 30 // 中间按钮半径 static let arcDepth: CGFloat = 8 // 两侧小弧形的凹陷深度 static let arcRadius: CGFloat = 12 // 两侧小弧形的半径 } func path(in rect: CGRect) -> Path { let path = UIBezierPath() // 起点:左下角 path.move(to: CGPoint(x: 0, y: rect.height)) // 左侧竖线到圆角起点 path.addLine(to: CGPoint(x: 0, y: rect.height - Constants.cornerRadius)) // 左上角圆角 path.addArc(withCenter: CGPoint(x: Constants.cornerRadius, y: Constants.cornerRadius), radius: Constants.cornerRadius, startAngle: .pi, endAngle: -.pi/2, clockwise: true) // 左侧水平线段到中间按钮左弧形起点 let leftArcStartX = rect.width/2 - Constants.buttonRadius - Constants.arcRadius path.addLine(to: CGPoint(x: leftArcStartX, y: 0)) // 左侧小弧形(向下凹陷) path.addArc(withCenter: CGPoint(x: leftArcStartX + Constants.arcRadius, y: Constants.arcDepth), radius: Constants.arcRadius, startAngle: .pi, endAngle: 0, clockwise: false) // 中间按钮下方的水平线段(连接左右弧形) let rightArcStartX = rect.width/2 + Constants.buttonRadius path.addLine(to: CGPoint(x: rightArcStartX, y: Constants.arcDepth)) // 右侧小弧形(向下凹陷) path.addArc(withCenter: CGPoint(x: rightArcStartX + Constants.arcRadius, y: 0), radius: Constants.arcRadius, startAngle: .pi, endAngle: 0, clockwise: true) // 右侧水平线段到右上角圆角起点 path.addLine(to: CGPoint(x: rect.width - Constants.cornerRadius, y: 0)) // 右上角圆角 path.addArc(withCenter: CGPoint(x: rect.width - Constants.cornerRadius, y: Constants.cornerRadius), radius: Constants.cornerRadius, startAngle: -.pi/2, endAngle: 0, clockwise: true) // 右侧竖线到右下角 path.addLine(to: CGPoint(x: rect.width, y: rect.height)) // 闭合路径 path.close() return Path(path.cgPath) } }
关键修改说明:
- 新增
arcDepth和arcRadius常量,分别控制小弧形的凹陷深度和弧度半径,方便后续调整 - 重新计算左右弧形的起点和中心点坐标,确保弧形正好贴合中间按钮的两侧
- 修正弧形的
startAngle和endAngle参数,让弧形方向正确(向下凹陷) - 简化中间部分的路径逻辑,避免原代码中不必要的重复计算
额外优化建议
- 中间按钮的
offset(y: -36)可以和Shape的arcDepth关联,比如用Constants.arcDepth + Constants.buttonRadius,调整尺寸时不用手动修改两个地方 - 如果需要适配不同屏幕尺寸,建议用相对值(基于rect.width的比例)代替固定常量,适配性更好
内容的提问来源于stack exchange,提问作者Dimpy-iRoid
相关产品推荐
相关产品推荐

