iOS开发:如何使用UIBezierPath绘制指定规格的复选框图标?
嘿,我懂你这种卡在UIBezierPath绘制特定图标上的感受——尤其是这种有严格边界要求的复选框,既要贴合5×5的整体范围,又得让勾超出内部3×3区域,确实容易绕晕。我来给你捋清楚实现思路,再附上代码示例,应该能帮你快速搞定!
实现思路与代码示例
1. 先明确坐标与尺寸逻辑
UIKit的坐标系以左上角为原点,y轴向下延伸。我们把5×5的整体边界对应到按钮的bounds,通过比例适配保证在不同尺寸按钮上都能符合设计要求:
- 单位长度:
let unit = bounds.width / 5.0(以宽度为准,确保图标是正方形) - 内部3×3区域的原点:
(unit, unit)(整体边界两边各留1单位的边距)
2. 绘制超出边界的复选框路径
这里以常见的“勾形”复选框为例,让勾的两端分别超出3×3的下边界和右边界,代码如下:
private func createCheckboxPath(in bounds: CGRect) -> UIBezierPath { let path = UIBezierPath() let unit = bounds.width / 5.0 // 勾的起点:内部3×3区域的左下偏上位置 let startPoint = CGPoint(x: unit, y: unit * 3) path.move(to: startPoint) // 第一个拐点:超出内部3×3的下边界(内部下边界为4*unit,延伸至4.5*unit) let middlePoint = CGPoint(x: unit * 2, y: unit * 4.5) path.addLine(to: middlePoint) // 第二个拐点:超出内部3×3的右边界(内部右边界为4*unit,延伸至4.5*unit) let endPoint = CGPoint(x: unit * 4.5, y: unit) path.addLine(to: endPoint) // 调整线条样式,让图标更圆润自然 path.lineWidth = unit * 0.6 path.lineCapStyle = .round path.lineJoinStyle = .round return path }
3. 集成到自定义按钮中
创建一个UIButton子类,在draw(_:)方法里调用路径绘制逻辑,还可以添加调试用的边界虚线:
class CustomCheckboxButton: UIButton { override func draw(_ rect: CGRect) { super.draw(rect) // 可选:绘制5×5的边界虚线,方便调试对齐 let borderPath = UIBezierPath(rect: rect) borderPath.lineWidth = 0.5 borderPath.setLineDash([1, 1], count: 2, phase: 0) UIColor.lightGray.setStroke() borderPath.stroke() // 绘制复选框主体 let checkboxPath = createCheckboxPath(in: rect) UIColor.black.setStroke() checkboxPath.stroke() } private func createCheckboxPath(in bounds: CGRect) -> UIBezierPath { // 插入上面的路径代码 } }
4. 处理CorelDRAW制作的加号图标
你用CorelDRAW做的加号图标,建议导出为PDF格式(矢量图,缩放不失真),然后通过以下方法转成UIBezierPath:
private func createPlusPath(from pdfName: String, in bounds: CGRect) -> UIBezierPath? { guard let url = Bundle.main.url(forResource: pdfName, withExtension: "pdf"), let pdfDoc = CGPDFDocument(url as CFURL), let page = pdfDoc.page(at: 1) else { return nil } let pageRect = page.getBoxRect(.mediaBox) let path = UIBezierPath() // 遍历PDF页面的路径元素,还原加号形状 page.applyPDFPath { elements in for element in elements { switch element.type { case .moveTo: path.move(to: element.points[0]) case .lineTo: path.addLine(to: element.points[0]) case .curveTo: path.addCurve(to: element.points[2], controlPoint1: element.points[0], controlPoint2: element.points[1]) case .closeSubpath: path.close() @unknown default: break } } } // 缩放路径到按钮边界,保持比例 let scale = min(bounds.width / pageRect.width, bounds.height / pageRect.height) path.apply(CGAffineTransform(scaleX: scale, y: scale)) return path }
之后在按钮的draw(_:)方法里调用这个方法,设置颜色后绘制即可。
小提示
- 如果你的复选框是“方框+勾”的样式,先绘制3×3的方框(路径为
UIBezierPath(rect: CGRect(x: unit, y: unit, width: unit*3, height: unit*3))),再叠加勾的路径 - 调试时可以打开Xcode的「Debug View Hierarchy」,直观查看路径的实际位置是否符合预期
内容的提问来源于stack exchange,提问作者Nerdy Bunz
相关产品推荐
相关产品推荐

