I have an interactive globe built with SceneKit. The globe is a SCNNode and the dots that represent land are also SCNNodes and are children of the globe. I want to add a custom view as the geometry for one of the children of the globe.
I know how to add a node with a spherical geometry and change its color and so on. I'm not sure how to use a custom view (Swift UI) for the geometry of a node.
let lowerCircle = SCNSphere(radius: dotRadius * 5)
lowerCircle.firstMaterial?.diffuse.contents = GenericColor(cgColor: UIColor.white.cgColor)
lowerCircle.firstMaterial?.lightingModel = SCNMaterial.LightingModel.constant
let dotNode = SCNNode(geometry: lowerCircle)
dotNode.name = "NewYorkDot"
dotNode.position = textureMap[i].position
positions.append(dotNode.position)
dotNodes.append(dotNode)
To use a custom SwiftUI view as the geometry for a
SCNNodein SceneKit, you can start with rendering your SwiftUI view into aUIImage. This can be done by creating a snapshot of the view.Once you have the
UIImage, you can apply it as a texture to theSCNMaterialof yourSCNNode.See for instance "Updating
SCNMaterialtexture in SceneKit" from Benoit Layer.Finally, create a geometry (e.g.,
SCNPlane) for yourSCNNode, and apply the material with the custom texture to this geometry.The process would be:
Your SwiftUI View to
UIImagewould be:Then apply the custom geometry:
But: SwiftUI views are rendered into a static image, so they won't be interactive in the SceneKit context.
The warning
=== AttributeGraph: cycle detected through attribute 1517200 ===suggests there is a cyclic dependency or an issue related to the view's layout in SwiftUI. That can happen when the view's state changes in a way that causes SwiftUI to continually recalculate the view's layout, leading to an infinite loop.So try and simplify the SwiftUI view: temporarily replace your SwiftUI view with a very simple view (like a single
Textelement) to confirm if the complexity of your view is causing the issue.And make sure you are not using any view modifiers that might cause cyclic dependencies, such as those that depend on the view's own size or layout. Set an explicit frame size for your SwiftUI view before rendering it to a
UIImage. That can help prevent issues related to size calculations that might lead to a cycle.Make sure all UI-related tasks, including rendering the SwiftUI view to a
UIImage, are performed on the main thread.