You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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参数,让弧形方向正确(向下凹陷)
  • 简化中间部分的路径逻辑,避免原代码中不必要的重复计算

额外优化建议

  1. 中间按钮的offset(y: -36)可以和Shape的arcDepth关联,比如用Constants.arcDepth + Constants.buttonRadius,调整尺寸时不用手动修改两个地方
  2. 如果需要适配不同屏幕尺寸,建议用相对值(基于rect.width的比例)代替固定常量,适配性更好

内容的提问来源于stack exchange,提问作者Dimpy-iRoid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:25:18