Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

ios

swift

iphone

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 ?

like image 844
Zizoo Avatar asked Oct 09 '16 10:10

Zizoo


People also ask

What is completion block in Swift?

The block to execute after the operation's main task is completed.

How do you dismiss a view in Swift?

The first option is to tell the view to dismiss itself using its presentation mode environment key. Any view can read its presentation mode using @Environment(\. presentationMode) , and calling wrappedValue. dismiss() on that will cause the view to be dismissed.

How do I dismiss a presented Viewcontroller?

When it comes time to dismiss a presented view controller, the preferred approach is to let the presenting view controller dismiss it. In other words, whenever possible, the same view controller that presented the view controller should also take responsibility for dismissing it.

What is a UIViewController?

The UIViewController class defines the shared behavior that's common to all view controllers. You rarely create instances of the UIViewController class directly. Instead, you subclass UIViewController and add the methods and properties needed to manage the view controller's view hierarchy.


2 Answers

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!")
       })
   }
}
like image 86
alexburtnik Avatar answered Nov 15 '22 21:11

alexburtnik


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

like image 33
Sam Avatar answered Nov 15 '22 22:11

Sam