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 beforeviewWillAppear()is called? Will an even a larger data set be available for rendering as PDF inviewWillAppear()? - Is it acceptable to present modally from the
UINavigationController? - Should I be subclassing the main
UINavigationControllerand using itsprepare(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.
