Zizoo
Zizoo

Reputation: 1764

Swift: When Does the Completion Block of Dismiss View Get Executed?

When does the completion block of dismiss view get executed? Is it after or before the user sees the view dismissed?

I have this code to make a toast with a message inside completion block but never see the toast after this view dismissed.

       self.dismiss(animated: true, completion: {
       self.view.makeToast(message: "Employee has been assigned successfully.", duration: 2.0, position: HRToastPositionCenter as AnyObject, title: "Succeeded!")
})

What I want is the user can see the toast when the view gets completely dismissed?

How do I do this ?

Upvotes: 8

Views: 26097

Answers (6)

Rico Crescenzio
Rico Crescenzio

Reputation: 4226

Maybe could be easier to show the toast on the window instead of a particular view?

   UIApplication.shared.keyWindow?.makeToast(message: "Employee has been assigned successfully.", duration: 2.0, position: HRToastPositionCenter as AnyObject, title: "Succeeded!")

Upvotes: 0

Sam
Sam

Reputation: 2341

For UIViewController.dismiss(animated:completion:)

The completion handler is called after the viewDidDisappear(_:) method is called on the presented view controller.

Source

For UIViewController.present(_:animated:completion:)

The completion handler is called after the viewDidAppear(_:) method is called on the presented view controller.

Source.


If you don't know when that is, this is the order of the UIViewController load, appear and dissapear methods

  1. viewDidLoad

normally we initialize data objects and controls. It will create all the necessary memory for all controls/data objects for this view. i.e. In the above case, anotherView and btnView, they will keep the same memory addresses for the whole life cycle.

  1. viewWillAppear

Called before the view is added to the windows’ view hierarchy. So it is ideal for updating the viewcontroller’s data.

  1. viewDidAppear

Called after the view is added to the windows’ view hierarchy.

  1. viewWillDisappear

Called before the view is removed from the windows’ view hierarchy.

  1. viewDidDisappear

Called after the view is removed from the windows’ view hierarchy.

Source

Upvotes: 3

alexburtnik
alexburtnik

Reputation: 7741

You can delegate the event from presented controller to the parent and handle it there.

In EmployeePickerViewController (or whatever your modal controller is called):

@protocol EmployeePickerDelegate {
    func employeeAssigned()
}

class EmployeePickerViewController {
    weak delegate: EmployeePickerDelegate!
}

When employee assignment is finished just call delegate's method:

delegate?.employeeAssigned()

In MainViewController when you present modally:

employeePicker.delegate = self
present(employeePicker, animated: true, completion: nil)

In MainViewController below:

extension MainViewController: EmployeePickerDelegate {
   func employeeAssigned {
       dismiss(animated: true, completion: {
            self.view.makeToast(message: "Employee has been assigned successfully.", duration: 2.0, position: HRToastPositionCenter as AnyObject, title: "Succeeded!")
       })
   }
}

Upvotes: 12

Lars Blumberg
Lars Blumberg

Reputation: 21421

The toast will be shown inside your dismissed view. Since the view has disappeared you won't see its toast. You might want to show the toast in the following screen that appears after the dismissed view.

Upvotes: 0

iCaramba
iCaramba

Reputation: 2640

The completion block is executed after the View Controller has been dismissed. This means your view is no longer on screen. I think you want to render the toast inside that view, which is not possible because it is off screen.

Upvotes: 0

Damien
Damien

Reputation: 3362

You are calling a dismiss on self, so every reference of that will be dealloc. your self.view doesn't exist anymore I guess.

Upvotes: 0

Related Questions