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)
- Current viewWillDisappear
- New viewWillAppear
- Current viewDidDisappear
- New viewDidAppear
Canceled Interactive Popping:
- Current viewWillDisappear
- New viewWillAppear
- New viewWillDisappear
- New viewDidDisappear
- Current viewWillAppear
- Current viewDidAppear
Page Scrolling (
UIPageViewControllerTransitionStyleScroll)Normal:
- New viewWillAppear
- Current viewWillDisappear
- New viewDidAppear
- Current viewDidDisappear
Canceled Interactive Scrolling:
- New viewWillAppear
- Current viewWillDisappear
- Current viewWillAppear
- Current viewDidAppear
- New viewWillDisappear
- New viewDidDisappear
Page Curling (
UIPageViewControllerTransitionStylePageCurl)Normal:
- New viewWillAppear
- Current viewWillDisappear
- Current viewDidDisappear
- New viewDidAppear
Canceled Interactive Curling:
- New viewWillAppear
- Current viewWillDisappear
- New viewWillDisappear
- Current viewWillAppear
- New viewDidDisappear
- Current viewDidAppear
As you can see:
- New view's
viewWillAppearmay be called before or after current view'sviewWillDisappear. - New view's
viewDidAppearmay be called before or after current view'sviewDidDisappear. - For interactive canceling, new view's
viewDidDisappearis not balanced withviewDidAppear— there is noviewDidAppearbetweenviewWillAppearandviewWillDisappear. - Of course, for the same view,
viewWillAppearis always beforeviewDidAppearandviewWillDisappearis alway beforeviewDidDisappear, if only both are gotten called — see point 3. - The only certain order between current view and new view is that current view's
viewWillDisappearis before new view'sviewDidAppearand new view'sviewWillAppearis before current view'sviewDidDisappear, but if only both are gotten called — see point 3.
