如何使用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
相关产品推荐
相关产品推荐

