使用 Swift 3.0 实时画线

Posted

技术标签:

【中文标题】使用 Swift 3.0 实时画线【英文标题】:Draw a line realtime with Swift 3.0 【发布时间】:2016-09-21 15:20:39 【问题描述】:

我正在尝试在 UIImageView 上绘图。使用 Swift 1.2,我能够让它工作,但我必须将它转换为 swift 3.0,我就是无法让它工作。

它需要做的就是准确地用手指在屏幕上绘制。

代码没有给出任何错误,但没有显示任何内容。

变量;

var lastPoint = CGPoint.zero
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var brushWidth: CGFloat = 10.0
var opacity: CGFloat = 1.0
var swiped = false

代码;

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
    swiped = false
    if let touch = touches.first 
        lastPoint = touch.location(in: self.view)
    


func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) 


    imageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height))
    UIGraphicsBeginImageContext(self.imageView.bounds.size);
    let context = UIGraphicsGetCurrentContext()

        context?.move(to: fromPoint)
        context?.addLine(to: toPoint)

        context?.setLineCap(CGLineCap.round)
        context?.setLineWidth(brushWidth)
        context?.setStrokeColor(red: red, green: green, blue: blue, alpha: 1.0)
        context?.setBlendMode(CGBlendMode.normal)

        imageView.image = UIGraphicsGetImageFromCurrentImageContext()
        imageView.alpha = opacity
        UIGraphicsEndImageContext()



override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) 
    swiped = true
    if let touch = touches.first 
        let currentPoint = touch.location(in: view)
        drawLineFrom(fromPoint: lastPoint, toPoint: currentPoint)

        lastPoint = currentPoint
    


override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) 
    if !swiped 
                    // draw a single point
        self.drawLineFrom(fromPoint: lastPoint, toPoint: lastPoint)
    

【问题讨论】:

所有函数调用正确,imageView帧设置也正确,启动时imageView设置为实际图片。绘图开始时 imageView 变为白色。 据我所见,您在每次迭代中只绘制微小像素,擦除旧像素。您注释掉了在上下文中绘制旧图像 是否缺少代码?我没有看到UIGraphicsBeginImageContext(...) @Knight0fDragon 我已经编辑了帖子! 你仍然没有在上下文中绘制 【参考方案1】:

你必须开始图像上下文:

UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0)

您还必须描边路径:

context?.strokePath()

你也没有画上一张图片:

imageView.image?.draw(in: view.bounds)

因此:

func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) 
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0)

    imageView.image?.draw(in: view.bounds)

    let context = UIGraphicsGetCurrentContext()

    context?.move(to: fromPoint)
    context?.addLine(to: toPoint)

    context?.setLineCap(CGLineCap.round)
    context?.setLineWidth(brushWidth)
    context?.setStrokeColor(red: red, green: green, blue: blue, alpha: 1.0)
    context?.setBlendMode(CGBlendMode.normal)
    context?.strokePath()

    imageView.image = UIGraphicsGetImageFromCurrentImageContext()
    imageView.alpha = opacity
    UIGraphicsEndImageContext()

【讨论】:

您好,我们如何才能清除imageView 中的勾画线? 您可以设置imageView.image = nil 来擦除整个内容。如果您只想删除最后一行,则必须在开始绘制路径之前将旧图像保存在某处,然后在您想要撤消笔划时将其恢复。但要小心,因为图像是资源占用,所以不要试图同时在内存中保存一堆旧图像! @Rob 我正在尝试实现类似的东西,但就我而言,我只想在视图中绘制。如何给 self.view (UIGraphics) 提供上下文? @user2924482 - 有两种方法:首先,您可以将UIView 子类化并将您的视图绘制在draw(rect:) 中的某个时间点。你可以只stroke 你的UIBezierPath,安全地知道你已经在draw(rect:) 中的图形上下文中。其次(恕我直言,甚至更简单),您可以使用CAShapeLayer,将其添加为视图layer 的子层,设置形状层的path,形状层负责处理所有笔触和图形上下文内容为你。见***.com/a/16846770/1271826。

以上是关于使用 Swift 3.0 实时画线的主要内容,如果未能解决你的问题,请参考以下文章

Swift 中的实时录音

使用 Swift 使用 AVAudioEngine 实时进行音高转换

Swift3:用户输入的实时 UiLabel 更新

如何获得低于 3.0 版本的 Android 设备的实时流媒体音频?

将 async/await (Swift 5.5) 与 firebase 实时数据库一起使用

Swift中字典对象的Firebase实时问题