Presenting and passing data to a modal view controller without using prepare(for:sender:) method I am using a toolbar button to present a modal view controller (in which I let the user export data as a PDF file). The main section of my app is a UITableViewController subclass embedded in a UINavigationController.

Here is a schematic of my layout.



The modal itself is embedded in a UINavigationController as I need it to have a bottom toolbar. It also has a transparent background and is presented using .overCurrentContext, so the main screen of the user's data blurs underneath. 

I found that to get it to float over everything else (including the navigation bar etc), I had to present it from the UINavigationController (otherwise the main navigation bar and toolbar appeared on top of it).
The problem with this is that the UITableViewController method prepare(for:sender:) is not called.

I call the segue to the modal view controller like this (from the UITableViewController subclass):

// User taps EXPORT button
@objc func exportButtonTapped(_ sender: UIBarButtonItem) {
    self.navigationController?.performSegue(withIdentifier: "showExport", sender: nil)
}


In order to transfer the array of user data to the modal view controller, I have called the following code in the modal view controller:

override func viewDidLoad() {
    super.viewDidLoad()
    // Get data from array in main table view controller
    let masterNav = navigationController?.presentingViewController as! UINavigationController
    let myTableVC = masterNav.topViewController as! MyTableViewController
    self.userData = myTableVC.userData // This is of type: [MyObject]
} 


The data is then rendered to a PDF (using HTML templating) in the modal view controller's viewWillAppear() method. This works as expected.

However, I have some concerns about doing it this way:


Is it guaranteed that viewDidLoad() will finish before viewWillAppear() is called? Will an even a larger data set be available for rendering as PDF in viewWillAppear()?
Is it acceptable to present modally from the UINavigationController?
Should I be subclassing the main UINavigationController and using its prepare(for:sender:) method (if this is even an option)?
In the performSegue(withIdentifier:sender:) method, does the sender argument make any difference?
Is it preferable to use present() rather than a segue?


I would of course be grateful for any other advice or refinements to the code. It seems to work as expected but I just want to make sure I following best practice as far as possible.
Is it guaranteed that viewDidLoad() will finish before viewWillAppear() is called? Will an even a larger data set be available for rendering as PDF in viewWillAppear()?


Yes. It needs to be loaded before it will appear.


  Is it acceptable to present modally from the UINavigationController?


I think it is.


  Should I be subclassing the main UINavigationController and using its prepare(for:sender:) method (if this is even an option)?


It sounds a bit complicated. prepare(for:sender:) is not a very clean way to do transfer data to begin with and only useful when you use segues in a regular way. Why don't you create the ModalViewController in code, set the value and then push it through code instead?


  In the performSegue(withIdentifier:sender:) method, does the sender argument make any difference?


I used it in rare occasions to understand where the push was coming from.


  Is it preferable to use present() rather than a segue?


I think in your case yes.