使用Core Graphics在UIImageView上绘制一个矩形

时间:2017-08-27 14:57:16

标签: ios uiimageview core-graphics

我想让用户在A上绘制一个矩形 我为最后一个触摸位置添加了两个变量 我添加了这个功能: -

UIImageView

我将方法添加到(func draw(from: CGPoint, to: CGPoint) { UIGraphicsBeginImageContext(imageView.frame.size) context = UIGraphicsGetCurrentContext() context?.setStrokeColor(UIColor(red: 0, green: 0, blue: 0, alpha: 1.0).cgColor) context?.setLineWidth(5.0) let currentRect = CGRect(x: from.x, y: from.y, width: to.x - from.x, height: to.y - from.y) context?.addRect(currentRect) context?.drawPath(using: .stroke) context?.strokePath() imageView.image?.draw(in: self.imageView.frame) imageView.image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() } )它绘制了许多矩形

我将方法添加到(touchMoved)它绘制一个,但是当用户移动触摸时它不会出现

screenshot

touchEnded

我希望让用户在override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first { firstTouchLocation = touch.location(in: self.view) } } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first { lastTouchLocation = touch.location(in: self.view) draw(from: firstTouchLocation, to: lastTouchLocation) } } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first { lastTouchLocation = touch.location(in: self.view) draw(from: firstTouchLocation, to: lastTouchLocation) } } 时扩展矩形,并在touchMoved时绘制。

1 个答案:

答案 0 :(得分:1)

您正在使用由前一个image组成的新图片以及在其上绘制的矩形替换您的image。不是从图像视图中绘制图像,而是绘制原始图像。

或者,您可以将矩形渲染为形状图层,然后只更新该形状图层的路径:

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!

    private let shapeLayer: CAShapeLayer = {
        let _shapeLayer = CAShapeLayer()
        _shapeLayer.fillColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0).cgColor
        _shapeLayer.strokeColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1).cgColor
        _shapeLayer.lineWidth = 3
        return _shapeLayer
    }()

    private var startPoint: CGPoint!

    override func viewDidLoad() {
        super.viewDidLoad()

        imageView.layer.addSublayer(shapeLayer)
    }

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

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let startPoint = startPoint, let touch = touches.first else { return }

        let point: CGPoint

        if let predictedTouch = event?.predictedTouches(for: touch)?.last {
            point = predictedTouch.location(in: imageView)
        } else {
            point = touch.location(in: imageView)
        }

        updatePath(from: startPoint, to: point)
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let startPoint = startPoint, let touch = touches.first else { return }

        let point = touch.location(in: imageView)

        updatePath(from: startPoint, to: point)
        imageView.image = imageView.snapshot(afterScreenUpdates: true)
        shapeLayer.path = nil
    }

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        shapeLayer.path = nil
    }

    private func updatePath(from startPoint: CGPoint, to point: CGPoint) {
        let size = CGSize(width: point.x - startPoint.x, height: point.y - startPoint.y)
        let rect = CGRect(origin: startPoint, size: size)
        shapeLayer.path = UIBezierPath(rect: rect).cgPath
    }

}

其中:

extension UIView {
    func snapshot(afterScreenUpdates: Bool = false) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0)
        drawHierarchy(in: bounds, afterScreenUpdates: afterScreenUpdates)
        let image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
}

这不仅更简单,而且效率更高。

产量:

enter image description here

顺便说一下,我可能建议在touchesMoved中使用预测性触摸。在设备(不是模拟器)上,可以产生稍微响应的UI。