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

如何使用UIBezierPath绘制左右带半圆的卡片视图?

实现左右带半圆的自定义卡片视图

需要用UIBezierPath绘制一个左右两侧带有半圆的卡片视图,效果如下:

卡片视图效果

以下是实现该效果的自定义卡片视图类代码:

class CustomCardView : UIView
{
    // 使用矩形frame初始化视图
    override init(frame: CGRect)
    {
        super.init(frame: frame)
        backgroundColor = UIColor.clear
    }
    // 通过反序列化初始化视图
    required init?(coder aDecoder: NSCoder)
    {
        super.init(coder: aDecoder)
        backgroundColor = UIColor.clear
    }
    /// 重写draw(_:)方法自定义视图绘制
    ///
    /// 默认实现为矩形视图
    ///
    override func draw(_ rect: CGRect)
    {
        // 卡片圆角半径
        let cardRadius = CGFloat(10)
        // 侧边半圆的半径
        let circleSlotRadius = CGFloat(20)
        
        // 卡片视图的尺寸
        let viewSize = self.bounds.size
        // 视图有效高度
        let effectiveViewHeight = viewSize.height
          
        // 创建路径对象
        let path = UIBezierPath()
        // 将起点移动到顶部直线的左端点
        path.move(to: CGPoint(x: cardRadius, y: 0))
        
        // MARK: 顶部线条与圆角
        // 绘制顶部直线
        path.addLine(to: CGPoint(x: viewSize.width - cardRadius, y: 0))
        // 绘制右上角圆角弧
        path.addArc(
            withCenter: CGPoint(
                x: viewSize.width - cardRadius,
                y: cardRadius
            ),
            radius: cardRadius,
            startAngle: CGFloat(Double.pi * 3 / 2),
            endAngle: CGFloat(0),
            clockwise: true
        )
        
        // MARK: 右侧线条与半圆
        // 绘制右侧上半段直线
        path.addLine(
            to: CGPoint(x: viewSize.width, y: effectiveViewHeight / 4)
        )
        
        // 绘制右侧半圆的上弧
        path.addArc(
            withCenter: CGPoint(
                x: viewSize.width,
                y: effectiveViewHeight / 4 - circleSlotRadius
            ),
            radius: circleSlotRadius,
            startAngle: CGFloat(0),
            endAngle: CGFloat(Double.pi / 2),
            clockwise: true
        )
        
        // 绘制半圆的外侧直线
        path.addLine(
            to: CGPoint(
                x: viewSize.width + circleSlotRadius,
                y: effectiveViewHeight / 4 + circleSlotRadius
            )
        )
        // 绘制半圆的下弧
        path.addArc(
            withCenter: CGPoint(
                x: viewSize.width,
                y: effectiveViewHeight / 4 + circleSlotRadius
            ),
            radius: circleSlotRadius,
            startAngle: CGFloat(0),
            endAngle: CGFloat(Double.pi),
            clockwise: false
        )
        
        // 绘制右侧下半段直线
        path.addLine(
            to: CGPoint(x: viewSize.width, y: effectiveViewHeight)
        )
        // 绘制右下角圆角弧
        path.addArc(
            withCenter: CGPoint(
                x: viewSize.width - cardRadius,
                y: effectiveViewHeight
            ),
            radius: cardRadius,
            startAngle: CGFloat(0),
            endAngle: CGFloat(Double.pi),
            clockwise: true
        )

        // MARK: 底部线条与圆角
        path.addLine(to: CGPoint(x: cardRadius, y: effectiveViewHeight))

        // 绘制左下角圆角弧
        path.addArc(
            withCenter: CGPoint(
                x: cardRadius,
                y: effectiveViewHeight - cardRadius
            ),
            radius: cardRadius,
            startAngle: CGFloat(Double.pi / 2),
            endAngle: CGFloat(Double.pi),
            clockwise: true
        )

        // MARK: 左侧线条
        // 绘制左侧直线
        path.addLine(to: CGPoint(x: 0, y: cardRadius))
        // 绘制左上角圆角弧
        path.addArc(
            withCenter: CGPoint(x: cardRadius, y: cardRadius),
            radius: cardRadius,
            startAngle: CGFloat(Double.pi),
            endAngle: CGFloat(Double.pi / 2 * 3),
            clockwise: true
        )
      
        // 闭合路径
        path.close()
        // 设置填充颜色并填充路径
        UIColor.gray.set()
        path.fill()
    }
}

注:原代码仅实现了右侧的半圆结构,若需要左侧也添加对称的半圆,可参照右侧的绘制逻辑,在左侧对应位置添加相同的圆弧与直线绘制代码。

内容的提问来源于stack exchange,提问作者aymen Braham

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:22:54