Search code examples
swiftuikitswiftuipdfkit

Passing data from UIViewControllerRepresentable to UIViewController


I'm trying to pass data from a SwiftUI struct (a first name and a last name) and can't seem to update the variables in my UIViewController with the data in my UIViewControllerRepresentable.

I've checked and confirmed that the data I'm trying to pass in from my SwiftUI view is correct. What do I need to do/change to update the firstName and lastName variables in my UIViewController?

import UIKit
import PDFKit
import SwiftUI

class PDFPreviewViewController: UIViewController {
    public var documentData: Data?

    var firstName: String = "firstName did not load"
    var lastName: String = "lastName did not load"

    @IBOutlet weak var pdfView: PDFView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let pdfCreator = PDFCreator(firstName: firstName, lastName: lastName, format: "test format")
        documentData = pdfCreator.createReleasePDF()
        if let data = documentData {
            pdfView.document = PDFDocument(data: data)
            pdfView.autoScales = true
        }
    }
}

struct PDFPreviewController: UIViewControllerRepresentable {
    var release: ModelRelease
    let vc = PDFPreviewViewController()

    func makeUIViewController(context: UIViewControllerRepresentableContext<PDFPreviewController>) -> UIViewController {

        let storyboard = UIStoryboard(name: "Preview", bundle: Bundle.main)
        let controller = storyboard.instantiateViewController(identifier: "Preview")

        vc.firstName = release.firstName
        vc.lastName = release.lastName

        return controller
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<PDFPreviewController>) {
    }
}

struct PDFPreviewControllerWrapper: View {
    @Environment(\.presentationMode) var presentationMode

    var release: ModelRelease

    var body: some View {
        NavigationView {
            PDFPreviewController(release: release)
            .navigationBarTitle(Text("Preview"))
            .navigationBarItems(trailing: Button(action: {
                self.presentationMode.wrappedValue.dismiss()
            }) {
                Text("Done")
                    .fontWeight(.bold)
                }
            )
        }
    }
}


Solution

  • Creating view controller representable you set parameters to one controller but return another. Probably you meant the following:

    //let vc = PDFPreviewViewController() // don't think it is needed at all
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<PDFPreviewController>) -> UIViewController {
    
        let storyboard = UIStoryboard(name: "Preview", bundle: Bundle.main)
        let controller = storyboard.instantiateViewController(identifier: 
                             "Preview") as! PDFPreviewViewController
    
        controller.firstName = release.firstName // << here !
        controller.lastName = release.lastName   // << and here !
    
        return controller
    }