How to prevent dismissal of UITabBarController by pushed SFSafariViewController? - swift

I'm pushing SFSafariViewController into UITabBarController. But clicking on the Safari Done button dismisses the UITabBarController. How to prevent it?

If you are Pushing the SFSafariViewController try popViewController instead of dismiss
self.navigationController?.popViewController(animated: true)
Or you can present the SFSafariViewController instead of pushing it
safariViewController.modalTransitionStyle = .crossDissolve
safariViewController.modalPresentationStyle = .overCurrentContext
self.present(safariViewController, animated: false, completion:nil)

Related

swift - Dismiss presenting view controller without dismissing navigation controller?

I am trying to dismiss a modal and push a new view controller from the navigation controller, but the code bellow dismisses the navigation controller as well, so there is nothing to push to and the window collapses. This code is inside my routing class:
func navigateToVC() {
self.navigationController.presentingViewController.dismiss(animated: false, completion: nil)
self.navigationController.pushViewController(newVC, animated: false)
}
So is there a way to dismiss the presenting view controllers while keeping the navigation controller?
Use this to dismiss presented ViewController,
self.dismiss(animated: true)
Once you dismiss it , that's where you should push ViewController. You can't push after you dismiss your viewController because it's deallocated already.
I recommend creating a delegate and call it from your HomeViewController

Present viewcontroller with tabbar

I created UITabBarController programmatically in AppDelegate with 4 view controllers(using .xib). When user tap some button on ViewController (VC-A) it present another VC (VC-B) and covered tabbar. So I want to VC-B has a tabbar on the button.
I tried to add VC-B as a child of tabbarcontroller. I tried to .present(vc) and .show(vc) on both: VC-A and VC-A.TabBarController
Creating controllers in AppDelegate:
let controllers = [tabViewController1,tabViewController2,tabViewController3,tabViewController4]
tabBarController.viewControllers = controllers
window?.rootViewController = tabBarController
presenting in VC-A
self.tabBarController?.present(controller, animated: false, completion: nil)
right click and drag from tabbar controller in storyboard to VC-B. that should create a tab on the bottom of your VC-A and VC-B to go back and forth without having to implement any backend code unless you want to animate
The solution is to embed every VC in navigationController and then add to TabBarController.
let vc1 = ViewController1()
let navController1 = UINavigationController(rootViewController: vc1)
navController.isNavigationBarHidden = true
let controllers = [navController1, navController2, navController3, navController4]
tabBarController.viewControllers = controllers
window?.rootViewController = tabBarController
Then call
self.navigationController?.pushViewController(controller, animated:
true)
To diplay VC with tabbar
I will press the red login button at the bottom of the picture and try to log in.
login button => "로그인"
After that, log in.
let moreVC = self.storyboard?.instantiateViewController(withIdentifier: "MoreViewController") as! MoreViewController
moreVC.definesPresentationContext = true
moreVC.modalPresentationStyle = .fullScreen
let navController = UINavigationController(rootViewController: moreVC)
self.present(navController, animated: true, completion: nil)
If the login proceeds without error, the above code will be called to display the screen when the login is completed.
If the flow proceeds as the code above, this screen appears.
The screen shown is not fullscreen, and the tabbar at the bottom is gone. The screen I want is the screen below.
How can I present a tab bar when presenting the screen?

Cant dismiss view controller after present it

