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.
Schematic of my storyboard 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.
1 Answer 1
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.
-
\$\begingroup\$ Thanks for your answer. I like these ideas - I’m going to try making the view controller in code. \$\endgroup\$Chris– Chris2018年09月01日 20:55:58 +00:00Commented Sep 1, 2018 at 20:55
-
\$\begingroup\$ That's not necessary. You can instantiate it from a storyboard or XIB if you want and then push it all through code. \$\endgroup\$Lucas van Dongen– Lucas van Dongen2018年09月01日 21:47:15 +00:00Commented Sep 1, 2018 at 21:47
-
1\$\begingroup\$ Ah yes I see what you mean. That sounds easier as I already have my Storyboard made! \$\endgroup\$Chris– Chris2018年09月02日 06:03:49 +00:00Commented Sep 2, 2018 at 6:03