Transparent ViewController work with presentViewController, but not pushViewController - ios

let dialog: FriendCheckInDialogViewController = storyboard?.instantiateViewControllerWithIdentifier("FriendCheckInDialogViewController") as! FriendCheckInDialogViewController
dialog.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
If I use
self.navigationController?.presentViewController(dialog, animated: false, completion: nil)
Then transparency works. But popToRootViewControllerAnimated does not, so I cannot go back.
If I use
self.navigationController?.pushViewController(dialog, animated: false)
Then background becomes black instead of transparent. But popToRootViewControllerAnimated works, so I can go back.
What should I do?

You seem to be mixing different presentation styles.
If you present a view controller modally using presentViewController, then you can dismiss it using dismissViewController. In this case you can present the view controller modally over the current view controller.
If you push a view controller onto the navigation controller stack, then you can pop that view controller back off, but the pushed view controller replaces the current view controller, so you can't expose it "underneath".

Related

Opening a navigation controller from Tabbar with back button on first ViewController

I know this question has been asked so many times on the SO, but I am asking this just because it is relevantly different and also some answers are out dated and some are in Objective-c which I can not understand properly.
USE CASE:
I have a UITabBar controller, and it is working fine. Let say I have 4 tabs in it and user click on the button given in the Tab 4. now on it I have to open some series of View Controllers. let say User has following patteren to follow.
4.A-->4.B--> 4.C and can go back to first like so: 4.C-->4.B-->4.A
And finally User must also be allowed to go back to Tab4 after closing 4.A view controller
WHAT I DID:
I am able to open the View controller using this code.
let VC1 = storyboard.instantiateViewController(withIdentifier :"myVcId") as! UIViewController
let navController = UINavigationController(rootViewController: VC1) // Creating a navigation controller with VC1 at the root of the navigation stack.
self.present(navController, animated:true, completion: nil)
This is opening a navigation controller and having me navigate the view controller as per my requirements but I want following thing too
WHAT I WANT: As I am presenting the Navigation Controller modally, I want to show the back button at very first view controller, and I want that if user select back button it kills all the Navigation controller and go the previous view controller where he came from
You need to select the 4th tab and embed it inside a navigation then do
let vc = storyboard.instantiateViewController(withIdentifier :"myVcId") as! UIViewController
self.navigationController?.pushViewController(vc, animated: true)
then you'll see a back on that first vc , to return to that tab do
self.navigationController?.popToRootViewController(animated: true)
As far as I understood, your structure looks like this:
A TabBarController, with ViewControllers as tabs, and from them you present a navigation controller with other ViewControllers, like this:
(TabBar) -vc-> (View) -present-> (NavController) -root-vc-> (View)
I have two suggestions for making it easier to handle.
First option
Use navigation controllers as tabs for your TabBarController, and make your ViewControllers that are tabs their root view controllers.
(TabBar) -vc-> (NavController) -root-vc-> (View) -push-> (View)
Second option
Another option is to use a navigation controller as your initial view controller, and make your tab bar this navigation controller's root view controller.
(NavController) -root-vc-> (TabBar) -view-> (View) -push-> (View)
Both options should work, and the first one should be a little easier to handle.
You need to instantiate the navigationController with 4A as the rootViewController.
Then, in the viewDidLoad for 4A, you need to instantiate 4B, and push it to your navigationController.
Then, finally, in your 4B viewController's viewDidLoad you need to instantiate 4C and push it to your navigationController's stack.
P.S.: Push all the viewControllers without animations.
This should be achieving your strange scenario.
EDITED:
You need your 4th tab from your tabBar to be a navigationController,
and its root view Controller to be the initial VC which will then push
your new navController, otherwise you won't have the back button.
So, your stack should be something like this:
4CVC
|-(push)
4BVC
|-(push)
4AVC
|-(push)
newNavController
|-(push)
someVC
|
navController
|
tab1 tab2 tab3 tab4
|
tabBar

viewWillAppear and viewDidAppear not called when presenting view controller from Side Menu?

I'm using this library to show a side menu inside my app: https://github.com/jonkykong/SideMenu
All is fine except for one thing. When I present a viewcontroller from the side menu, and then dismiss this view controller to the main view controller, the viewWillAppear and/or viewDidAppear of the main view controller is not called ever.
From SideMenuVC (side menu view controller) I present other view controller:
let myPortfoliosNC = storyboard!.instantiateViewController(withIdentifier: "myPortfoliosNC")
present(myPortfoliosNC, animated: true, completion: nil)
Next, form the myPortfolioNC i dismiss (from the first view controller) and when go to main view controller the viewDidAppear and viewWillAppear is not called. Any idea of what i'm doing wrong ??

