截图不需要';在SwiftUI中使用@State时无法工作

截图不需要';在SwiftUI中使用@State时无法工作,swift,swiftui,Swift,Swiftui,我正在尝试使用CGRect拍摄所选区域的屏幕截图。如果我不使用@State变量,它可以正常工作。但我也需要使用@State变量。 这是我的密码 struct ScreenShotTest: View { @State var abc = 0 //Works well if I remove the line var body: some View { Button(action: { let image = self.takeScree

我正在尝试使用CGRect拍摄所选区域的屏幕截图。如果我不使用@State变量,它可以正常工作。但我也需要使用@State变量。 这是我的密码

struct ScreenShotTest: View {

    @State var abc = 0 //Works well if I remove the line

    var body: some View {
        Button(action: {
            let image = self.takeScreenshot(theRect: CGRect(x: 0, y: 0, width: 200, height: 100))
            print(image)
        }) {
            Text("Take Screenshot")
                .padding(.all, 10)
                .background(Color.blue)
                .foregroundColor(.white)
        }
    }
}


extension UIView {
    var renderedImage: UIImage {
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, UIScreen.main.scale)
        let context: CGContext = UIGraphicsGetCurrentContext()!
        self.layer.render(in: context)
        let capturedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return capturedImage
    }
}

extension View {
        func takeScreenshot(theRect: CGRect) -> UIImage {
        let window = UIWindow(frame: theRect)
        let hosting = UIHostingController(rootView: self)
        hosting.view.frame = window.frame
        window.addSubview(hosting.view)
        window.makeKeyAndVisible()
        return hosting.view.renderedImage
    }
}

我也遇到了这个问题,但是有一个EnvironmentObject。我通过在外部视图中声明EnvironmentObject并将其作为普通变量传递给内部视图解决了这个问题,而内部视图在我使用它时崩溃了。这是从我的真实代码中删减下来的,但它应该传达出这个想法

struct Sample: View {
    @State private var isSharePresented: Bool = false
    @EnvironmentObject var model: Model
    static var screenshot: UIImage?
    
    var body: some View {
        GeometryReader { geometry in
            // Hack to get a black background.
            ZStack {
                Spacer()
                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                    .background(Color.black)
                    .edgesIgnoringSafeArea(.all)
                VStack {
                    CompletionContent(model: Model.theModel)
                    Spacer()
                    Button(action: {
                        model.advanceToNext()
                    }) {
                        Text("Continue", comment: "Dismiss this view")
                            .font(.headline)
                            .foregroundColor(.init(UIColor.link))
                    }
                    HStack {
                        Spacer()
                        Button(action: {
                            Sample.screenshot = self.takeScreenshot(theRect: (geometry.frame(in: .global)))
                            self.isSharePresented = true
                        }) {
                            VStack {
                                Image("blank")
                                Image(systemName: "square.and.arrow.up")
                                    .resizable()
                                    .frame(width: 20, height: 30)
                            }
                        }
                    }
                    Spacer()
                }
            }
        }
        .sheet(isPresented: $isSharePresented, onDismiss: {
            print("Dismiss")
        }, content: {
            ActivityViewController(screenshot: Sample.screenshot!)
        })
    }
}

struct SampleContent : View {
    var model: Model
    
    var body: some View {
        Text("Content that uses the model variable goes here")
    }
}

extension UIView {
    var renderedImage: UIImage {
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, UIScreen.main.scale)
        let context: CGContext = UIGraphicsGetCurrentContext()!
        self.layer.render(in: context)
        let capturedImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return capturedImage
    }
}

extension View {
    func takeScreenshot(theRect: CGRect) -> UIImage {
        let window = UIWindow(frame: theRect)
        let hosting = UIHostingController(rootView: self)
        hosting.view.frame = window.frame
        window.addSubview(hosting.view)
        
        window.makeKeyAndVisible()
        return hosting.view.renderedImage
    }
}

struct ActivityViewController: UIViewControllerRepresentable {
    var screenshot: UIImage
    var applicationActivities: [UIActivity]? = nil
    
    func makeUIViewController(
        context: UIViewControllerRepresentableContext<ActivityViewController>)
    -> UIActivityViewController {
        let controller = UIActivityViewController(
            activityItems: [screenshot], applicationActivities: applicationActivities)
        return controller
    }
    
    func updateUIViewController(_ uiViewController: UIActivityViewController, context: UIViewControllerRepresentableContext<ActivityViewController>) {
    }
}
struct示例:视图{
@国家私有变量isSharePresented:Bool=false
@环境对象变量模型:模型
静态var屏幕截图:UIImage?
var body:一些观点{
GeometryReader{中的几何体
//黑背景。
ZStack{
垫片()
.frame(最小宽度:0,最大宽度:。无穷大,最小高度:0,最大高度:。无穷大)
.背景(颜色.黑色)
.edgesIgnoringSafeArea(.all)
VStack{
CompletionContent(模型:model.theModel)
垫片()
按钮(操作:{
model.advanceToNext()
}) {
文本(“继续”,注释:“驳回此视图”)
.font(.headline)
.foregroundColor(.init(UIColor.link))
}
HStack{
垫片()
按钮(操作:{
Sample.screenshot=self.takeScreenshot(结果:(geometry.frame(in:.global)))
self.isSharePresented=true
}) {
VStack{
图像(“空白”)
图像(系统名称:“方形和箭头向上”)
.可调整大小()
.框架(宽:20,高:30)
}
}
}
垫片()
}
}
}
.表(显示:$isSharePresented,onDismiss:{
打印(“驳回”)
},内容:{
ActivityViewController(屏幕截图:Sample.screenshot!)
})
}
}
结构示例内容:视图{
var模型:模型
var body:一些观点{
文本(“使用模型变量的内容显示在此处”)
}
}
扩展UIView{
var renderImage:UIImage{
UIGraphicsBeginImageContextWithOptions(self.bounds.size,false,UIScreen.main.scale)
让上下文:CGContext=UIGraphicsGetCurrentContext()!
self.layer.render(在:上下文中)
让CaptureDiImage:UIImage=UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsSendImageContext()
返回捕获图像
}
}
扩展视图{
func take截图(theRect:CGRect)->UIImage{
let window=UIWindow(帧:theRect)
let hosting=UIHostingController(rootView:self)
hosting.view.frame=window.frame
window.addSubview(hosting.view)
window.makeKeyAndVisible()的
返回hosting.view.renderImage
}
}
结构ActivityViewController:UIViewControllerRepresentable{
var屏幕截图:UIImage
var应用活动:[UIActivity]?=nil
func makeUIViewController(
上下文:UIViewControllerRepresentableContext)
->UIActivityViewController{
让控制器=UIActivityViewController(
activityItems:[屏幕截图],应用程序活动:应用程序活动)
返回控制器
}
func updateUIViewController(uViewController:UIActivityViewController,上下文:UIViewControllerRepresentableContext){
}
}