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
UINavigationController
and 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.