Completion Block for Popviewcontroller

Completion block for popViewController

I know an answer has been accepted over two years ago, however this answer is incomplete.

There is no way to do what you're wanting out-of-the-box

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:

[CATransaction begin];
[CATransaction setCompletionBlock:^{
// handle completion here
}];

[self.navigationController popViewControllerAnimated:YES];

[CATransaction commit];

The completion block will be called as soon as the animation used by popViewControllerAnimated: ends. This functionality has been available since iOS 4.

Wait until popToRootViewControllerAnimated:YES animation is done

in your rootViewController , when you rootViewController invoke the - (void)viewDidAppear:(BOOL)animated it means the animation is finish.

You can code in the rootViewControllers - (void)viewDidAppear:(BOOL)animated

If you want must code in your current ViewController , I think it has 2 ways:

1.add a delegate in the rootViewController , when invoke the - (void)viewDidAppear:(BOOL)animated use delegate to sent the message

2.add a notification in the rootViewController,when invoke the - (void)viewDidAppear:(BOOL)animated post a notification . And in your current ViewController you can receive the notification

popToViewController isn't popping all of the view controllers

Your confusion may simply be the way you are trying to "check" that the VCs are "popped".

Suppose you have gone:

root->TableView->A->B->A->B->B->B->`

At that point, the only VC that is visible is the last instance of A. So when you call

navController.popToViewController(controller, animated: true)

viewWillDisappear() will only be called on the last instance of A - none of the other VC instances will "disappear" because they are not visible.

If you want to confirm the other VCs in the stack are being "removed", put this in each view controller:

deinit() {
print("I'm being removed:", self)
}

The other part of the question - do you want to animate through the process? So you would actually see the VCs "walk back up the stack"? If so, follow @FryAnEgg's link to Completion block for popViewController

How to use completion block for UIView.animate()?

The size is 0, 0. Transforming zero by any scale is still zero. I would advise you to not use transform at all, but rather just set the final frame to be what you want.

E.g.,

let startFrame = CGRect(x: view.bounds.midX, y: view.bounds.midY, width: 0, height: 0)
let endFrame = view.bounds

let imageView = UIImageView(image: ...)
imageView.contentMode = .scaleAspectFill
view.addSubview(imageView)
imageView.frame = startFrame
UIView.animate(withDuration: 3, delay: 0, options: .curveEaseInOut) {
imageView.frame = endFrame
} completion: { _ in
// do something here
}

That yields:

enter image description here


By the way, the performSegue probably should be inside a completion closure of the inner animate call.

Dose UIView.animate completion block run in main thread?

The answer is yes. But to be sure you can test it by adding a debug print:

UIView.animate(withDuration: 0.3, animations: {
popup.alpha = 0
}, completion: {
print("---- isMainThread: \(Thread.isMainThread) ----")
animationCount -= 1
if animationCount == 0 {
popup.removeFromSuperview()
}
})


Related Topics



Leave a reply



Submit