Can't add view infront of modal controller's view - ios

I have a modally presented view controller and I want to push a modal view on top of it. This should be simple to do, but I've missed something :)
The modally presented view controller doesn't cover the whole screen (it uses custom presentation) so I can't just add my view on top of that. But when I try to add my view to either the presenting view controller, or just onto UIApplication.shared.keyWindow.rootViewController.view I get a very strange result.
I've tried this using the default modal presentation an it still behaves in the same way, so I don't believe it's my custom presentation causing this.
Here is the exploded view from Xcode - with the overlay at the correct position front and center.
And here is the simulator at the time this interface was snapshotted.
Does anyone know why the alert view (which is clearly at the top of the stack looking in Xcode) doesn't appear?
NB: I'm pretty confident that the exploded view in Xcode is correct because it matches up with the output from po [[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] recursiveDescription]

I think you should try to present some vc in your current and in other view controllers first.
... // your view controller
present(/* your alert view controller */, animated: true, completion: nil)
For example, it should show a empty vc like below. See if you can present any vc normally. If yes, it might be your alert view controller problem.
... // your view controller
let vc = UIViewController()
present(vc, animated: true, completion: nil)
... // presented a black screen, it works

Related

Dismissing modally presented ViewController always throws me back to root

I've had this issue for months with multiple views, both Apple provided like ImagePicker and VCs from storyboard.
I believe that it has something to do with the underlying views we have both a tab bar controller and navigation controller in most views.
Strange thing is using some open source views from pods does not cause this bug.
So I'm two views deep on a navigation controller and present another view modally on top with present(vc, animated: true, completion: {})
Works like a charm, now dismissing that view with dismiss(animated: true, completion: nil) throws me back all the way to the initial view or root view of the navigation controller, had both happen before, depending on the presented view.
Update:
Build a sample project trying to reproduce the behavior but failed. Drew a reduced diagram to better explain the current bug behavior.
Also noticed that if I'm invoking the post view one step earlier in the Fandom view it works as expected.
In my case i am using UITabBarController, and I wrote code in viewWillAppear of UITabBarController
self.selectedIndex = 2
so when i present any thing from any controller whose parent is UITabBarController and when i dismiss that it automatically open third tab of UITabBarController.
Maybe you explicitly wrote any code to select specific index of TabBar.
Maybe this is useful for you or anyone else.

Present 2 navigationControllers in one stack in one go

current i am developing this app and i have the main and login screen.
The architecture works in such a way that when the app launches, the main screen will always present first.
then, if the user is not logged in, the login screen will be presented modally on top of the main screen. (i think this is a normal approach right?).
However, the thing is now that, whenever i do the following code.
self.present(mainNavigationController, animated: false, completion: {
let storyboard = UIStoryboard(name: "LoginSignUp", bundle: nil)
let loginNavigationController = storyboard.instantiateViewController(withIdentifier: "loginNavigationViewController") as! UINavigationController
mainNavigationController.present(loginNavigationController, animated: false, completion: nil)
})
I will always see a blank white main screen before the the login screen is shown, that is kinda ugly.. Anyone has any solution such that these two view controllers are stacked on top of each other from the very beginning and shown once, rather than shown in sequence?
You code is trying to accomplish this:
Present main navigation controller modally over the current view controllers navigation.
Then after showing it present login modally on mainNavigation controller.
You need to change in this way:
Push your main screen in current navigation stack by pushViewController.
And then try to present login screen modally over the current navigation stack.

Dismiss presented view controller, after the presenting view controller has been released

I am working on some old code that I didn't write, and it's really not architected well...
The situation is that a view controller presents a custom view controller modally, however every 30 seconds the presenting view controller is recreated.
The issue here is that if the modal is on screen when this happens, then any effort to dismiss it results in odd behaviour (such as a white screen).
I have tried calling [self.presentedViewController dismissViewControllerAnimated]; on the newly recreated controller, but presentedViewController is nil as you would expect.
I have also tried keeping a weak reference to the modal view controller, then when the presenting VC is reloaded, setting this value to that of the old VC. This has allowed me to call self.customModalVC dismissViewControllerAnimated]; but this is causing the aforementioned white screen, perhaps because it's presenting VC is no longer in the stack?
Any and all suggestions appreciated.
Try passing the navigation controller to newly presented ViewController:
presentedVC.navigation = self.navigationController
Add this to newly created one for dismissing
self.dismiss(animated: false) {
_ = self.navigation?.popViewController(animated: true)
}

Presenting Modal ViewController from (Table)ViewController inside a NavigationController inside a TabBarController

When I try presenting the modal controller right from the table view controller (could be a normal view controller as well), it appears behind the tab bar and looks quite ugly as I'm using a blur effect on it. I am using a navigation controller because I need to have a bar at the top and, after research, found that's the best way to do it.
I have found that doing something like:
self.parent?.parent?.present(ModelViewController(), animated: true, completion: nil)
when wanting to present the modal controller works. However, I imagine this isn't very safe. What is the correct way of doing this?
In order for the ModalViewController to present in front of the tab bar, its modalPresentationStyle has to be set to overFullScreen. So for instance when initializing the ModalViewController:
self.modalPresentationStyle = .overFullScreen (Swift 3 syntax)

"Present Modally" does not show when another modal is already presented

In my iOS application, my VC is presenting a modal (A) via code.
However, when I already have another modal presented (B), this one is not showing at all.
However, when (A) is deinitted, I see that (B) also gets deinitted.
How can I make sure that (B) always gets shown, no matter what, and in front of all other modals?
performSegueWithIdentifier(SEGUES.SegueTabBarToBroadcast, sender: view )
My TabBarViewController is calling this segue. (The segue is modal according to storyboard).
The problem occurs when one of the view controllers in my TabBar presents a modal. Then, when I try to call performSegueWithIdentifier, the modal doesn't show (but yet deinits when I close the other modal).
I just want this modal to present NO MATTER WHAT. This modal should overlap all other modals.
I also tried this, but the problem persists:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let bvc = storyboard.instantiateViewControllerWithIdentifier("BroadcastViewController") as! BroadcastViewController
self.presentViewController( bvc , animated: true, completion: nil)
Presenting multiple view controllers as a modal is not good practice. If you want to present your vc no matter what, then you have to understand the hierarchy of your view controllers. Shortly, you can present view controller modally on the vc with view that has a window, and when you have already presented any vc modally, your view controller's view that has presented the vc does not have the window, thus can't present other view controller modally. Conclusion: you can present vc modally from the top-most vc. So, solution would be keeping reference to the top-most vc, and presenting the desired vc from that vc. Another solution would be adding vc's view directly to the main window of the app, but I would not recommend solving your problem that way. Hope, this helps.

Resources