如何截取 SCNScene 或 SceneView 的屏幕截图?

问题描述 投票:0回答:1

目标: 截取

SceneView

中显示的 .usdz 文件的屏幕截图

问题: 空/空白屏幕截图图像

完整上下文: 我已经被这个问题困扰了几天,已经尝试了我能找到的所有解决方案,也尝试设计自己的解决方案,但到目前为止没有任何效果。我的目标很简单:截取 SwiftUI 项目中显示的 .usdz 文件的屏幕截图。我正在

SCNScene
中加载 .usdz 文件,并在
SceneView
中显示该场景,当我尝试直接或通过其任何分层容器截取该
SCNScene
的屏幕截图时,屏幕截图最终为空/空白。而用于截取屏幕截图的相同代码适用于应用程序中的任何其他视图。

这是我清理的文件代码,使其与问题相关:

import SwiftUI
import SceneKit

struct USDZModelView: View {
    
    @State private var scene: SCNScene?
    @State var takeSnapshot: Bool = false
    @State var savedImage: UIImage?
    
    init(url: URL) {
        do {
            self._scene = State(initialValue: try SCNScene(url: url, options: nil))
            self.scene?.background.contents = UIColor.gray
        } catch {
            
        }
    }
    
    var body: some View {
        NavigationStack {
            let myView = VStack {
                if let scene = scene {
                    SceneView(
                        scene: scene,
                        options: [.allowsCameraControl, .autoenablesDefaultLighting]
                    )
                } else {
                    
                }
                
                Button("Take SS") {
                    takeSnapshot = true
                }
            }
            myView
                .onChange(of: takeSnapshot) {
                    let img = myView.snapshot()
                    savedImage = img
                    // View the image however, upload on firestore and view, show in another view via state variable etc etc to view the image, all show the same result
                    // Firestore upload manager code was here - removed it for the question
                }
            
            if let img = savedImage {
                Image(uiImage: img)
                    .border(Color.red)
                    .background(.purple)
            }
        }
        .navigationBarBackButtonHidden(true)
    }
}

extension View {
    func snapshot() -> UIImage {
        let controller = UIHostingController(rootView: self)
        let view = controller.view
        
        let targetSize = controller.view.intrinsicContentSize
        view?.bounds = CGRect(origin: .zero, size: targetSize)
        view?.backgroundColor = .clear
        
        let renderer = UIGraphicsImageRenderer(size: targetSize)
        
        return renderer.image { _ in
            view?.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
        }
    }
}

USDZModelView
通过
.fullScreenCover

从之前的另一个视图显示

这里是我在互联网上找到的示例 .usdz 文件的链接,如果有人有兴趣尝试使用 .usdz 文件的代码以找到解决方案。

swiftui screenshot scenekit scnscene sceneview
1个回答
0
投票

我通过在 Swift/UIKit 中实现相同的功能解决了我的问题。 UIKit 中的

SCNView
有一个内置的快照功能,可以完美运行。在
UIViewController
中实现了此功能,并将其集成到我的 SwiftUI 应用程序中。

© www.soinside.com 2019 - 2024. All rights reserved.