The Inconsistent Order of View Transition Events

You should never write code depending on any particular order of

  • – viewWillAppear:
  • – viewDidAppear:
  • – viewWillDisappear:
  • – viewDidDisappear:

calls in any app with more that one kind of view transitions because each kind of view transition has its own order and it may be incompatible with the assumption of your code.

For demonstration I'll show you the cases of three common view transitions.

  • Navigation

    Normal: (Pushing and popping, interactive or not)

    1. Current viewWillDisappear
    2. New viewWillAppear
    3. Current viewDidDisappear
    4. New viewDidAppear

    Canceled Interactive Popping:

    1. Current viewWillDisappear
    2. New viewWillAppear
    3. New viewWillDisappear
    4. New viewDidDisappear
    5. Current viewWillAppear
    6. Current viewDidAppear
  • Page Scrolling (UIPageViewControllerTransitionStyleScroll)

    Normal:

    1. New viewWillAppear
    2. Current viewWillDisappear
    3. New viewDidAppear
    4. Current viewDidDisappear

    Canceled Interactive Scrolling:

    1. New viewWillAppear
    2. Current viewWillDisappear
    3. Current viewWillAppear
    4. Current viewDidAppear
    5. New viewWillDisappear
    6. New viewDidDisappear
  • Page Curling (UIPageViewControllerTransitionStylePageCurl)

    Normal:

    1. New viewWillAppear
    2. Current viewWillDisappear
    3. Current viewDidDisappear
    4. New viewDidAppear

    Canceled Interactive Curling:

    1. New viewWillAppear
    2. Current viewWillDisappear
    3. New viewWillDisappear
    4. Current viewWillAppear
    5. New viewDidDisappear
    6. Current viewDidAppear

As you can see:

  • New view's viewWillAppear may be called before or after current view's viewWillDisappear.
  • New view's viewDidAppear may be called before or after current view's viewDidDisappear.
  • For interactive canceling, new view's viewDidDisappear is not balanced with viewDidAppear — there is no viewDidAppear between viewWillAppear and viewWillDisappear.
  • Of course, for the same view, viewWillAppear is always before viewDidAppear and viewWillDisappear is alway before viewDidDisappear, if only both are gotten called — see point 3.
  • The only certain order between current view and new view is that current view's viewWillDisappear is before new view's viewDidAppear and new view's viewWillAppear is before current view's viewDidDisappear, but if only both are gotten called — see point 3.