如何在 Swift 中保存 CoreGraphics 绘图
How to save a CoreGraphics Drawing in Swift
我想制作一个用户可以在屏幕上绘图然后保存绘图的应用程序。下面是我的 UIView
绘制代码:
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)
}
}
第 class 行代码:
import UIKit
class Line {
var start: CGPoint
var end: CGPoint
init(start _start: CGPoint, end _end: CGPoint ) {
start = _start
end = _end
}
}
现在我希望能够使用 NSUserDefaults
保存此绘图。我该怎么做?
要捕获视图,您可以使用 UIGraphicsImageRenderer
和 drawHierarchy
:
let image = UIGraphicsImageRenderer(bounds: view.bounds).image { _ in
view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
}
要将其保存在 UserDefaults
中,您可以:
if let data = image.pngData() {
UserDefaults.standard.set(data, forKey: "snapshot")
}
要从 UserDefaults
检索它,您可以:
if let data = UserDefaults.standard.data(forKey: "snapshot"), let image = UIImage(data: data) {
...
}
就我个人而言,我不倾向于将图像存储在 UserDefaults
中。我会把它保存到持久存储中。例如,要将其保存到 Application Support 文件夹中,您可以:
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)
}
//I would recomend you to save line on touches end
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
save()
}
func save() {
var data : NSMutableData=NSMutableData()
var archiver=NSKeyedArchiver(forWritingWithMutableData: data)
archiver.encodeObject(lines, forKey:"classLine")
archiver.finishEncoding()
NSUserDefaults.standardUserDefaults().setObject(data, forKey: "shape")
}
class func loadSaved() {
if let data = NSUserDefaults.standardUserDefaults().objectForKey("shape") as? NSData {
var unarchiver :NSKeyedUnarchiver = NSKeyedUnarchiver(forReadingWithData: data);
var line : Line = unarchiver.decodeObjectForKey("classLine") as Line!
}
}
}
class Line : NSObject {
var start: CGPoint
var end: CGPoint
init(start _start: CGPoint, end _end: CGPoint ) {
start = _start
end = _end
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeCGPoint(start, forKey: "start")
aCoder.encodeCGPoint(end, forKey: "end")
}
required init(coder aDecoder: NSCoder) {
start = aDecoder.decodeCGPointForKey("start")
end = aDecoder.decodeCGPointForKey("end")
}
}
我想制作一个用户可以在屏幕上绘图然后保存绘图的应用程序。下面是我的 UIView
绘制代码:
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)
}
}
第 class 行代码:
import UIKit
class Line {
var start: CGPoint
var end: CGPoint
init(start _start: CGPoint, end _end: CGPoint ) {
start = _start
end = _end
}
}
现在我希望能够使用 NSUserDefaults
保存此绘图。我该怎么做?
要捕获视图,您可以使用 UIGraphicsImageRenderer
和 drawHierarchy
:
let image = UIGraphicsImageRenderer(bounds: view.bounds).image { _ in
view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
}
要将其保存在 UserDefaults
中,您可以:
if let data = image.pngData() {
UserDefaults.standard.set(data, forKey: "snapshot")
}
要从 UserDefaults
检索它,您可以:
if let data = UserDefaults.standard.data(forKey: "snapshot"), let image = UIImage(data: data) {
...
}
就我个人而言,我不倾向于将图像存储在 UserDefaults
中。我会把它保存到持久存储中。例如,要将其保存到 Application Support 文件夹中,您可以:
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)
}
//I would recomend you to save line on touches end
override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
save()
}
func save() {
var data : NSMutableData=NSMutableData()
var archiver=NSKeyedArchiver(forWritingWithMutableData: data)
archiver.encodeObject(lines, forKey:"classLine")
archiver.finishEncoding()
NSUserDefaults.standardUserDefaults().setObject(data, forKey: "shape")
}
class func loadSaved() {
if let data = NSUserDefaults.standardUserDefaults().objectForKey("shape") as? NSData {
var unarchiver :NSKeyedUnarchiver = NSKeyedUnarchiver(forReadingWithData: data);
var line : Line = unarchiver.decodeObjectForKey("classLine") as Line!
}
}
}
class Line : NSObject {
var start: CGPoint
var end: CGPoint
init(start _start: CGPoint, end _end: CGPoint ) {
start = _start
end = _end
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeCGPoint(start, forKey: "start")
aCoder.encodeCGPoint(end, forKey: "end")
}
required init(coder aDecoder: NSCoder) {
start = aDecoder.decodeCGPointForKey("start")
end = aDecoder.decodeCGPointForKey("end")
}
}