3
\$\begingroup\$

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:

  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()?
  2. Is it acceptable to present modally from the UINavigationController?
  3. Should I be subclassing the main UINavigationController and using its prepare(for:sender:) method (if this is even an option)?
  4. In the performSegue(withIdentifier:sender:) method, does the sender argument make any difference?
  5. 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.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks for your answer. I like these ideas - I’m going to try making the view controller in code. \$\endgroup\$
    – Chris
    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\$ 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
    Sep 2, 2018 at 6:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.