How can I create a SwiftUI View
extension to return a NSImage
? I have seen how it can be done on iOS using UIGraphicsImageRenderer
but it seems there is no macOS equivalent.
CodePudding user response:
View Image.swift
import SwiftUI
extension View {
func renderAsImage() -> NSImage? {
let view = NoInsetHostingView(rootView: self)
view.setFrameSize(view.fittingSize)
return view.bitmapImage()
}
}
NoInsetHostingView.swift
import SwiftUI
class NoInsetHostingView<V>: NSHostingView<V> where V: View {
override var safeAreaInsets: NSEdgeInsets {
return .init()
}
}
NSView Image.swift
public extension NSView {
func bitmapImage() -> NSImage? {
guard let rep = bitmapImageRepForCachingDisplay(in: bounds) else {
return nil
}
cacheDisplay(in: bounds, to: rep)
guard let cgImage = rep.cgImage else {
return nil
}
return NSImage(cgImage: cgImage, size: bounds.size)
}
}
I'm not sure exactly why NoInsetHostingView
is needed, but with just a normal NSHostingView
the image has undesired insets, and this fixes it.