在 SwiftUI 项目中将视图渲染为图像

Rendering a View as an image in SwiftUI project

我目前正在处理一个涉及 ClockKit 复杂功能的端到端 SwiftUI 项目。由于并发症的模板之一需要图像(UI图像),我需要将现有的 SwiftUI 视图渲染(快照)为图像。我找到了解决这个问题的几个可能的方法,包括以下视图扩展:

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)
        }
    }
}

我遇到的问题是,无论我在哪里实施此扩展,我都会不断收到“不在范围内”Xcode 错误(“无法在范围内找到 'UIHostingController'”、“无法在范围内找到 'UIGraphicsImageRenderer'”,“无法推断参考成员 'clear'”的上下文基础“”。

SwiftUI 和 UIKit 是在这些 Swift 文件中导入的(但我认为后者应该不是必需的)。 Xcode12.5.

请分享一些可以帮助克服这个障碍的技巧...我是一个相当缺乏经验的开发人员,我可能会遗漏一些相当明显的东西,但在这一点上我正在努力。每当我实施一个恰好在其他问题或网站中的合理解决方案时,它总是会出现 UI套件特定命令不在范围内。

编辑:结果证明只有在 iOS 目标的主 ContentView 中实现此扩展才有效。如果放在任何其他目录中则不起作用。但是,我需要此扩展才能在 (watchOS) 扩展文件的文件中工作(正如我所说,CK Complication 需要它)并且无法为 (watchOS) 扩展设置主要 iOS ContentView 的目标成员资格,因为那么两个 ContentView 将应用于一个 watchOS 版本并发生错误。那么如何有效地放置上面的扩展代码,以便它可以应用到需要的地方?

弹出错误的问题(例如 无法在范围内找到 UIHostingController 等)是因为 UIHostingControllerUIGraphicsImageRenderer 在 watchOS 上不可用,这意味着扩展,如所写,将不会在该平台上编译。

参考