Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I convert or load a UIImage into a PKDrawing?

I'd like to be able to load a PNG file into a PKCanvasView to be able to draw on and erase parts of it. Is there a way to accomplish this?

like image 231
rawbee Avatar asked Jun 13 '19 03:06

rawbee


3 Answers

Use an UIImageView and put it behind PKCanvasView, then set the PKCanvasView opaque to false, and color to clear. Draw on it is fine, but erase is not possible.

like image 195
Lim Thye Chean Avatar answered Oct 10 '22 02:10

Lim Thye Chean


I can't find any official documentation about this, but I make it work by adding a UIImageView as subview of first subview of PKCanvasView. Zooming is also working perfectly by setting both .maximumZoomScale=1 and .minimumZoomScale=5

But notice this might not work in the future as Apple might change their implementation of PKCanvasView

Here's the sample code for SwiftUI

    func makeUIView(context: Context) -> UIView {
        let view = PKCanvasView()
        ...
        ...
        view.backgroundColor = .clear
        view.isOpaque = false
        view.maximumZoomScale = 5
        view.minimumZoomScale = 1

        let imageView = UIImageView(image: UIImage(named: "NameOfImage"))
        let contentView = Tool.getContentViewFromPkCanvasView(view)
        contentView.addSubview(imageView)
        contentView.sendSubviewToBack(imageView)
        return view
    }
class Tool{
    static func getContentViewFromPkCanvasView(_ view: UIView) -> some UIView {
        return view.subviews[0]
    }
}
like image 43
Po-Wen Kao Avatar answered Oct 10 '22 02:10

Po-Wen Kao


First, put your UIImageView behind PKCanvasView, then set the PKCanvasView opaque to false, and color to clear.

Then in PKCanvasViewDelegate:

func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    return YOUR_IMAGEVIEW
}

func scrollViewDidZoom(_ scrollView: UIScrollView) {

    let offsetX: CGFloat = max((scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5, 0.0)
    let offsetY: CGFloat = max((scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5, 0.0)
    YOUR_IMAGEVIEW.frame.size = CGSize(width: self.view.bounds.width * scrollView.zoomScale, height: self.view.bounds.height * scrollView.zoomScale)
    YOUR_IMAGEVIEW.center = CGPoint(x: scrollView.contentSize.width * 0.5 + offsetX, y: scrollView.contentSize.height * 0.5 + offsetY)

}

As apple said, putting your imageView in viewForZooming is enough, but It doesn't work. So I added above codes in scrollViewDidZoom and it just works as it is supposed to be.

like image 42
Munkhsoyol Ganbat Avatar answered Oct 10 '22 03:10

Munkhsoyol Ganbat