我正在使用 UIBezierPath 在视图上徒手绘制注释。我想将它保存在 SQLite 中,以便在用户打开该视图时在该视图上绘制。有没有办法在 SQLite 中保存 UIBezierPath,这样我就可以随时使用它来绘制视图。
您可以将其序列化为数据(以 NSData 实例的形式),因为 UIBezierPath 符合 NSCoding (即
NSData * data = [NSData archivedDataWithRootObject:yourPath]
另一种选择可能是与 SVG 相互转换并保存。
您可以保存
UIBezierPath
的所有控制点,而不是直接保存路径。
您可以通过定义路径模型并使用 Codable 来序列化/反序列化
UIBezierPath
。虽然将 lineWidth
或 lineCapStyle
等属性设置为 Codable
很简单,但路径元素的代码(存储在 UIBezierPath.cgPath
中)则更为复杂。然而,这是一个起点:
enum PathElement: Codable, Equatable {
case moveToPoint(CGPoint)
case addLineToPoint(CGPoint)
case addQuadCurveToPoint(controlPoint: CGPoint, endPoint: CGPoint)
case addCurveToPoint(controlPoint1: CGPoint, controlPoint2: CGPoint, endPoint: CGPoint)
case closeSubpath
}
extension CGPath {
static func pathFromPathElements(_ pathElements: [PathElement]) -> CGPath {
let path = CGMutablePath()
for pathElement in pathElements {
switch pathElement {
case .moveToPoint(let point):
path.move(to: point)
case .addLineToPoint(let point):
path.addLine(to: point)
case .addQuadCurveToPoint(let controlPoint, let endPoint):
path.addQuadCurve(to: endPoint, control: controlPoint)
case .addCurveToPoint(let controlPoint1, let controlPoint2, let endPoint):
path.addCurve(to: endPoint, control1: controlPoint1, control2: controlPoint2)
case .closeSubpath:
path.closeSubpath()
}
}
return path
}
func pathElements() -> [PathElement] {
var result = [PathElement]()
applyWithBlock { elementPointer in
let element = elementPointer.pointee
switch element.type {
case .moveToPoint:
let points = Array(UnsafeBufferPointer(start: element.points, count: 1))
let el = PathElement.moveToPoint(points[0])
result.append(el)
case .addLineToPoint:
let points = Array(UnsafeBufferPointer(start: element.points, count: 1))
let el = PathElement.addLineToPoint(points[0])
result.append(el)
case .addQuadCurveToPoint:
let points = Array(UnsafeBufferPointer(start: element.points, count: 2))
let el = PathElement.addQuadCurveToPoint(
controlPoint: points[0], endPoint: points[1])
result.append(el)
case .addCurveToPoint:
let points = Array(UnsafeBufferPointer(start: element.points, count: 3))
let el = PathElement.addCurveToPoint(
controlPoint1: points[0], controlPoint2: points[1], endPoint: points[2])
result.append(el)
case .closeSubpath:
result.append(.closeSubpath)
@unknown default:
fatalError()
}
}
return result
}
}