Can you detect when a UIViewController has been dismissed or popped?

-dealloc is probably your best bet. The view controller will be deallocated when it is popped from the stack, unless you are retaining it elsewhere.

viewWillDisappear: and viewDidDisappear: aren't good choices because they are called any time the view controller is no longer shown, including when it pushes something else on the stack (so it becomes second-from-the-top).

viewDidUnload is no longer used. The system frameworks stopped calling this method as of iOS 6.


Building upon @Enricoza's comment, if you do have your UIViewController embedded in a UINavigationController, try this out:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    
    if ((navigationController?.isBeingDismissed) != nil) {
        // Add clean up code here
    }
}

override func viewDidDisappear(animated: Bool) {
    super.viewDidDisappear(animated)
    if (isBeingDismissed() || isMovingFromParentViewController()) {
        // clean up code here
    }
}

EDIT for swift 4/5

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    if (isBeingDismissed || isMovingFromParent) {
        // clean up code here
    }
}