instantiated view controller displays for 1 second then segues to next view controller for no reason

I'm having an issue when it comes to instantiating a view controller and actually having it stay on the screen without automatically jumping to the next view controller. I setup a view controller sort of identical to another view controller I have in my project, but the class names are completely different obviously.

Now I want to instantiate this view controller when a user finishes signing up. So I do that in this block of code:

Code Block {
      //Create user
      Auth.auth().createUser(withEmail: schoolEmail, password: schoolPassword) { (result, error) in
         
        guard error == nil else {
          self.showAlert(title: "Error Signing Up", message: "There was an error creating the user, please check your connection and try again later.")
          return
        }
          let db = Firestore.firestore()
          guard let result = result else { return }
          db.document("school_users/\(result.user.uid)").setData(["school_name":schoolName,
                                       "school_id":schoolID,
                                       "remindersPushNotificationsOn": true,
                                       "updatesPushNotificationsOn": true,
                                       "schoolDistrict":schoolDistrict,
                                       "time_created":dateCreated,
                                       "userID": result.user.uid],
                                       merge: true) { (error) in
            guard error == nil else {
              self.showAlert(title: "Error Signing Up", message: "There was an error creating the user, please check your connection and try again later.")
              return
            }
          }
           
          let changeRequest = result.user.createProfileChangeRequest()
          changeRequest.displayName = schoolName
          changeRequest.commitChanges { (error) in
            guard error == nil else {
              return
            }
            print("School Name Saved!")
          }
           
         
      }
      guard let nextVC = storyboard?.instantiateViewController(withIdentifier: Constants.StoryboardIDs.SchoolOnboarding) as? SchoolSignUpOnboardingViewController else { return }
      navigationController?.pushViewController(nextVC, animated: true)
    }


This works, but to an extent. When I finish signing up, the view controller is displayed for literally a split second with the proper UI and everything and it then automatically segues to the next view controller which makes no sense. This has never happened to me with segues before and I can't understand why it's happening now.

I used TestFlight with my friends last night and for some reason bits of my code just completely turned it's back on me when I was trying to test certain functionalities. I wanted to also add a new addition which was this view controller I want to instantiate but now this addition to the app won't even work properly. So with this in mind, I was wondering if it's an issue with the TestFlight and the app's build number, so I incremented the build number and tried to run the app on the simulator again, but it still didn't keep the view controller on the screen and just kept jumping to the next view controller automatically.

This is so frustrating because I genuinely can't figure out what the cause of this view controller issue is. Any suggestions?
Please be more precise.

the view controller is displayed for literally a split second with the proper UI and everything

Which controller ?
nextVC (SchoolOnboarding) ?
Another ?

and it then automatically segues to the next view controller 

Which segue ?
To which controller ?
Line 36 you push (not segue). Is it the transition you speak about ?

Please also report all the prints you get on the console when you authenticate.

This has never happened to me with segues before and I can't understand why it's happening now. 

Because you have an error in your code !

 I wanted to also add a new addition which was this view controller I want to instantiate but now this addition to the app won't even work properly.

Please explain, it is totally unclear.

So with this in mind, I was wondering if it's an issue with the TestFlight and the app's build number, so I incremented the build number and tried to run the app on the simulator 

No link with build number.
Ok i'll try my best to re-explain, the "nextVC" (aka the correct vc) shows up for a split second with all the UI and everything meaning the view controller instantiation was successful but then it automatically segues to the DashboardVC (the vc I want users to goto after nextVC). I am aware I push the nextVC, I didn't mean to say segue, but when that vc loads for a split second you don't even have time to interact with it, it automatically segues to the DashboardVC.

Here is what prints in the console when I finish authenticating:

Code Block
ocean@gmail.com
School Name Saved!
Algolia Search Client Swift: Default minimal log severity level is info. Change Logger.minLogServerityLevel value if you want to change it.
2021-04-19T14:03:59-0400 info com.algolia.InstantSearchCore : Default minimal log severity level is info. Change Logger.InstantSearchCore.minLogSeverityLevel value if you want to change it.
Permission granted: true
Notification settings: <UNNotificationSettings: 0x13332fed0; authorizationStatus: Authorized, notificationCenterSetting: Enabled, soundSetting: Enabled, badgeSetting: Enabled, lockScreenSetting: Enabled, carPlaySetting: NotSupported, announcementSetting: NotSupported, criticalAlertSetting: NotSupported, alertSetting: Enabled, alertStyle: Banner, groupingSetting: Default providesAppNotificationSettings: No>
2021-04-19 14:03:59.080697-0400 Gothere[20652:174544] 7.5.0 - [Firebase/Messaging][I-FCM012002] Error in application:didFailToRegisterForRemoteNotificationsWithError: remote notifications are not supported in the simulator
Failed to register: Error Domain=NSCocoaErrorDomain Code=3010 "remote notifications are not supported in the simulator" UserInfo={NSLocalizedDescription=remote notifications are not supported in the simulator}
Subbed to Invoices
Subbed to GothereUpdates.


