【问题标题】:SwiftUI View to NSImage in AppKitSwiftUI 视图到 AppKit 中的 NSImage
【发布时间】:2021-04-25 19:35:03
【问题描述】:

SwiftUI 2.0 |斯威夫特 5.4 | Xcode 12.4 | macOS 大苏尔 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 上不起作用,并且没有等效方法。

【问题讨论】:

  • 点赞。我非常期待这个问题的答案。

标签: swift swiftui appkit


【解决方案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
    }
}

我希望这会有所帮助。如果您有任何问题,请告诉我!

【讨论】:

  • 这就是我实现的方式,但输出不是矢量的,所以文本看起来很模糊:/
  • 嘿!所以你可以使用NSImage(data: host.dataWithPDF(inside: host.bounds)),其中hostNSHostingView 来获取矢量数据。请记住,这并不适用于所有事情!在我非常基本的测试中,文本被继承,但不是系统符号。
猜你喜欢
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 2020-01-10
  • 1970-01-01
  • 2020-01-02
  • 1970-01-01
相关资源
最近更新 更多