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.
Related
I have a basic scenario:
I present a VC modally using self.present(, animated:, completion:).
Sometimes due to interactions in this modal VC i need to close one modal and open another one.
So i do the following:
weak var presenter = self.presentingViewController
let newVc = UIViewController()
presenter?.dismiss(animated: true, completion: {
presenter?.present(newVc, animated: true, completion: nil)
})
This works but there is the annoying delay when switching the VC's when user sees the original presenter and can try to interact with it (to open other modals...).
I tried setting animated: false but that doesn't seem to work :/
I can't really switch to UINavigationController model for this because the modals i am presenting themselves are Page View Controllers and have the whole hierarchy of dependent views; the user is never going 'back'; so i'd really like to just present the new modal as quickly as possible...
Update My question is not about how to control or choose the animation. My questions is about having no delay between the modals.
The built-in view controller architecture that switches views with no transition is the tab bar controller. So just turn your view controller into a tab bar controller — with no visible tab bar! To change to the other view controller just change tabs (in code). The change is instant.
This screencast makes it clear that this works as described. We present a view controller (yellow). Then we switch back and forth between two view controllers (green and yellow) as the presented view controllers, instantly. Finally, we dismiss whichever one (green or yellow) is showing. I'm doing it all with simple buttons but that's just for the demo; obviously you could do this however you like. It's the architecture that's the important thing.
I can think only of solutions which would require you to handle the animations yourself
create custom modal transition using UIViewControllerTransitionCoordinator
add your controllers to container views as suggested by #muhammed-gül
present newVC over self and dismiss all presented controllers when you're done
And just a tip, you don't always need to wait for the dismiss completion closure, you can call this and it usually works, but still the underlying viewController is visible.
dismiss(animated: true)
present(newVC, animated: true)
I have view controllers, embedded in a UITabBarController. In one of this UIViewControllers I have a button which calls a popup view controller (pVC). pVC's is connected to the view controller via a UISegue modally, and its presentation style is set to overCurrentContext.
It works fine. However, I have noticed that when the pVC is showing and I switch the view controller to another one through the tab bar and come back to the one with the popup, the popup is still there, but the background is black. It looks like this:
I guess, this happens because the views beneath the popup are removed from the view hierarchy. In a view hierarchy debugger I see that my entire view controller is removed (not just its subviews). The problem is, I don't understand why this happens when I return back to that view controller (doesn't tab bars work that way?), and why the popup is still there (maybe because it is not just a view, but a UIViewController). I also would like to know how to solve this issue.
If you could explain why this happens (what is happening behind this), and how to solve this, I would appreciate your help.
Put this code into your popupVC:
tabBarController.tabBar.isUserInteractionEnabled = false
Do this if user can select with touch
// UITabBarControllerDelegate
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
print("Selected view controller")
self.dismiss(animated: true, completion: nil)
}
Or this if manually
self.tabBarController?.selectedIndex = 0
self.tabBarController(self.tabBarController!, didSelect: self)
any option implement UITabBarControllerDelegate
I'm pretty new to swift development but I am trying to implement a back button in my application.
I have the following layout in my Main.storyboard
As seen in the picture the navigation bars display however when i lunch my app they are not visible.
I also have tried using a button that will take me back to the previous view with
self.navigationController?.popViewControllerAnimated(true)
but it has not worked
Update:
The image above doesnt show the initial controller which is my ViewController
the problem is that All Routes is actually a PageContentViewController which is called from ViewController which checks for fb login than calls:
dispatch_async(dispatch_get_main_queue()){
self.setViewControllers([self.getViewControllerAtIndex(0)] as [UIViewController], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
}
So i cannot change my initial view controller.
I dont know how I can get around this problem.
Is there a way to do it from Main.storyboard or a programistic solution ?
Embedding my initial view in a navigational controller and setting it to the initial view has worked.
Even though it doesnt look right on the preview because my initial view calls the other views programmatically it works correctly on the device
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)
I'm having an issue with my main.storyboard file. I changed the settings of my app so that the start screen is the main.storyboard file, rather than LaunchScreen.xib. The initial ViewController is the NavigationController, and the second is my SplashScreeViewController. (I created my own splash screen in the storyboard so that I could change it with additional code.) I use a line of code in my splash screen to later transition to the second view controller. Here it is:
var controller:UIViewController = self.storyboard?.instantiateViewControllerWithIdentifier("Second") as! ViewController
controller.modalTransitionStyle = .CrossDissolve
self.presentViewController(controller, animated: true, completion: nil)
For some reason, when I transition to that second ViewController, the navigation bar that should be at the top (of the second ViewController) isn't there, opposite of what was shown in the main.storyboard file. I tried to add an invisible, disabled button to the splash screen as to add a connection between the two view controllers, and therefore adding a navigation bar to the second, but when the splash transitions on its own, no navigation bar appears on the second.
Is there a way I could have a navigation bar on my second view controller without dragging one in, nor programming it in? I would like to use the one Xcode provides when you create a new connection between controllers.
Thanks in advance to all who reply.
*(I apologize for the lack of pictures to help describe my problem. I don't have enough 'reputation' to do so.)
You need to embed your Second view controller on a Navigation Controller, and then instantiate that navigation controller instead.
This might solve the problem - It looks like you are presenting a modal view controller when you probably want to be pushing your view controller from your initial navigation controller with pushViewController