Also when the nextVC loads for that split second, it isn't displaying the "rightBarButtonItem" that I added into the UI Setup. Here is the code for the nextVC UI as well:

Code Block  func setupUI() {
    let navbar = navigationController?.navigationBar
    let appearance = UINavigationBarAppearance()
    appearance.backgroundColor = colorLiteral(red: 0.3084011078, green: 0.5618229508, blue: 0, alpha: 1)
    appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont(name: Constants.AppFonts.menuTitleFont, size: 22) ?? UIFont.boldSystemFont(ofSize:22)]
    appearance.shadowColor = .clear
    navbar?.standardAppearance = appearance
    navbar?.compactAppearance = appearance
    navbar?.scrollEdgeAppearance = appearance
    navbar?.prefersLargeTitles = false
    navigationItem.setHidesBackButton(true, animated: true)
    navigationItem.title = "How Gothere Works"
    navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "xmark"), style: .done, target: self, action: #selector(closeTapped))
    navigationItem.leftBarButtonItem?.tintColor = .white
    navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "chevron.right.2"), style: .done, target: self, action: #selector(gotoAddAnEventPage))
    navigationItem.rightBarButtonItem?.tintColor = .white
     
  }
   
  @objc func closeTapped() {
    performSegue(withIdentifier: Constants.Segues.fromSchoolOnboardingToSchoolEvents, sender: self)
  }
   
  @objc func gotoAddAnEventPage() {
    performSegue(withIdentifier: Constants.Segues.fromSchoolOnboardingToSchoolAddAnEvent, sender: self)
  }

The new addition is the nextVC, that's what I meant by the new addition, I added it this morning to the project but it seems to be screwing everything up. In regards to TestFlight, this isn't related, the simulator and the builds on TestFlight are two different things, the goal is to just get this to work on the simulator, once I know it works on the simulator I can upload it to TestFlight. Hopefully this clears things up.

@Claude31

What I would need is you explain
  • all the viewControllers involved, with their names

VC1 ---> VC 2 ---> VC3
  • show the code of each.

  • how you try to transition from one to the next (button with segue, instantiate… ). Tell where in code this transition is defined.

  • Which transition does not work as expected.


Ok cool, so the first View Controller is the SchoolSignUpViewController, this where a school user signs up, when they are done, they press the sign up button and I want them to see the SchoolSignUpOnboardingViewController aka nextVC via instantiation.

Here is the function for that desired action I want:

Code Block  @IBAction func signupPressed(_ sender: UIButton) {
    let validationError = validateFields()
    let schoolName = schoolNameTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    let schoolEmail = schoolEmailTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    let schoolPassword = schoolPasswordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    let schoolID = schoolIDTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    let schoolDistrict = schoolDistrictTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    let dateCreated = Date()
     
    if validationError != nil {
      return
    } else {
      //Create user
      Auth.auth().createUser(withEmail: schoolEmail, password: schoolPassword) { (result, error) in
         
        guard error == nil else {
          self.showAlert(title: "Error Signing Up", message: "There was an error creating the user, please check your connection and try again later.")
          return
        }
          let db = Firestore.firestore()
          guard let result = result else { return }
          db.document("school_users/\(result.user.uid)").setData(["school_name":schoolName,
                                       "school_id":schoolID,
                                       "remindersPushNotificationsOn": true,
                                       "updatesPushNotificationsOn": true,
                                       "schoolDistrict":schoolDistrict,
                                       "time_created":dateCreated,
                                       "userID": result.user.uid],
                                       merge: true) { (error) in
            guard error == nil else {
              self.showAlert(title: "Error Signing Up", message: "There was an error creating the user, please check your connection and try again later.")
              return
            }
          }
           
          let changeRequest = result.user.createProfileChangeRequest()
          changeRequest.displayName = schoolName
          changeRequest.commitChanges { (error) in
            guard error == nil else {
              return
            }
            print("School Name Saved!")
          }
           
         
      }
      guard let nextVC = storyboard?.instantiateViewController(withIdentifier: Constants.StoryboardIDs.SchoolOnboarding) as? SchoolSignUpOnboardingViewController else { return }
      navigationController?.pushViewController(nextVC, animated: true)
    }
  }
   

when this is called, this is where the transition from SchoolSignUpVC to SchoolSignUpOnboardingVC is supposed to happen. Instead, what ends up happening is the SchoolSignUpOnboardingVC shows up for literally a split second on screen, and then it vanishes and segues to the SchoolDashboardTableVC.

The transition that does not work as expected is the sign up button, it instantiates the correct view controller yes, but it does for one second and doesn't even allow the user to interact with the screen.

Here is the full code for the SchoolSignUpOnboardingVC :

Code Block
extension SchoolSignUpOnboardingViewController: PaperOnboardingDataSource {
   