After presenting a Tab bar controller, I can't dismiss tab bar controller.
I also can't even tap my button after I reinstall without delete the app. Need to uninstall and reinstall the app then I am able to tap the button
I already tried some other way of dismiss the tab bar controller but still unable to dismiss the controller.
This is my current way to present controller after login
let storyboard = UIStoryboard.init(name: "Main", bundle: Bundle.main)
let loginVC = storyboard.instantiateViewController(withIdentifier: "Home")
self.present(loginVC, animated: true, completion: nil)
This is my current way to dismiss controller
#IBAction func btnLogout_TouchUpInside(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
This is my root view
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
if defaults.bool(forKey: "isLoggedIn") {
// Show Home screen
window?.rootViewController = storyboard.instantiateViewController(withIdentifier: "Home")
} else {
// Show Login screen
window?.rootViewController = storyboard.instantiateViewController(withIdentifier: "Login")
}
window?.makeKeyAndVisible()
try to dismiss all presented controller it may work for you
DispatchQueue.main.async {
self.view.window!.rootViewController?.dismiss(animated: true, completion: {
print("All controller dismissed successfully..")
})
}
Try This
self.presentingViewController?.dismiss(animated: true, completion: nil)
Hmm. Your update helps although I'm still not sure what's happening. My guess is that you are setting login as root, then presenting home. But I'm not sure where or what you are trying to dismiss. If it's on the login then there is nothing to dismiss as it's the root view controller.
My suggestion would be to reconfigure the storyboard. Because you are manually presenting the view controllers I'm going to assume that the storyboard doesn't contain any segues between the controllers. I'd suggest adding the segues and using them.
I'd set the home view controller as the initial view controller and set the Main storyboard as the storyboard to load in the apps settings. Then all the code to load the storyboard and set the root view controller can be removed.
Next I'd make a manual modal segue from the home view controller to the login view controller. Then in the viewDidAppear of the home view controller I'd add the code to decide if a login was needed and to them perform the login segue.
Then in the login view controller you can do a dismiss and it will remove the model login view.
This is but one of many ways to do this, but it's pretty much the simplest to get you going. You don't need any code to load or set root view controllers or anything else. It just lets the storyboard do the work for you.

modalPresentationStyle .overCurrentContext causing issues with remote button presses on presented view controller

I am having an issue with using the .overCurrentContext modalPresentationStyle on a tvOS view controller:
let vc = UIStoryboard(name: "", bundle: Bundle.main).instantiateInitialViewController() //representative of actually presented VC
vc.modalPresentationStyle = .overCurrentContext
present(vc, animated: true, completion: nil)
On the presented view controller, pressing the menu button ceases to return to the presenting view controller. This also occurs when setting it to .overFullScreen and .blurOverFullScreen. However, I am having no such problem when setting it to .currentContext or .fullScreen. Is there anything particular that needs to be used when using certain UIModalPresentationStyle's?
let vc = UIStoryboard(name: "", bundle: Bundle.main).instantiateInitialViewController() //representative of actually presented VC
vc.modalPresentationStyle = .overCurrentContext
self.definesPresentationContext = true //*** adding this line should solve your issue ***
self.present(vc, animated: true, completion: nil)
So what's going on here? The definesPresentationContext property was added in iOS 8, and the documentation states the following:
When a view controller is presented, iOS starts with the presenting view controller and asks it if it wants to provide the presentation context. If the presenting view controller does not provide a context, then iOS asks the presenting view controller's parent view controller. iOS searches up through the view controller hierarchy until a view controller provides a presentation context. If no view controller offers to provide a context, the window's root view controller provides the presentation context.
If a view controller returns YES, then it provides a presentation context. The portion of the window covered by the view controller's view determines the size of the presented view controller's view. The default value for this property is NO.
By setting definesPresentationContext to YES you ensure that the controller to be presented is presented within the bounds of the original view controller.

Issue dismissing Popover presenting another ViewController

I've create a Popover segue in my project and inside a button to when it's touched open another ViewController modally. Then inside the another ViewController I've a button to dismiss the actual ViewController and the Popover too with the following code :
var tmpController :UIViewController! = self.presentingViewController;
self.dismissViewControllerAnimated(true, completion: {()->Void in
println("done");
tmpController.dismissViewControllerAnimated(true, completion: nil);
});
My problem is that when the actual ViewController is dismissed the Popover is like in FullScreen, then it resize to its original size and is dismissed after, and the resize process is animated.
What is causing this behaviour ?
How can I avoid this?
I would suggest you to dismiss the popover view controller from the parent view controller using delegation/notification.