show segue from modal viewController - swift

I am trying to implement a push/show segue from a UITableViewController that is presented modally. I am able to perform a push segue from a row in the tableview, but it is delayed. I know it has something to do with the navigation hierarchy stack, and I have tried many things like resetting the rootViewController but am not having any luck...thanks for any help!
// present place tableViewController ---> modally
func handleShowPlacesVC() {
let vc = PlacesTableVC()
let navigationController = UINavigationController(rootViewController: vc)
present(navigationController, animated: true, completion: nil)
}
// show details tableViewController ---> push segue from tableview
func handleShowCurrentUserPlaceDetailsVC() {
let vc = CurrentUserPlaceDetailsVC()
navigationController?.pushViewController(vc, animated: true)
}

Related

Presenting Modal UINavigationController Changes Background of presented UIViewController

I have a current controller within a UITabBarController
I present a UINavigationController on this UITabBarController with a modal style of .overFullScreen
I then want to present modally another controller on top of this however, the background color of the second modally presented controller is grey. Even if it's set to another color it will revert to a grey color.
How do I remove this color issue?
CODE
// MARK: - WITHIN TABBARCONTROLLER
fileprivate func presentCreatePostController() {
let controller = CreatePostController()
let navigationController = UINavigationController(rootViewController: controller)
navigationController.navigationBar.configureAppearance()
navigationController.modalPresentationStyle = .overFullScreen
navigationController.navigationBar.isTranslucent = true
selectedViewController?.present(navigationController, animated: true)
}
// MARK: - WITHIN CREATEPOSTCONTROLLER
func uploadMedia() {
print("UPLOAD IMAGE BUTTON TAPPED")
PermissionManager.shared.requestPhotoLibraryPermission()
let navigationController = UINavigationController(rootViewController: ControllerProvider.mediaPickerController)
navigationController.modalPresentationStyle = .popover
navigationController.definesPresentationContext = true
let rootViewController: UIViewController = (UIApplication.shared.windows.last?.rootViewController)!
self.view.endEditing(true)
rootViewController.present(navigationController, animated: true, completion: nil)
}

Embed ViewController in NavigationController when it is already presented - swift - programmatically

Is it possible to embed a ViewController in a UINavigationController when it is already presented?
I know that to present a ViewController in a NavigationController you should initialise it before like this:
let navigationController = UINavigationController(rootViewController: viewController)
self.present(navigationController, animated: true)
But I would like to know if it is possible to present a VC:
self.present(viewController, animated: true)
and once it is presented to embed it inside a NavigationController.

Swift - resetting vc in nav controller that is embedded in tab bar

I have a customerViewController that has a simple a form. When the user presses submit, a segue is triggered and another view appears. The problem occurs when the user goes back to the customerViewController and finds all of the old information still there. I could simply reset the form fields, but what I'd really like is to find a way to reset the entire VC. From what I've learned so far, the way to reset a vc that hasn't been pushed is to remove it and then add it back.
customerViewController is the initial view controller in a navigation controller which is embedded in a tab bar controller. I have a tabBarController class that is a UITabBarControllerDelegate. This is where I call:
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if item.tag == 2 { //This is the tab with my navigation controller
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "CustomerVCID")
var viewcontrollers = self.navigationController?.viewControllers
viewcontrollers?.removeFirst()
viewControllers?.insert(vc, at: 0)
self.navigationController?.setViewControllers(viewcontrollers!, animated: true)
}
The problem with my code is that navigationController?.viewControllers is nil in the code above. I can reference viewControllers which gives me a list of tab bar viewControllers, but I'm not sure how to get from there to the navigation controller.
I guess my question is, assuming that I'm on the right track, how do I reference the view controllers in my navigation controller?
You can reset your form values in vc inside the viewWillAppear(_:),
class ViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
//clear the textfields, textviews values etc. here.
}
}
It turns out, I was over-complicating things by trying to access navigationController.viewControllers or tabBarController.viewControllers. All I needed was viewControllers which is a property of UITabBarController that contains an array of the controllers associated with each tab:
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if item.tag == 2 { //tab with navigation controller
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vcon = storyboard.instantiateViewController(withIdentifier: "CustomerVCID")
for viewcontroller in viewControllers! {
if let vc = viewcontroller as? UINavigationController {
vc.viewControllers.removeFirst()
vc.viewControllers.insert(vcon, at: 0)
vc.setViewControllers(vc.viewControllers, animated: true)
}
}
}

Navigate from a controller to another controller having a root controller between them

I have 3 controllers: RootController, FirstController and SecondController.
I want to navigate from RootController -> FirstController (here I press a button) -> Take me to SecondController.
How can I do this without Notifications and Observers and without to create a segue from that button to SecondVC because after I need to press < Back and again < Back.
This is what I've tried to do but is not working:
import UIKit
class FirstViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func goToSecondVC(_ sender: UIButton) {
// Go from first VC to second VC
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let showSecondVC = storyBoard.instantiateViewController(withIdentifier: "goSecondVC") as! SecondViewController
self.present(showSecondVC, animated:true, completion:nil)
}
}
For your code example to work your SecondViewController needs to have the Storyboard ID set to "goSecondVC". This is done in the Identity inspector in the third tab in the right pane. This will present your ViewController modally. However since you have a navigationController you most likely want to push the SecondViewController on the navigationStack like so:
navigationController?.pushViewController(secondVC, animated: true)

Swift, present a new uiview with tab bar

I am trying to present a new view after click button in a tableview cell. The view can show up but without the tab bar. Is there any solution that showing the view with tab bar? Thanks.
Storyboard Screenshot
Using segue or progammatically are not right.
func viewDetailAction(sender: UIButton){
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("patientDetailVC ") as! PatientDetailViewController
// self.presentViewController(vc, animated: true, completion: nil)
// self.navigationController?.pushViewController(vc, animated: true)
self.performSegueWithIdentifier("patientDetailCell", sender: self)
}
A easier way is to present the VC yourself
self.presentViewController(vc, animated:true, completion:nil)
This will present it on your current VC and not on the tab barController as it is being done probably in the storyboard segue
Please ignore any code syntax mistakes.
Try,
vc.modalPresentationStyle = .OverCurrentContext
after instantiateViewControllerWithIdentifier.
Edit: (using segue)
Simply, delete show segue and use Present Modally segue, click on segue, be sure Over Current Context presentation.
And then use in your action only:
self.performSegueWithIdentifier("overNewPage", sender: nil)
You can reach its properties using prepareForSegue method.
Edit: (using instantiateViewControllerWithIdentifier)
let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("patientDetailVC") as! PatientDetailViewController
viewController.modalPresentationStyle = .OverCurrentContext
viewController.someString = "youCanPassData"
self.presentViewController(viewController, animated:true, completion:nil)