[iOS]使用UIBezierPath在drawRect中绘制三角形无效果问题
问题:使用UIBezierPath绘制三角形不显示
我正在学习使用UIBezierPath构建自定义图形,尝试绘制一个简单的三角形,以下是我使用的代码:
class ViewController: UIViewController { let customView = CustomTraingleView(frame: CGRectZero) override func viewDidLoad() { super.viewDidLoad() view.addSubview(customView) customView.frame = CGRect(origin: CGPoint(x: 150, y: 200), size: CGSize(width: 100, height: 100)) } } class CustomTraingleView: UIView { override init(frame: CGRect) { super.init(frame: frame) backgroundColor = UIColor.red } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func draw(_ rect: CGRect) { let viewSize = self.bounds.size let path = UIBezierPath() path.lineWidth = 3 path.move(to: CGPoint(x: frame.origin.x + viewSize.width/2, y: frame.origin.y + viewSize.height/2)) path.addLine(to: CGPoint(x: frame.origin.x + (3 * viewSize.width)/4, y: frame.origin.y + (3 * viewSize.height)/4)) path.addLine(to: CGPoint(x: frame.origin.x + viewSize.width/2, y: frame.origin.y + (3 * viewSize.height)/4)) UIColor.black.setStroke() path.stroke() path.close() } }
目前仅能看到添加的视图显示红色背景,没有任何图形被渲染,恳请帮忙排查问题所在。
问题排查与修复
导致三角形不显示的核心问题有两个:
- 坐标系错误:
draw(_:)方法的绘图坐标系基于视图自身的bounds(原点是视图内部左上角,即(0,0)),你却用了视图在父视图中的位置frame.origin来计算路径坐标,导致绘制的三角形偏移到了红色视图的可视区域之外,自然看不到。 - 路径闭合时机错误:你在
path.stroke()之后调用path.close(),此时描边操作已经完成,闭合路径的修改不会生效,即便坐标正确,三角形也会缺少最后一条边。
修复后的代码如下:
class CustomTraingleView: UIView { override init(frame: CGRect) { super.init(frame: frame) backgroundColor = UIColor.red } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func draw(_ rect: CGRect) { let viewSize = rect.size // 直接使用draw方法传入的rect参数,等价于当前视图的bounds let path = UIBezierPath() path.lineWidth = 3 // 基于视图自身内部坐标系计算点位置 path.move(to: CGPoint(x: viewSize.width/2, y: viewSize.height/2)) path.addLine(to: CGPoint(x: (3 * viewSize.width)/4, y: (3 * viewSize.height)/4)) path.addLine(to: CGPoint(x: viewSize.width/2, y: (3 * viewSize.height)/4)) // 先闭合路径,再执行描边 path.close() UIColor.black.setStroke() path.stroke() } }
额外优化提示:如果需要填充三角形,可以在描边前添加UIColor.black.setFill()和path.fill()操作。
内容的提问来源于stack exchange,提问作者sr116
相关产品推荐
相关产品推荐

