迅速在UIImageView上绘图 [英] Drawing on UIImageView in swift

查看:79
本文介绍了迅速在UIImageView上绘图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试开发一个应用程序,可以在UIImageView上绘制一些内容.我有以下代码.

I am trying to develop an app where I can draw something on the UIImageView. I have got the following code.

import UIKit
class Line
{
    var startPoint:CGPoint
    var endPoint:CGPoint

    init (start:CGPoint , end:CGPoint)
    {
        startPoint = start
        endPoint = end
    }
}


class AnnotationView: UIView {

    static internal let nibName = "AnnotationView"
    @IBOutlet weak var imageView: UIImageView!
    var lines :[Line] = []
    var lastPoint:CGPoint!


    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        lastPoint = touches.first?.location(in: self)
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch  = touches.first
        {
            let newPoint = touch.location(in:self)
            lines.append(Line(start: lastPoint, end: newPoint))
            lastPoint = newPoint
            self.setNeedsDisplay()
        }
    }
    override func draw(_ rect: CGRect) {
        if let context = UIGraphicsGetCurrentContext()
        {
            context.beginPath()
            for line in lines
            {
                context.move(to: line.startPoint)
                context.addLine(to: line.endPoint)
            }
            context.setLineCap(CGLineCap.round)
            context.setStrokeColor(red: 0, green: 0, blue: 0, alpha: 1)
            context.setLineWidth(5)
            context.strokePath()
        }
    }
}

所以现在在上面的代码中,我有一个从UIView派生的AnnotationView类,在这里我有一个UIImageView,我将其设置为来自接口构建器的超级视图的完整大小.这是一个简单的绘图应用程序,在这里我想在UIImageView上绘制一些东西.现在的问题是,当imageView.image为nil时,它确实显示了我的绘图,并且如果为imageView.image设置了任何图像,则它不显示该绘图.它只是显示在此imageView中设置的图像.我在两种情况下都调试了所有方法的调用.我肯定缺少某些东西.谁能帮帮我吗?我想在我的UIImageView中设置的图像上显示我的绘图.问候,内娜(Neena)

so now in the above code I have AnnotationView class derived from UIView where I have a UIImageView which I set to full size of the superview from the interface builder. This is a simple drawing app where I want to draw somethings on the UIImageView. Now the problem is when the imageView.image is nil then it does show my drawing and if there is any image set for imageView.image then it doesn't show the drawing. It just show the image that is set in this imageView. I have debugged in both scenarios all the methods get called. There is surely something which I am missing. Can anyone please help me? I want to show my drawing on top of the image which I have set in my UIImageView. Regards, neena

推荐答案

问题是您正在绘制 AnnotationView 的主层,该主层位于其任何子视图(包括您的子视图)的后面 UIImageView .解决方案是将图形移动到添加到 AnnotationView 主层的单独的 sublayer .

The problem is that you're drawing in the AnnotationView's main layer which is laid behind any of its subviews, including your UIImageView. The solution is to move your drawing to separate sublayer added to AnnotationView's main layer.

除了直接在 draw()方法中绘制线条外,您还需要为绘图叠加层提供单独的图层.将此属性添加到您的 AnnotationView :

Instead of drawing your lines directly in draw() method, you need to have a separate layer for your drawing overlay. Add this property to your AnnotationView:

let drawingLayer = CAShapeLayer()

并重写 awakeFromNib(),以在从Storyboard/Nib加载视图后立即使该层成为所有其他内容之上的子层:

And override awakeFromNib() to make this layer a sublayer on top of everything else as soon as your view is loaded from Storyboard/Nib:

override func awakeFromNib() {
    super.awakeFromNib()
    layer.addSublayer(drawingLayer)
}

现在,让我们创建一个在每次需要更新覆盖时调用的函数,而不是调用 setNeedsDisplay():

Now let's create a function to call every time you need to update your overlay instead of calling setNeedsDisplay():

func updateDrawingOverlay() {
    let path = CGMutablePath()

    for line in lines {
        path.move(to: line.startPoint)
        path.addLine(to: line.endPoint)
    }

    drawingLayer.frame = imageView.frame
    drawingLayer.path = path
    drawingLayer.lineWidth = 5
    drawingLayer.strokeColor = UIColor.black.cgColor

    setNeedsDisplay()
}

由于现在是多余的,请使用 draw(_:)方法删除您的代码,并从 touchesMoved(_:with:)<替换 setNeedsDisplay()调用 updateDrawingOverlay()调用.

Delete your code in draw(_:) method since it's redundant now, and replace setNeedsDisplay() call from touchesMoved(_: with:) with updateDrawingOverlay() call.

整个事情对您来说应该像这样:

The whole thing should look like this for you:

import UIKit

class Line {
    var startPoint:CGPoint
    var endPoint:CGPoint

    init (start:CGPoint , end:CGPoint) {
        startPoint = start
        endPoint = end
    }
}


class AnnotationView: UIView {
    static internal let nibName = "AnnotationView"
    @IBOutlet weak var imageView: UIImageView!

    var lines :[Line] = []
    var lastPoint:CGPoint!
    let drawingLayer = CAShapeLayer()

    override func awakeFromNib() {
        super.awakeFromNib()
        layer.addSublayer(drawingLayer)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        lastPoint = touches.first?.location(in: self)
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch  = touches.first
        {
            let newPoint = touch.location(in:self)
            lines.append(Line(start: lastPoint, end: newPoint))
            lastPoint = newPoint
            updateDrawingOverlay()
        }
    }

    func updateDrawingOverlay() {
        let path = CGMutablePath()

        for line in lines {
            path.move(to: line.startPoint)
            path.addLine(to: line.endPoint)
        }

        drawingLayer.frame = imageView.frame
        drawingLayer.path = path
        drawingLayer.lineWidth = 5
        drawingLayer.strokeColor = UIColor.black.cgColor

        setNeedsDisplay()
    }
}

这应该可以解决问题,让我知道它的进展.

This should do the trick, let me know how it goes.

这篇关于迅速在UIImageView上绘图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