0

I'm trying to call the reloadData() method to update a table view in an external class (different view controller), using the method viewDidDisappear().

I can already update the table view when the view where it is located is loaded or appears:

class OrderHistoryController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    @IBOutlet var orderTable: UITableView!
    
    //called when order table is loaded or appears
    override func viewDidLoad() {
        super.viewDidLoad()
        self.orderTable.delegate = self
        self.orderTable.dataSource = self
        self.orderTable.reloadData()
    }
    override func viewDidAppear(_ animated: Bool) {
        self.orderTable.delegate = self
        self.orderTable.dataSource = self
        self.orderTable.reloadData()
    }
    // ...
}

But I want the table to be reloaded when another view disappears.

class OrderDocumentationController: UIViewController {
      
    override func viewDidDisappear(_ animated: Bool) {
        OrderHistoryController().orderTable.reloadData()
        return
    }
    // ...
}

I get the fatal error:

Unexpectedly found nil while implicitly unwrapping an Optional value.

Guess it is just a rookie mistake. Any ideas? Thank you in advance!

Andreas Oetjen
  • 9,889
  • 1
  • 24
  • 34
alju2404
  • 31
  • 5
  • you’re calling a new instance of OrderedHistoryController() for which you don’t even have the views loaded. try to pass the reference of the existing instance of OrderedHistoryController to this one where you call the viewDidDisappear() or maybe reload the table virw in the other controller method viewDidAppear if the flow you’re following allows it – Luca Iaco Aug 23 '20 at 16:46
  • This implementation is wrong. You can use the concept called Delegates in swift. – Santosh Aug 23 '20 at 17:20

2 Answers2

0

When you call OrderHistoryController().orderTable.reloadData(), this will create a new OrderHistoryController instance, that will have not orderTable outlet connected hence resulting in the crash.

There are differnt ways to achieve what you want:

  • Store a reference to the OrderHistoryController instance and use this
  • Maybe better: Implement some custom delegation mechanism
  • Use the NotificationCenter to send a message that then will result in a refresh
Andreas Oetjen
  • 9,889
  • 1
  • 24
  • 34
0

No need to reload orderTable if OrderHistoryController appears when OrderDocumentationController disappears. Since, self.orderTable.reloadData() is called in OrderHistoryController::viewDidAppear()

UPDATE:

A better approach would be to have OrderDocumentationController provide a block which is called when the modal controller has completed.

So in OrderDocumentationController, provide a block property say with the name onDoneBlock.

In OrderHistoryController you present as follows:

  • In OrderHistoryController, create OrderDocumentationController

  • Set the done handler for OrderDocumentationController as: OrderDocumentationController.onDoneBlock={[OrderDocumentationController dismissViewControllerAnimated:YES completion:nil]};

  • Present the OrderDocumentationController controller as normal using [self OrderDocumentationController animated:YES completion:nil];

  • In OrderDocumentationController, in the cancel target action call self.onDoneBlock();

The result is OrderDocumentationController tells whoever raises it that it is done. You can extend the onDoneBlock to have arguments which indicate if the modal completed, cancelled, succeeded etc.

Nandish
  • 1,136
  • 9
  • 16
  • This is not very reliable, because for for many iPad presentation styles (like popover, formSheet etc.) the appear-Methods are not called upon dismissal. – Andreas Oetjen Aug 23 '20 at 18:11
  • that's it! I'm using a popover presentation style and in this case my first view controller (orderHistory) won't be reloaded and does not "appear" again when leaving my second view controller (orderDocumentation). I'm trying the delegate concept, but am still struggling... – alju2404 Aug 23 '20 at 20:37