问题描述
我正在尝试绘制一个 CALayer 的图像,该图像包含位于特定点的多个子图层,但目前当我使用 CALayer.render(在 ctx: 中)时,它不符合子图层的 zPosition。它在屏幕上运行良好,但在呈现为 PDF 时,它似乎按照创建顺序呈现它们。
在绘图层上定位(x,y,角度)的这些子层。
一种解决方案似乎是覆盖绘图层上的 render(in ctx:) 方法,这似乎有效,只是子层的渲染位置不正确。它们都在左下角 (0,0) 并且没有正确旋转。
override func render(in ctx: CGContext) {
if let layers:[CALayer] = self.sublayers {
let orderedLayers = layers.sorted(by: {
$0.zPosition < $1.zPosition
})
for v in orderedLayers {
v.render(in: ctx)
}
}
}
如果我不覆盖此方法,则它们将正确定位,但只是在错误的 zPosition 中 - 即应该在底部 (zPosition-0) 的那些在顶部。
我在这里错过了什么?似乎我需要在 render(incts:) 函数中以某种方式正确定位子层?
我该怎么做?这些子图层已经定位在屏幕上,我要做的就是生成绘图的图像。这是使用以下函数完成的。
func createPdfData()->Data?{
DebugLog("")
let scale: CGFloat = 1
let mWidth = drawingLayer.frame.width * scale
let mHeight = drawingLayer.frame.height * scale
var cgRect = CGRect(x: 0,y: 0,width: mWidth,height: mHeight)
let documentInfo = [kCGPDFContextCreator as String:"MakeSpace(www.xxxx.com)",kCGPDFContextTitle as String:"Layout Image",kCGPDFContextAuthor as String:GlobalVars.shared.appUser?.username ?? "",kCGPDFContextSubject as String:self.level?.imageCode ?? "",kCGPDFContextKeywords as String:"XXXX,Layout"]
let data = NSMutableData()
guard let pdfData = CGDataConsumer(data: data),let ctx = CGContext.init(consumer: pdfData,mediaBox: &cgRect,documentInfo as CFDictionary) else {
return nil}
ctx.beginpdfpage(nil)
ctx.saveGState()
ctx.scaleBy(x: scale,y: scale)
self.drawingLayer.render(in: ctx)
ctx.restoreGState()
ctx.endpdfpage()
ctx.closePDF()
return data as Data
}
解决方法
这就是我最终做的 - 它似乎有效。
ZOrderDrawingLayer 类:CALayer {
override func render(in ctx: CGContext) {
if let layers:[CALayer] = self.sublayers {
let orderedLayers = layers.sorted(by: {
$0.zPosition < $1.zPosition
})
for v in orderedLayers {
ctx.saveGState()
// Translate and rotate the context using the sublayers
// size,position and transform (angle)
let w = v.bounds.width/2
let ww = w*w
let h = v.bounds.height/2
let hh = h*h
let c = sqrt(ww + hh)
let theta = asin(h/c)
let angle = atan2(v.transform.m12,v.transform.m11)
let x = c * cos(theta+angle)
let y = c * sin(theta+angle)
ctx.translateBy(x: v.position.x-x,y: v.position.y-y)
ctx.rotate(by: angle)
v.render(in: ctx)
ctx.restoreGState()
}
}
}
}