共享SwiftUI视图截图导致崩溃

共享SwiftUI视图截图导致崩溃,swift,swiftui,Swift,Swiftui,我正在抓取SwiftUI视图中的子视图的屏幕截图,以便立即传递到共享表以共享图像 该视图是一组问题的视图,这些问题来自一个文本数组,呈现为一堆卡片。我正在尝试获取问题的屏幕截图,并将其与应用程序的链接一起共享(使用愤怒的小鸟链接进行测试) 我已经能够使用Asperi对以下问题的基本回答捕获屏幕截图: 我的共享页启动了,我可以使用“复制”功能复制图像,所以我知道它实际上得到了一个屏幕截图,但每当我点击“消息”发送给某人,或者如果我只是打开共享页,应用程序就会崩溃 消息说这是一个内存问题,但没有给

我正在抓取SwiftUI视图中的子视图的屏幕截图,以便立即传递到共享表以共享图像

该视图是一组问题的视图,这些问题来自一个文本数组,呈现为一堆卡片。我正在尝试获取问题的屏幕截图,并将其与应用程序的链接一起共享(使用愤怒的小鸟链接进行测试)

我已经能够使用Asperi对以下问题的基本回答捕获屏幕截图:

我的共享页启动了,我可以使用“复制”功能复制图像,所以我知道它实际上得到了一个屏幕截图,但每当我点击“消息”发送给某人,或者如果我只是打开共享页,应用程序就会崩溃

消息说这是一个内存问题,但没有给出太多的问题描述。有没有解决这类问题的好方法?我想这一定是因为在这种情况下截图是如何保存的

以下是我对View和UIView的扩展,用于渲染图像:

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


extension View {
    func asImage() -> UIImage {
        let controller = UIHostingController(rootView: self)
        
        // locate far out of screen
        controller.view.frame = CGRect(x: 0, y: CGFloat(Int.max), width: 1, height: 1)
        UIApplication.shared.windows.first!.rootViewController?.view.addSubview(controller.view)
        
        let size = controller.sizeThatFits(in: UIScreen.main.bounds.size)
        controller.view.bounds = CGRect(origin: .zero, size: size)
        controller.view.sizeToFit()
        controller.view.backgroundColor = .clear
        
        let image = controller.view.asImage()
        controller.view.removeFromSuperview()
        return image
    }
}
这是我的视图的一个缩写版本-按钮大约在中间位置,应该调用底部的私有函数,该函数从视图/UIView扩展中渲染图像,并将“questionScreenShot”变量设置为渲染图像,然后显示在共享表中

struct TopicPage: View {
    var currentTopic: Topic
    @State private var currentQuestions: [String]
    @State private var showShareSheet = false
    @State var questionScreenShot: UIImage? = nil
    
    var body: some View {
        GeometryReader { geometry in
                Button(action: {
                    self.questionScreenShot = render()
                    if self.questionScreenShot != nil {
                        self.showShareSheet = true
                    } else {
                        print("Did not set screenshot")
                    }

                }) {
                    Text("Share Question").bold()
                }
                .sheet(isPresented: $showShareSheet) {
                    ShareSheet(activityItems: [questionScreenShot!])
                }
        }
    }

    
    private func render() -> UIImage {
        QuestionBox(currentQuestion: self.currentQuestions[0]).asImage()
    }
}

我找到了一个解决方案,似乎在这里奏效。我启动变量,在该变量中,questionScreenShot存储为nil,以开始:

    @State var questionScreenShot: UIImage? = nil
然后,我只需确保在视图出现时将其设置为“render”,这意味着它将加载UIImage,因此如果用户单击“Share Question”,它将准备加载(我认为之前存在一个问题,即共享完成后UIImage无法及时加载)

它还会在消失时将该变量设置回零

.onAppear {
                self.currentQuestions = currentTopic.questions.shuffled()
                self.featuredQuestion = currentQuestions.last!
                self.questionScreenShot = render()
            }
            .onDisappear {
                self.questionScreenShot = nil
                self.featuredQuestion = nil
            }

我找到了一个解决方案,似乎在这里奏效。我启动变量,在该变量中,questionScreenShot存储为nil,以开始:

    @State var questionScreenShot: UIImage? = nil
然后,我只需确保在视图出现时将其设置为“render”,这意味着它将加载UIImage,因此如果用户单击“Share Question”,它将准备加载(我认为之前存在一个问题,即共享完成后UIImage无法及时加载)

它还会在消失时将该变量设置回零

.onAppear {
                self.currentQuestions = currentTopic.questions.shuffled()
                self.featuredQuestion = currentQuestions.last!
                self.questionScreenShot = render()
            }
            .onDisappear {
                self.questionScreenShot = nil
                self.featuredQuestion = nil
            }

我正在寻找同样的东西,虽然我只想转换堆栈,而不是整个屏幕。祝你好运。你的情况如何?我认为,如果您将堆栈作为一个单独的视图结构拉出,这个解决方案就会起作用,就像我的示例中“QuestionBox”的设置一样。我重置了我的手机并再次尝试,这个问题实际上得到了解决。所以这个可能有用,还在继续。我一弄明白就会告诉你。祝你好运。嘿@AndiAna你在哪里重新声明错误?想知道你是否有另一个同名函数?我正在寻找同样的东西,虽然我只想转换一个堆栈,而不是整个屏幕。祝你好运。你的情况如何?我认为,如果您将堆栈作为一个单独的视图结构拉出,这个解决方案就会起作用,就像我的示例中“QuestionBox”的设置一样。我重置了我的手机并再次尝试,这个问题实际上得到了解决。所以这个可能有用,还在继续。我一弄明白就会告诉你。祝你好运。嘿@AndiAna你在哪里重新声明错误?想知道您是否有另一个同名函数?