使用SwiftUI将视图转换为AppKit中的NSImage

9

SwiftUI 2.0 | Swift 5.4 | Xcode 12.4 | macOS Big Sur 11.4

iOS中有一种方法可以将SwiftUI视图渲染为UIImage,但在AppKit中不起作用,只能在UIKit中使用:

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

有没有解决方法可以在AppKit上运行? 方法UIGraphicsImageRenderer(size:) 在AppKit上无法工作,也没有相应的方法。


点赞。我非常期待这个问题的答案。 - alobaili
1个回答

1
如果我正确理解了你的问题,你应该可以使用NSBitmapImageRef来实现!以下是一个从SwiftUI视图生成NSImage的简单示例(注意:您的宿主视图必须可见!):

let view = MyView() // some SwiftUI view
let host = NSHostingView(rootView: view)

// Note: the host must be visible on screen, which I am guessing you already have it that way. If not, do that here.

let bitmapRep = host.bitmapImageRepForCachingDisplay(in: host.bounds)
host.cacheDisplay(in: host.bounds, to: bitmapRep!)

let image = NSImage(size: host.frame.size)
image.addRepresentation(bitmapRep!)

这里有一个扩展程序适用于NSHostingView,可以安全地进行快照操作:
extension NSHostingView {
    func snapshot() -> NSImage? {
        // Make sure the view is visible:
        guard self.window != nil else { return nil }

        // Get bitmap data:
        let bitmapRep = self.bitmapImageRepForCachingDisplay(in:
        self.bounds)
        self.cacheDisplay(in: self.bounds, to: bitmapRep!)

        // Create NSImage from NSBitmapImageRep:
        let image = NSImage(size: self.frame.size)
        image.addRepresentation(bitmapRep!)
        
        return image
    }
}

我希望这可以帮到您。如果您有任何问题,请告诉我!


这是我实现的方式,但输出不是矢量化的,所以文本看起来模糊 :/ - AlbertUI
1
嘿!所以你可以使用NSImage(data: host.dataWithPDF(inside: host.bounds)),其中host是一个NSHostingView,以获取矢量数据。请记住,这并不适用于所有情况!在我的非常基本的测试中,文本被传递了,但系统符号没有被传递。 - Quinn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接