  func onboardingItem(at index: Int) -> OnboardingItemInfo {
    let next = (UIImage(systemName: "chevron.right.circle")?.mask(with: .white))!
    let titleFont = UIFont(name: Constants.AppFonts.menuTitleFont, size: 20) ?? UIFont.boldSystemFont(ofSize: 20)
    let descripFont = UIFont(name: Constants.AppFonts.consistentFont, size: 17) ?? UIFont.boldSystemFont(ofSize: 17)
     
    ... way too much code for answer
  }
   
  func onboardingItemsCount() -> Int {
    return 7
  }
   
   
  func setupUI() {
    let navbar = navigationController?.navigationBar
    let appearance = UINavigationBarAppearance()
    appearance.backgroundColor = colorLiteral(red: 0.3084011078, green: 0.5618229508, blue: 0, alpha: 1)
    appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont(name: Constants.AppFonts.menuTitleFont, size: 22) ?? UIFont.boldSystemFont(ofSize:22)]
    appearance.shadowColor = .clear
    navbar?.standardAppearance = appearance
    navbar?.compactAppearance = appearance
    navbar?.scrollEdgeAppearance = appearance
    navbar?.prefersLargeTitles = false
    navigationItem.setHidesBackButton(true, animated: true)
    navigationItem.title = "How Gothere Works"
    navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "chevron.right.2"), style: .done, target: self, action: #selector(gotoAddAnEventPage))
    navigationItem.rightBarButtonItem?.tintColor = .white
     
  }
   
   
  @objc func gotoAddAnEventPage() {
    performSegue(withIdentifier: Constants.Segues.fromSchoolOnboardingToSchoolAddAnEvent, sender: self)
  }
   
}


And then in the actual View Controller file:

Code Block class SchoolSignUpOnboardingViewController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    setupUI()
    let onboarding = PaperOnboarding()
    onboarding.dataSource = self
    onboarding.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(onboarding)
    
    for attribute: NSLayoutConstraint.Attribute in [.left, .right, .top, .bottom] {
     let constraint = NSLayoutConstraint(item: onboarding,
                       attribute: attribute,
                       relatedBy: .equal,
                       toItem: view,
                       attribute: attribute,
                       multiplier: 1,
                       constant: 0)
     view.addConstraint(constraint)
    }
  }
   
}


The SchoolDashboardVC has way too many lines of code to post in this thread it wouldn't make sense, the main issue is the transition from SchoolSignUpVC to the SchoolSignUpOnboardingVC.

The Transition should be : SchoolSignUpVC - > SchoolSignUpOnboardingVC -> SchoolDashboardTableVC
instead it's like : SchoolSignUpVC - > SchoolSignUpOnboardingVC (for 1 split second) -> SchoolDashboardTableVC.

@Claude31

By any chance, is PaperOnboardingDataSource a Navigation Controller ?

If so, you do not open it but its RootViewController, probably SchoolDashboardTableVC.
it's a protocol, not a navigation controller @Claude31
OK, so the same question for SchoolSignUpOnboardingViewController.

Can you show its declaration ?
I showed you the whole class what do you mean it's declaration? @Claude31
Sorry, I cannot find the class declaration of SchoolSignUpOnboardingViewController. I just see its extension to the protocol.

Another question:

The Transition should be : SchoolSignUpVC - > SchoolSignUpOnboardingVC -> SchoolDashboardTableVC
instead it's like : SchoolSignUpVC - > SchoolSignUpOnboardingVC (for 1 split second) -> SchoolDashboardTableVC.

What is the type of connection between SchoolSignUpOnboardingVC -> SchoolDashboardTableVC
What triggers it ?
The class declaration:


Code Block
import UIKit
import PaperOnboarding
class SchoolSignUpOnboardingViewController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    setupUI()
    let onboarding = PaperOnboarding()
    onboarding.dataSource = self
    onboarding.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(onboarding)
    // add constraints
    for attribute: NSLayoutConstraint.Attribute in [.left, .right, .top, .bottom] {
     let constraint = NSLayoutConstraint(item: onboarding,
                       attribute: attribute,
                       relatedBy: .equal,
                       toItem: view,
                       attribute: attribute,
                       multiplier: 1,
                       constant: 0)
     view.addConstraint(constraint)
    }
  }
   
}




Also, it is a segue connection that connects SchoolSignUpOnboardingVC -> SchoolDashboardTableVC and it is triggered by a bar button item.

@Claude31
What happens if you remove the segue from the bar button item ? Does it continue to automatically segue ?
Yes, and even if I completely delete the segue from the storyboard, it still continues to automatically segue. @Claude31
Can you create and share a simplified project which can reproduce the issue?
In storyboard, select
  • SchoolSignUpOnboardingVC

And look at Connection inspector.
What do you see (please list all)

Do the same for
  • SchoolDashboardTableVC

Also search in WHOLE code where you reference SchoolDashboardTableVC. You have most likely a connection somewhere or a call to this VC.
instantiated view controller displays for 1 second then segues to next view controller for no reason
 
 
Q