I have an app using a view model EnvironmentObject. I want to add a Print to PDF ShareLink but the rendered image doesn't have access to the environment object. The code below replicates the problem in shorter form, the run time error being:
Fatal error: No ObservableObject of type Model found. A View.environmentObject(_:) for Model may be missing as an ancestor of this view.
Is there anyway to get the environmentObject into the rendered view? or an alternative way to implement Print to PDF with a viewModel based app?
import SwiftUI
@main
struct ImageRendererWithEnvironmentApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
//
// ContentView.swift
// ImageRendererWithEnvironment
//
// Created by Stuart on 18/03/2023.
//
import SwiftUI
struct ContentView: View {
@EnvironmentObject var model: Model
var myView: some View {
return createMyView(text: "Help me!")
}
var body: some View {
VStack {
myView
ShareLink("Print to PDF", item: render())
}
}
private func createMyView(text: String) -> some View {
VStack {
ZStack {
RoundedRectangle(cornerRadius: 20)
.fill(model.backgroundColor)
.frame(width: 300, height: 200)
VStack {
Image(systemName: "globe")
.imageScale(.large)
Text(text)
}
.foregroundColor(.white)
.padding()
}
}
}
func render() -> URL {
let renderer = ImageRenderer(content: myView)
let url = URL.documentsDirectory.appending(path: "output.pdf")
renderer.render { size, context in
var box = CGRect(x: 0, y:0, width: size.width, height: size.height)
guard let pdf = CGContext(url as CFURL, mediaBox: &box, nil) else {
return
}
pdf.beginPDFPage(nil)
context(pdf)
pdf.endPDFPage()
pdf.closePDF()
}
return url
}
}
class Model: ObservableObject {
// Publish the decision being worked on (will be worked as EnvironmentObject and occasionally saved to CoreData)
@Published var backgroundColor: Color = .red
}