Brecht Verhelst
Brecht Verhelst

Reputation: 91

Swift segue not doing what it is supposed to do

I am having a little problem with a segue in my application. When I try to push a segue so that it has a navbar it shows up correctly in the storyboard but not when I try it on my iPhone.

This is an overview of a couple of view controllers where my problem lays.

enter image description here

This is supposed to be the segue, so you can see that it has a navigation bar and is correctly positioned on the storyboard.

enter image description here

enter image description here

This is the view on the iPhone. No navigation bar or nothing. I tried everything but can't seem to find a solution to this problem.

enter image description here

Does anyone what the problem could be?

A little extra side information: I don't know if may have something to do with the problem but the navigation view controller is not always present only when the user is logged in the app. this is decided on a log in screen if the user is not logged in the user will see a normal login screen. Else it will go to navigation view controller with a view did appear function and self.present.

Here is the code that handles that action.

 // Sees if the user is logged, If yes --> go to the account detail page else go to the account view.
    override func viewDidAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if let data = UserDefaults.standard.data(forKey: "User") {
            do {
                // Create JSON Decoder
                let decoder = JSONDecoder()
                // Decode Note
                _ = try decoder.decode(User.self, from: data)
                guard let loginVC = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier:
                        "AccountDetailViewController") as? AccountDetailViewController else { return }
                loginVC.modalPresentationStyle = .overCurrentContext
                self.present(loginVC, animated: false, completion: {})
            } catch {
                print("Unable to Decode Note (\(error))")
            }
        }
    }

Upvotes: 0

Views: 153

Answers (2)

emrcftci
emrcftci

Reputation: 3514

You should push view controller instead of present. Please check this article to know more about Pushing, Popping, Presenting, & Dismissing ViewControllers


You can push AccountDetailViewController without segues. And you don't need to call performSegue(withIdentifier:) into tableView's didSelect function.

  • Remove segue from Interface Builder
let navigator = UINavigationController()

guard let loginVC = UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier:
                        "AccountDetailViewController") as? AccountDetailViewController else { return }
loginVC.modalPresentationStyle = .overCurrentContext

navigator.pushViewController(loginVC, animated: true)

Upvotes: 2

Keshu R.
Keshu R.

Reputation: 5223

After succesful login, you are presenting AccountDetailViewController without adding it in a navigation controller. I would suggest you to use these extensions that i created.

extension UIViewController {

    func pushVC(vcName : String) {
        let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: vcName)
        vc.hidesBottomBarWhenPushed = true
        self.navigationController?.pushViewController(vc, animated: true)
    }


    func pushVC(storyboardName : String, vcName : String)  {
        let vc = UIStoryboard.init(name: storyboardName, bundle: Bundle.main).instantiateViewController(withIdentifier: vcName)
        vc.hidesBottomBarWhenPushed = true
        self.navigationController?.pushViewController(vc, animated: true)
    }

    func popVC() {
        self.navigationController?.popViewController(animated: true)
    }

    func makeRootVC(storyBoardName : String, vcName : String) {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
         let vc = UIStoryboard(name: storyBoardName, bundle: Bundle.main).instantiateViewController(withIdentifier: vcName)
         let nav = UINavigationController(rootViewController: vc)
         nav.navigationBar.isHidden = true
         appDelegate.window?.rootViewController = nav // If using XCode 11 and above, copy var window : UIWindow? in your appDelegate file
         let options: UIView.AnimationOptions = .transitionCrossDissolve
         let duration: TimeInterval = 0.6
         UIView.transition(with: appDelegate.window!, duration: duration, options: options, animations: {}, completion: nil)
     }
}

Now in your case, when a user logs in, you should change your root view controller to AccountDetailViewController. So first, copy paste the above extension anywhere in your file and then use it like this:

 // Sees if the user is logged, If yes --> go to the account detail page else go to the account view.
    override func viewDidAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if let data = UserDefaults.standard.data(forKey: "User") {
            do {
                // Create JSON Decoder
                let decoder = JSONDecoder()
                // Decode Note
                _ = try decoder.decode(User.self, from: data)
                self.makeRootVC(storyBoardName : "Main", vcName :"AccountDetailViewController")
            } catch {
                print("Unable to Decode Note (\(error))")
            }
        }
    }

Upvotes: 1

Related Questions