部分切断了SwiftUI视图的快照 [英] Snapshot of SwiftUI view is partially cut off

查看:28
本文介绍了部分切断了SwiftUI视图的快照的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用HWS: How to convert a SwiftUI view to an image中的代码从SwiftUI视图(快照)创建UIImage

我得到以下结果,很明显是不正确的,因为图片被截断了。

编码:

struct ContentView: View {
    @State private var savedImage: UIImage?

    var textView: some View {
        Text("Hello, SwiftUI")
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .clipShape(Capsule())
    }

    var body: some View {
        ZStack {
            VStack(spacing: 100) {
                textView

                Button("Save to image") {
                    savedImage = textView.snapshot()
                }
            }

            if let savedImage = savedImage {
                Image(uiImage: savedImage)
                    .border(Color.red)
            }
        }
    }
}
extension View {
    func snapshot() -> UIImage {
        let controller = UIHostingController(rootView: self)
        let view = controller.view

        let targetSize = controller.view.intrinsicContentSize
        view?.bounds = CGRect(origin: .zero, size: targetSize)
        view?.backgroundColor = .clear

        let renderer = UIGraphicsImageRenderer(size: targetSize)

        return renderer.image { _ in
            view?.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
        }
    }
}

看起来快照的原始视图比应有的位置低,但我不确定。我如何修复此问题?


编辑

我们发现这个问题并不发生在iOS 14上,而只发生在iOS 15上。所以问题是.如何针对iOS 15修复此问题?

推荐答案

我最近也注意到了这个问题。我在不同的模拟器(例如,iPhone8和iPhone13Pro)上进行了测试,发现偏移量似乎总是状态栏高度的一半。因此,我怀疑当您在内部调用drawHierarchy(in:afterScreenUpdates:)时,SwiftUI总是将安全区域插入考虑在内。

因此,我使用edgesIgnoringSafeArea(_:)视图修饰符修改了View扩展中的snapshot()函数,它起作用了:

extension View {
    func snapshot() -> UIImage {
        let controller = UIHostingController(rootView: self.edgesIgnoringSafeArea(.all))
        let view = controller.view

        let targetSize = controller.view.intrinsicContentSize
        view?.bounds = CGRect(origin: .zero, size: targetSize)
        view?.backgroundColor = .clear

        let renderer = UIGraphicsImageRenderer(size: targetSize)

        return renderer.image { _ in
            view?.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
        }
    }
}

这篇关于部分切断了SwiftUI视图的快照的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