如何将视图(不是 UIView)转换为图像? [英] How to convert a View (not UIView) to an image?

查看:22
本文介绍了如何将视图(不是 UIView)转换为图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

类似于此线程:

这是代码(在 iPhone Xr 模拟器上测试,Xcode 11 beta 4):

import SwiftUI扩展 UIView {func asImage(rect: CGRect) ->用户界面{让渲染器 = UIGraphicsImageRenderer(bounds: rect)返回 renderer.image { rendererContext inlayer.render(在:rendererContext.cgContext)}}}结构内容视图:查看{@State 私有变量 rect1:CGRect = .zero@State 私有变量 rect2:CGRect = .zero@State 私有变量 uiimage: UIImage?= 零var主体:一些视图{虚拟堆栈{堆栈{虚拟堆栈{文本(左")文本(视图")}.padding(20).background(颜色.绿色).border(颜色.蓝色,宽度:5).background(RectGetter(rect: $rect1)).onTapGesture { self.uiimage = UIApplication.shared.windows[0].rootViewController?.view.asImage(rect: self.rect1) }虚拟堆栈{文本(右")文本(视图")}.填充(40).background(颜色.黄色).border(颜色.绿色,宽度:5).background(RectGetter(rect: $rect2)).onTapGesture { self.uiimage = UIApplication.shared.windows[0].rootViewController?.view.asImage(rect: self.rect2) }}如果 uiimage != nil {虚拟堆栈{文本(捕获的图像")图像(uiImage: self.uiimage!).padding(20).border(Color.black)}.padding(20)}}}}struct RectGetter:查看{@Binding var rect:CGRectvar主体:一些视图{GeometryReader { 代理输入self.createView(代理:代理)}}func createView(proxy: GeometryProxy) ->一些视图{DispatchQueue.main.async {self.rect = proxy.frame(in: .global)}返回矩形().填充(颜色.清除)}}

Similar to this thread: How to convert a UIView to an image.

I would like to convert a SwiftUI View rather than a UIView to an image.

解决方案

Although SwiftUI does not provide a direct method to convert a view into an image, you still can do it. It is a little bit of a hack, but it works just fine.

In the example below, the code captures the image of two VStacks whenever they are tapped. Their contents are converted into a UIImage (that you can later save to a file if you need). In this case, I am just displaying it below.

Note that the code can be improved, but it provides the basics to get you started. I use GeometryReader to get the coordinates of the VStack to capture, but it could be improved with Preferences to make it more robust. Check the links provided, if you need to learn more about it.

Also, in order to convert an area of the screen to an image, we do need a UIView. The code uses UIApplication.shared.windows[0].rootViewController.view to get the top view, but depending on your scenario you may need to get it from somewhere else.

Good luck!

And this is the code (tested on iPhone Xr simulator, Xcode 11 beta 4):

import SwiftUI

extension UIView {
    func asImage(rect: CGRect) -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: rect)
        return renderer.image { rendererContext in
            layer.render(in: rendererContext.cgContext)
        }
    }
}

struct ContentView: View {
    @State private var rect1: CGRect = .zero
    @State private var rect2: CGRect = .zero
    @State private var uiimage: UIImage? = nil

    var body: some View {
        VStack {
            HStack {
                VStack {
                    Text("LEFT")
                    Text("VIEW")
                }
                .padding(20)
                .background(Color.green)
                .border(Color.blue, width: 5)
                .background(RectGetter(rect: $rect1))
                .onTapGesture { self.uiimage = UIApplication.shared.windows[0].rootViewController?.view.asImage(rect: self.rect1) }

                VStack {
                    Text("RIGHT")
                    Text("VIEW")
                }
                .padding(40)
                .background(Color.yellow)
                .border(Color.green, width: 5)
                .background(RectGetter(rect: $rect2))
                .onTapGesture { self.uiimage = UIApplication.shared.windows[0].rootViewController?.view.asImage(rect: self.rect2) }

            }

            if uiimage != nil {
                VStack {
                    Text("Captured Image")
                    Image(uiImage: self.uiimage!).padding(20).border(Color.black)
                }.padding(20)
            }

        }

    }
}

struct RectGetter: View {
    @Binding var rect: CGRect

    var body: some View {
        GeometryReader { proxy in
            self.createView(proxy: proxy)
        }
    }

    func createView(proxy: GeometryProxy) -> some View {
        DispatchQueue.main.async {
            self.rect = proxy.frame(in: .global)
        }

        return Rectangle().fill(Color.clear)
    }
}

这篇关于如何将视图(不是 UIView)转换为图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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