1

I am having a viewController with a couple of animated buttons, when the user presses a button the background is blurred (animation) and a menu to choose a couple of things (which all go to a new viewController) is presented.

So basically there is a scene, the user opens the menu, the scene is blurred except for the menu and the user presses a button and another viewController is shown programmatically with a crossDissolve. This is how I show the new controller:

let storyboard = UIStoryboard.init(name: "Timer", bundle: nil)
let vc = storyboard.instantiateInitialViewController()!
vc.modalTransitionStyle = .crossDissolve
present(vc, animated: true, completion: nil)

So far so good, but I am not able to reset the original scene (basically to just remove the blur and reset the animated buttons). I have a function in it called setupScene() which prepares everything for the app start (some buttons are hidden, the blur has an alpha of 0, etc....).

I just dismiss the new viewController like this:

dismiss(animated: true, completion: nil)

And than the original scene with it's last state (blurred etc.) is shown again.

So when the new viewController is presented I would like to reset everything in the original viewController in the background, so that when the new viewController is dismissed the old scene is already reset, but this doesn't work. I tried to move the setupScene() function in viewDidAppear, but either in viewDidAppear or viewDidLoad first the new viewController is dismissed showing the original viewController in it's last state with the blur again and then the setupScene() runs to reset everything (which obviously works fine).

Is there a way to reset everything in the background while the new viewController is shown or while the crossDissolve is running?

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
RjC
  • 827
  • 2
  • 14
  • 33

2 Answers2

1

There are several solutions to this, depending on how fancy you want to get.

Based on what you describe I think the first thing to try is to take advantage of that completion parameter in dismiss(animated:completion:)

It's a callback to your code once the dismiss is completed. This will allow you to reverse your animation.

The callback takes no parameters.

So, if your setupScene() method does what it says,

dismiss(animated: true, completion: {
    setupScene()
})

should do it.

ageektrapped
  • 14,482
  • 7
  • 57
  • 72
  • The approach sounds great, but how would I access the setupScene() function from the other viewController? The dismiss function is on timerViewControler.swift and not on the original viewController.swift. – RjC Nov 29 '17 at 14:12
  • 1
    Apple recommends not to do that. :) The VC that presents should dismiss. You could try what @Brian suggests, which is put the code in `viewWillAppear:` (or `viewDidDisappear:`, for that matter) for now to see if that works for you. Then you can introduce deferring the dismiss at another time. – ageektrapped Nov 29 '17 at 14:21
1

This sounds like a good case for viewWillAppear. This is a lifecycle method that is called when the visibility of a view controller's views change. viewDidLoad is only called once.

Brian
  • 924
  • 13
  • 22