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

Swift UIView调用draw后如何用UIBezierPath追加绘制图形?

问题解决思路

你的问题出在iOS的绘制机制上:draw(_:)是系统管理的专属绘制入口,只有这个方法内的绘制操作才会被正确渲染并持久化;直接在外部调用drawArrow()时,没有处于有效的图形上下文环境中,绘制内容无法被保留,而且下次draw(_:)执行时会覆盖所有临时绘制结果。

另外你提供的控制器代码遗漏了将bezierView添加到父视图的步骤(不过从你的输出图看主路径已显示,推测实际代码里补充了这一步,但仍需注意规范)。

修正方案

1. 修改BezierView,用状态变量控制绘制

把箭头的绘制逻辑整合到draw(_:)方法中,通过布尔变量控制是否绘制箭头:

final class BezierView: UIView {
    var currentPoint: CGPoint = CGPoint()
    // 新增状态变量:控制是否绘制箭头
    var shouldDrawArrow = false

    override func draw(_ rect: CGRect) {
        // 绘制主路径
        let line1 = UIBezierPath()
        line1.move(to: CGPoint(x: 20, y: 65))
        line1.addLine(to: CGPoint(x: 20, y: 15))
        line1.addLine(to: CGPoint(x: self.frame.width - 20, y: 5))
        line1.addLine(to: CGPoint(x: self.frame.width - 20, y: 65))
        line1.lineWidth = 2
        UIColor.darkGray.setStroke()
        line1.stroke()
        currentPoint = line1.currentPoint

        // 根据状态决定是否绘制箭头
        if shouldDrawArrow {
            drawArrow()
        }
    }

    private func drawArrow() {
        let point = currentPoint
        let arrowTip = UIBezierPath()
        arrowTip.move(to: point)
        arrowTip.addLine(to: CGPoint(x: point.x - 6, y: point.y - 6))
        arrowTip.addLine(to: CGPoint(x: point.x + 6, y: point.y - 6))
        arrowTip.close()
        UIColor.darkGray.setFill()
        arrowTip.fill()
    }
}

2. 修改控制器代码,正确触发重绘

设置状态变量后,调用setNeedsDisplay()通知系统触发重绘:

override func viewDidLoad() {
    super.viewDidLoad()
    let bezierView = BezierView(frame: CGRect(x: 0, y: 40, width: self.view.frame.width, height: 200))
    view.addSubview(bezierView) // 必须添加到父视图才能显示
    // 开启箭头绘制并触发重绘
    bezierView.shouldDrawArrow = true
    bezierView.setNeedsDisplay()
}

核心原理

iOS的视图绘制由系统统一调度,只有在draw(_:)方法内,系统才会创建并传递有效的图形上下文(CGContext)。所有需要持久化的绘制操作都应该放在这个方法里,外部通过修改状态变量+调用setNeedsDisplay()触发更新,系统会重新调用draw(_:),根据最新状态完成完整绘制。

内容的提问来源于stack exchange,提问作者Mehmet Ali Kısacık

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 18:20:42