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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 01:35:16