Dismissing presented view controller won't work

I've got a kind of complicated modal segue setup in my project. I'm trying to dismiss a view controller another view controller previously presented. I'm doing so with this code:
if(self.presentedViewController != nil){
print(self.presentedViewController!)
self.presentedViewController!.dismiss(animated: false)
print(self.presentedViewController!)
}
The prints are there for debugging purposes. They show that the presentedViewController doesn't actually get closed.
Even though I've set animated to false, I still see an animation occuring in the app when dismiss is called. Yet, the VC doesn't actually get dismissed.
Anyone knows a solution?
Apple
The presenting view controller is responsible for dismissing the view
controller it presented. If you call this method on the presented view
controller itself, UIKit asks the presenting view controller to handle
the dismissal.
dismiss(animated:completion:) dismisses the view controller that was
presented modally by the view controller.
https://developer.apple.com/documentation/uikit/uiviewcontroller/1621505-dismiss
If you present a view controller from the app's root, for example:
Presenting view controller
let root = UIApplication.shared.keyWindow!.rootViewController!
root.present(someViewController, animated: true, completion: nil)
You would dismiss it from the presented view controller like so:
Presented view controller
let root = UIApplication.shared.keyWindow?.rootViewController
root?.dismiss(animated: true, completion: nil)

No animation when pushing view controllers in UINavigationController

I have a storyboard set up with a UITabBarController which contains a UINavigationController for each tab. For one of the UINavigationControllers there are no transition animations when pushing or presenting a view controller.
There are, at least, two different cases when this happens
1. I have a storyboard segue set up to push the child view controller. The segue triggers when selecting a cell in a table view. The "Animates"-box is checked.
Attempting to programatically push the child view controller yields the same result.
self.navigationController?.pushViewController(nextController, animated: true)
2. There is also no animation when attempting to modally present another view controller from the root view controller of the navigation controller.
modalViewController.modalTransitionStyle = UIModalTransitionStyle.flipHorizontal
self.present(modalViewController, animated: true, completion: nil)
If I present the modalViewController from another view controller the transition is animated which leads me to believe that there is something wrong in the root view controller that is presenting.
Is there a way to disable animations on a UIViewController that I might accidentally have triggered? I have checked and verified that there are no UIView.setAnimationsEnabled(false)
Use self.navigationController?.pushViewController( instead of self.present(
You set up animation in UINavigationController. But you called the function self.present( which is provided by UIViewController. UIViewController of course cannot provide the animation.
In my overridden viewWillDisappear(_ animated: Bool) of the parent view controller I had some code that reset the state of a custom view. The reset did in turn disable actions via CATransaction.setDisableActions(true), thus disabling the transition animations.
Moving the reset to viewDidDisappear(_ animated: Bool) resolved the issue.

presentViewController does not show Tab Bar or Navigation Bar

I am new to Swift and have been struggling with this for a while.
I am trying to redirect users based on login status to either "Login" viewcontroller or "Home" viewcontroller.
"Home" viewcontroller has NavigationBar and TabBar and it shows a table. But, when i use the following code, i see only the table. NavigationBar and TabBar are not shown at all.
var view = self.storyboard?.instantiateViewControllerWithIdentifier("HomeViewController") as UIViewController
self.presentViewController(view, animated: true, completion: nil)
Here is my storyboard : https://www.dropbox.com/s/dkcz45n8000gua6/storyboard.png?dl=0
Any help would be appreciated!
Edit (used TabBarController):
var view = self.storyboard?.instantiateViewControllerWithIdentifier("MainTabController") as UITabBarController
self.presentViewController(view, animated: true, completion: nil)
Your problem has nothing to do with being new to swift; it has to do with not understanding storyboards. If you instantiate HomeViewController, and present it, then that's all you will get. The fact that it's embedded in a tab bar controller and navigation controller in the storyboard is not "known" to this bare controller you just instantiated. You should instantiate the tab bar controller instead, and present it. It will take care of instantiating any of its children, and the navigation controller will take care of instantiating its root view controller.

Resources