-1

I have a view controller which presents another view controller and within the presented viewcontroller , user makes choices which will lead to many other notifications to be pushed but when we dismiss the presentation viewcontroller I would like original parent viewcontroller to be notified as viewwillappear is not firing.

D C T
  • 39
  • 10
  • 1
    I would expect viewWillAppear to get called in the parent view controller when the child is dismissed. (viewDidLoad won't get called again, but viewWillAppear is supposed to be called each time a view controller is about to be moved frontmost.) – Duncan C Sep 17 '21 at 12:35
  • 1
    @DuncanC That depends on the _modal transition style_: if the presented view is "full screen", then viewWillAppear will be called (more precisely: _may_ be called). If it covers partially the view of the presenting view controller, then viewWillAppear will not be called - because it's already there and not appearing. – CouchDeveloper Sep 17 '21 at 13:28
  • 1
    @CouchDeveloper Good point. I thought about that after I posted my comment. – Duncan C Sep 17 '21 at 15:26
  • 1
    Like you said , It's presented modally and viewwillappear is not gettign called – D C T Sep 17 '21 at 17:01

2 Answers2

1

You can add a block handler to your child controller to notify the parent controller with the user choice:

struct Choice {
  // whatever object that represents the user choice
}

class ChildController: UIViewController {

  var completionHandler: ((ChildController, Choice) -> Void)?

  func finishPresentation(with choice: Choice) {
     // Suppose this function is called when user picks something in the user interface
     completionHandler?(self, choice)
  }

}

Then in parent controller, assign the completionHandler to get notified with the user choice.

class ParentController: UIViewController {
  func presentChild() {
     let controller = ChildController()

     controller.completionHandler = { child, choice
        child.dismiss(animated: true) {
          // do something with the user choice
        }
     }

     present(controller, animated: true)
  }
}
pronebird
  • 12,068
  • 5
  • 54
  • 82
  • I'm using MVVM architecture and it's bit complicated to pass the data through handlers from one view model to another view model to another etc... Is there anyway I can get to know this via some viewcontroller lifecycle methods in parent viewcontroller ? – D C T Sep 17 '21 at 10:32
  • @DCT Not really, even though there are ways to figure this out on the presenting view controller. The problem then is, you only know that a UIViewController is about to be dismissed. But you actually need the _data_ the child passes back to the parent. The solution of Ben is perfect. ;) – CouchDeveloper Sep 17 '21 at 13:36
  • @DCT this is not mentioned in the question. I don't think it really matters if you use models or not, you should have some sort of back channel to pass the data between controllers. – pronebird Sep 20 '21 at 12:06
0

You may post the notification from child when it's about to be dismissed and observe the notification in parent view controller.

In parent view controller

NotificationCenter.default.addObserver(self, selector: #selector(methodtobecalled(_:)), name: "childdismissed", object: nil)

 @objc func methodtobecalled(_: Notification) {
        
    }

In child viewcontroller when you choose to dismiss , send the notification

NotificationCenter.default.post(name: "childdismissed", object: nil, userInfo: nil)

Adopt the class UIAdaptivePresentationControllerDelegate in presented view controller

add below delegate methods

func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
        return false
    }

func presentationControllerDidAttemptToDismiss(_ presentationController: UIPresentationController) {
    dismiss(animated: true, completion: nil)
   // Post the notification here

}

CuriousMan
  • 42
  • 11