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

Swift绘图异常求助:代码无法绘制线条仅显示微小圆点

排查画线App仅显示小圆点的问题

从你给出的代码片段和描述来看,大概率是触摸事件处理不完整或者绘制逻辑有问题,我来帮你一步步排查:

1. 检查Line结构体的实现

首先确保你的Line类/结构体正确存储了起点和终点,并且终点支持修改(拖动时需要实时更新):

struct Line {
    let begin: CGPoint
    var end: CGPoint // 终点设为可变,方便拖动时更新
    let color: UIColor
    let width: CGFloat
    
    init(begin: CGPoint, end: CGPoint, color: UIColor = .black, width: CGFloat = 3.0) {
        self.begin = begin
        self.end = end
        self.color = color
        self.width = width
    }
}

如果你的Line里终点是不可变的,拖动时就无法更新线条的终点,自然只能显示起点的圆点。

2. 补全触摸事件的处理逻辑

你可能只实现了touchesBegan,但缺少touchesMoved和touchesEnded的处理,这会导致线条无法跟随手指拖动更新:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesBegan(touches, with: event)
    guard let touch = touches.first else { return }
    let startPoint = touch.location(in: self)
    // 初始化当前线条,终点暂时和起点一致
    currentLine = Line(begin: startPoint, end: startPoint)
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesMoved(touches, with: event)
    guard let touch = touches.first, var line = currentLine else { return }
    let currentPoint = touch.location(in: self)
    // 更新当前线条的终点
    line.end = currentPoint
    currentLine = line
    // 必须调用这个方法触发重绘,否则界面不会实时更新
    setNeedsDisplay()
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesEnded(touches, with: event)
    guard let line = currentLine else { return }
    // 将完成的线条加入已完成数组
    finishedLines.append(line)
    currentLine = nil
    setNeedsDisplay()
}

如果没有touchesMoved里的setNeedsDisplay(),即使更新了currentLine的终点,界面也不会实时刷新,只会在触摸结束时显示最后一个点。

3. 检查draw(_ rect:)的绘制逻辑

绘制方法里要正确遍历已完成的线条和当前正在绘制的线条,用UIBezierPath绘制完整的线段,而不是单个点:

override func draw(_ rect: CGRect) {
    super.draw(rect)
    
    // 先绘制已完成的线条
    for line in finishedLines {
        drawLine(line)
    }
    
    // 再绘制当前正在绘制的线条
    if let currentLine = currentLine {
        drawLine(currentLine)
    }
}

// 封装绘制单条线的方法,避免重复代码
private func drawLine(_ line: Line) {
    let path = UIBezierPath()
    path.move(to: line.begin)
    path.addLine(to: line.end)
    path.lineWidth = line.width
    path.lineCapStyle = .round // 让线条两端圆润,避免尖锐的点
    line.color.setStroke()
    path.stroke()
}

如果你的draw方法里只绘制了起点(比如只调用了path.move(to: line.begin),没有addLine(to: line.end)),那自然只会显示一个圆点。另外,设置lineCapStyle = .round可以让线条的端点更圆润,符合常规画线App的体验。

4. 额外检查点

  • 确保你的DrawView已经添加到ViewController的视图层级中,并且frame设置正确(比如不要设成CGRectZero)。
  • 检查DrawView的backgroundColor是否和线条颜色一致,导致线条被背景遮挡(比如背景是黑色,线条也是黑色)。

按照上面的步骤调整代码后,应该就能正常绘制线条了。

内容的提问来源于stack exchange,提问作者new programmer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:14:33