ios - 将 SwiftUI View 渲染为 UIImage

标签 ios xcode render swiftui snapshot

我正在尝试将 SwiftUI View 渲染为 UIImage,然后让用户选择保存到相机胶卷或通过电子邮件发送给其他人。

举个例子,我想将 50 行的列表渲染到 UIImage 中。

struct MyList: View {
    var body: some View {
        List {
            ForEach(0 ..< 50, id:\.self) {
                Text("row \($0)")
            }
        }
    }
}

过去几周在互联网上搜索仍然没有运气。我尝试了两种不同的方法。

<强>1。 UIHostingController (source here)

let hosting = UIHostingController(rootView: Text("TEST"))
hosting.view.frame = // Calculate the content size here //
let snapshot = hosting.view.snapshot        // output: an empty snapshot of the size
print(hosting.view.subviews.count)          // output: 0

我已经尝试过layoutSubviews() , setNeedsLayout() , layoutIfNeeded() , loadView() ,但仍然导致 0 个子浏览。

<强>2。 UIWindow.rootViewController (source here)

var vc = UIApplication.shared.windows[0].rootViewController
vc = vc.visibleController          // loop through the view controller stack to find the top most view controller
let snapshot = vc.view.snapshot    // output: a snapshot of the top most view controller

这几乎产生了我想要的输出。然而,我得到的快照实际上是一个屏幕截图,即带有导航栏、选项卡栏和固定尺寸(与屏幕尺寸相同)。我需要捕获的只是没有这些栏的 View 内容,有时可能比屏幕大(在本例中我的 View 是一个很长的列表)。

尝试查询vc.view.subviews寻找我想要的 TableView ,但返回无用的 [<_TtGC7SwiftUI16PlatformViewHostGVS_42PlatformViewControllerRepresentableAdaptorGVS_16BridgedSplitViewVVS_22_VariadicView_Children7ElementGVS_5GroupGVS_19_ConditionalContentS4_GVS_17_UnaryViewAdaptorVS_9EmptyView______: 0x7fb061cc4770; frame = (0 0; 414 842); anchorPoint = (0, 0); tintColor = UIExtendedSRGBColorSpace 0 0.478431 1 1; layer = <CALayer: 0x600002d8caa0>>] .

非常感谢任何帮助。

最佳答案

这样的东西对你有用吗?

import SwiftUI

extension UIView {
    func takeScreenshot() -> UIImage {
        // Begin context
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, UIScreen.main.scale)
        // Draw view in that context
        drawHierarchy(in: self.bounds, afterScreenUpdates: true)
        // And finally, get image
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        if (image != nil) {
            UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil);
            return image!
        }

        return UIImage()
    }
}

struct ContentView: UIViewRepresentable {
    func makeUIView(context: Context) -> UIView {
        let someView = UIView(frame: UIScreen.main.bounds)
        _ = someView.takeScreenshot()
        return someView
    }

    func updateUIView(_ view: UIView, context: Context) {

    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

关于ios - 将 SwiftUI View 渲染为 UIImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59131976/

相关文章:

iOS 沙盒测试与生产

ios - 无法在 swift 4 iOS 的文档目录中保存正确的 firebase 图像

ios - 如何在 UIAlert 显示时显示键盘 带有自定义文本标签 View 的 UIAlert

objective-c - 如何在 Objective-C 中创建可变参数方法

ios - restoreCompletedTransactions 并要求登录

iphone - 通过单击应用程序中的按钮直接从应用程序发送短信

javascript - 使用javascript渲染 map

ruby-on-rails - RoR : update action. 出错时的渲染路径

graphics - 在终端上将图形渲染为 ASCII 艺术的库?

ios - SKProductRequest 返回 0 作为响应