У меня есть иерархия CALayers, которую я устанавливаю в качестве свойства diffuse материала моего SCNNode.Я делаю снимки текущего состояния сцены (в котором есть только один узел), чтобы сохранить его в формате PNG в файл, используя следующий код:
scene.rootNode.addChildNode(node)
node.geometry?.firstMaterial?.diffuse.contents = self.createLayer() // CALayer
// Set transform of node.
let renderTime = CACurrentMediaTime() + 1
let size = CGSize(width: 600, height: 600)
let renderer = SCNRenderer(
device: MTLCreateSystemDefaultDevice(),
options: nil)
let image = self.renderer.snapshot(
atTime: renderTime,
with: size,
antialiasingMode: .multisampling4X)
return image
Часто это работает, что делает узел ожидаемым, ноПримерно в 25-50% случаев любой CATextLayer, который у меня есть в качестве подслоя слоя, возвращенного в self.createLayer()
, не отображает текст.Все остальные слои, кажется, каждый раз воспроизводятся очень хорошо.
Например, изображение, которое должно выглядеть так:
![correct](https://i.stack.imgur.com/vgV3n.png)
В конце пропускается текст "N": ![incorrect](https://i.stack.imgur.com/ZkOkP.png)
Сам слой визуализируется, что я могу подтвердить, изменив цвет фона текстового слоя:
![enter image description here](https://i.stack.imgur.com/4yfIY.png)
Эта проблема возникает только после создания слоев.Если я отправляю код рендеринга асинхронно, даже без добавления какой-либо задержки, все рендеринг выполняется так, как ожидалось:
scene.rootNode.addChildNode(node)
node.geometry?.firstMaterial?.diffuse.contents = self.createLayer() // CALayer
// Set transform of node.
let renderTime = CACurrentMediaTime() + 1
let size = CGSize(width: 600, height: 600)
DispatchQueue.main.async {
let image = self.renderer.snapshot(
atTime: renderTime,
with: size,
antialiasingMode: .multisampling4X)
completion(image)
}
Обходное решение кажется хакерским, и я не верю в его надежность.Кроме того, я бы предпочел не заставлять свои вызывающие сайты вызывать метод асинхронно.
Есть ли свойство или метод в SceneKit или CoreAnimation, которые мне не хватает, которые я могу использовать, чтобы убедиться, что слойполностью отрисован перед попыткой рендерить его на изображение?