0

In StoreViewController, when a button is clicked, a ModalViewController, named AddStoreVC is opened.

Then at AddStoreVC, when I press Save, I want to dismiss itself (which I can) and when StoreViewController is loaded, the tableView to be refreshed.

viewWillAppear, viewDidAppear or none of the alternatives on previous threads are applicable.

I'd appreciate for your support.

Baseduo
  • 35
  • 1
  • 1
  • 10

1 Answers1

2

You can use a closure, delegate or notifications (and even KVO would also be a solution). Since you have a relation of one-one, I'd go with closure or pattern.

Closure:

Add in the ViewController which will be modally presented (AddStoreVC)

var onWillDismiss: (() -> Void)?

When you call dismiss(animated:completion:) on it, call onWillDismiss?()

In the presenting ViewController, get a reference on the modal one, and do:

modalVC.onWillDismiss = { [weak self] in 
    self?.myTableView.reloadData()
}

I passed no param (()), but if you also want to retrieve a param, add it. Imagine you want an Int:

var onWillDismiss: ((Int) -> Void)?
onWillDismiss?(theIntIWantToPass)
modalVC.onWillDismiss = { [weak self] theIntPassed in 
    print(theIntPassed)
    self?.myTableView.reloadData()
}

Delegate :

You can also use the delegate pattern:

Create the delegate:

protocol AddStoreVCCustomProtocol {
    func modalVCWillDismiss(_ modalVC: AddStoreVC)
    func modalVC(_ modalVC, willDimissWithParam param: Int)
}

Make the presenting one compliant to it:

extension StoreViewController: AddStoreVCCustomProtocol {
    func modalVCWillDismiss(_ modalVC: AddStoreVC) {
        myTableView.reloadData()
    }
    func modalVC(_ modalVC, willDimissWithParam param: Int) {
        print("theIntPassed with delegate: \(param)")
        myTableView.reloadData()
    }
}

Add a property to the Modal to have a delegate:

weak var customDelegate: AddStoreVCCustomProtocol?

And call it on dismiss(animated:completion:): customDelegate?.modalVCWillDismiss(self) or `customDelegate?.modalVC(self, willDimissWithParam: theIntIWantToPass)

Larme
  • 24,190
  • 6
  • 51
  • 81
  • Actually in modally presented controller you don't need closure nor delegate. There is [`presentingViewController`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621430-presentingviewcontroller) – vadian May 07 '21 at 12:24
  • Good point. `(presentingViewController as? StoreViewController).myTableView.reloadData()` might do the trick indeed. It's just that a reloading method or the var shouldn't be visible others instances. So keeping the protocol still be a good thing, to do `(presentingViewController as? ReloadableProtocol).reload()`. – Larme May 07 '21 at 12:27
  • In the Closure case, where should I add ````modalVC.onWillDismiss = { [weak self] in self?.myTableView.reloadData() } ```` part? Because willWillAppear is not working. – Baseduo May 07 '21 at 12:33
  • 1
    How do you present modally `AddStoreVC`? Segue from Storyboard? Code? That's where you get that `modalVC` var. Either when you create it by code, or by override prepareForSegue. – Larme May 07 '21 at 12:35
  • 1
    @Baseduo *....when I press Save*. There, in the action. Or adopt `UIAdaptivePresentationControllerDelegate` and implement `presentationControllerDidAttemptToDismiss`. It is called when you swipe down. – vadian May 07 '21 at 12:41
  • Thank you @Larme. I succeeded with closure case – Baseduo May 07 '21 at 14:33