【问题标题】:How to save a CoreGraphics Drawing in Swift如何在 Swift 中保存 CoreGraphics 绘图
【发布时间】:2015-04-14 17:15:12
【问题描述】:

我想制作一个用户可以在屏幕上绘图然后保存他们的绘图的应用程序。下面是我的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)
    }
}

Line 类代码:

import UIKit

class Line {

    var start: CGPoint
    var end: CGPoint

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

    }
}

现在我希望能够使用NSUserDefaults 保存此绘图。我该怎么做?

【问题讨论】:

    标签: ios swift uiview save core-graphics


    【解决方案1】:

    要捕获视图,您可以使用UIGraphicsImageRendererdrawHierarchy

    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)
    }
    

    【讨论】:

      【解决方案2】:
          //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")
      
      
       }
      }
      

      【讨论】:

      • 欢迎您,我已经进行了一些更新,如果您遇到任何问题,请尝试让 mw 知道。
      • 感谢@Rob 在 NSKeyedArchiving 之前需要对其进行编码,并且在取消归档之前也需要对其进行解码。我喜欢你的答案保存到 PNG 文件并检索 PNG 文件
      • 好的,默认情况下它不是 NSObject。你说的对。我将编辑我的答案
      猜你喜欢
      • 1970-01-01
      • 2022-10-16
      • 1970-01-01
      • 2011-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-02
      • 1970-01-01
      相关资源
      最近更新 更多