Search code examples
swiftmacosswiftuiscreenshotnsimage

How can you turn a macOS SwiftUI view into an Image?


I know that you can turn an iOS SwiftUI View into an image by following these steps, but this uses UIKit things in the SwiftUI extension which you cannot use in SwiftUI for macOS.

Does anyone know how to snapshot/screenshot a macOS SwiftUI View?


Solution

  • In macOS same approach can be used. NSHostingController is analog of UIHostingController. Also to get it drawn the view should be added to some window:

    extension View {
        func snapshot() -> NSImage? {
            let controller = NSHostingController(rootView: self)
            let targetSize = controller.view.intrinsicContentSize
            let contentRect = NSRect(origin: .zero, size: targetSize)
            
            let window = NSWindow(
                contentRect: contentRect,
                styleMask: [.borderless],
                backing: .buffered,
                defer: false
            )
            window.contentView = controller.view
            
            guard
                let bitmapRep = controller.view.bitmapImageRepForCachingDisplay(in: contentRect)
            else { return nil }
            
            controller.view.cacheDisplay(in: contentRect, to: bitmapRep)
            let image = NSImage(size: bitmapRep.size)
            image.addRepresentation(bitmapRep)
            return image
        }
    }