我知道您可以按照
这些步骤将 iOS SwiftUI
View
转换为图像,但这在 SwiftUI 扩展中使用了 UIKit 东西,而您不能在 SwiftUI for macOS 中使用它。
有人知道如何对 macOS SwiftUI 视图进行快照/截图吗?
在 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
}
}
使用 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
}
}
}
}