如何将 macOS SwiftUI 视图转换为图像?

问题描述 投票:0回答:2

我知道您可以按照

这些
步骤将 iOS SwiftUI View 转换为图像,但这在 SwiftUI 扩展中使用了 UIKit 东西,而您不能在 SwiftUI for macOS 中使用它。

有人知道如何对 macOS SwiftUI 视图进行快照/截图吗?

swift macos swiftui screenshot nsimage
2个回答
6
投票

在 macOS 中可以使用相同的方法。

NSHostingController
UIHostingController
的模拟。同样要绘制视图,应将视图添加到某个窗口:

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

0
投票

使用 SwiftUI 的原生 ImageRenderer 对象将 macOS 视图光栅化为 NSImage。

代码如下:

import SwiftUI

@MainActor final class BitmapImage : ObservableObject {
    
    @Published var images: [String: NSImage] = [:]

    init() {
        let view = SampleView()
        let renderer = ImageRenderer(content: view)
        
        #if os(macOS)
            renderer.scale = NSApplication.shared
                                          .mainWindow?
                                          .backingScaleFactor ?? 2.0
        
            if let nsImage = renderer.nsImage {
                images["1"] = nsImage
            }
        #endif
    }
}

struct SampleView : View {
    var body: some View {
        ZStack {
            Image("picture")
            VStack {
                Divider()
                Text("Lorem ipsum dolor sit amet")
                    .foregroundColor(.white)
                    .font(.custom("", size: 72))
                Spacer()
            }
        }
    }
}

@available(macOS 13.0, *) struct ContentView : View {
    
    @StateObject private var bitmapImage = BitmapImage()
    
    var body: some View {
        ZStack {
            if let nsImage = bitmapImage.images["1"] {
                Image(nsImage: nsImage)
                    .resizable()
                    .frame(width: 500)      // "Squeezed" Image test
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.