Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save a CoreGraphics Drawing in Swift

I want to make an application where the user can draw on the screen and then save their drawings. Below is my UIView draw code:

import UIKit

class DrawView: UIView {


    var lines: [Line] = [] // Line is a custom class, shown below
    var lastPoint: CGPoint!

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        lastPoint = touches.anyObject()?.locationInView(self)
    }

    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
        var newPoint = touches.anyObject()?.locationInView(self)
        lines.append(Line(start: lastPoint, end: newPoint!))
        lastPoint = newPoint
        self.setNeedsDisplay()
    }

    override func drawRect(rect: CGRect) {
        var context = UIGraphicsGetCurrentContext()
        CGContextBeginPath(context)
        CGContextSetLineCap(context, kCGLineCapRound)
        for line in lines {
            CGContextMoveToPoint(context, line.start.x, line.start.y)
            CGContextAddLineToPoint(context, line.end.x, line.end.y)
        }
        CGContextSetRGBStrokeColor(context, 0, 0, 0, 1)

        CGContextSetLineWidth(context, 5)
        CGContextStrokePath(context)
    }
}

Code for Line class:

import UIKit

class Line {

    var start: CGPoint
    var end: CGPoint

    init(start _start: CGPoint, end _end: CGPoint ) {
        start = _start
        end = _end

    }
}

Now I want to be able to save this drawing using NSUserDefaults. How would I do this?

like image 834
brimstone Avatar asked Feb 13 '15 15:02

brimstone


1 Answers

To capture a view, you can use UIGraphicsImageRenderer and drawHierarchy:

let image = UIGraphicsImageRenderer(bounds: view.bounds).image { _ in
    view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
}

To save it in UserDefaults, you could:

if let data = image.pngData() {
    UserDefaults.standard.set(data, forKey: "snapshot")
}

To retrieve it from UserDefaults, you could:

if let data = UserDefaults.standard.data(forKey: "snapshot"), let image = UIImage(data: data) {
    ...
}

Personally, I wouldn't be inclined to store images in UserDefaults. I'd save it to persistent storage. For example, to save it into the Application Support folder you could:

do {
    let fileURL = try FileManager.default
        .url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        .appendingPathComponent("test.png")

    try data.write(to: fileURL, options: .atomicWrite)
} catch {
    print(error)
}
like image 104
Rob Avatar answered Sep 30 '22 12:09

Rob