When dismissing a modal view controller using dismissViewController
, there is the option to provide a completion block. Is there a similar equivalent for popViewController
?
The completion argument is quite handy. For instance, I can use it to hold off removing a row from a tableview until the modal is off screen, letting the user see the row animation. When returning from a pushed view controller, I would like the same opportunity.
I have tried placing popViewController
in an UIView
animation block, where I do have access to a completion block. However, this produces some unwanted side effects on the view being popped to.
If there is no such method available, what are some workarounds?
I know an answer has been accepted over two years ago, however this answer is incomplete.
This is technically correct because the
UINavigationController
API doesn't offer any options for this. However by using the CoreAnimation framework it's possible to add a completion block to the underlying animation:The completion block will be called as soon as the animation used by
popViewControllerAnimated:
ends. This functionality has been available since iOS 4.There is a pod called UINavigationControllerWithCompletionBlock which adds support for a completion block when both pushing and popping on a UINavigationController.
Just for completeness, I've made an Objective-C category ready to use:
I made a
Swift
version with extensions with @JorisKluivers answer.This will call a completion closure after the animation is done for both
push
andpop
.SWIFT 4.1
I achieved exactly this with precision using a block. I wanted my fetched results controller to show the row that was added by the modal view, only once it had fully left the screen, so the user could see the change happening. In prepare for segue which is responsible for showing the modal view controller, I set the block I want to execute when the modal disappears. And in the modal view controller I override viewDidDissapear and then call the block. I simply begin updates when the modal is going to appear and end updates when it disappears, but that is because I'm using a NSFetchedResultsController however you can do whatever you like inside the block.