56

I want to transition from ViewController to secondViewController, when the user presses a UIButton, using code only in Swift.

//Function to transition
func transition(Sender: UIButton!)
{   
    //Current Code, default colour is black
    let secondViewController:UIViewController = UIViewController()
    self.presentViewController(secondViewController, animated: true, completion: nil)

 }
12
  • 1
    Is it not working? Is it giving you an error? Have you tried self.presentViewController(...)? Commented Jun 11, 2014 at 15:39
  • I keep getting a black screen when I try change to the secondViewController, but no errors occur. Would it be the fact that I have them in two different .swift files. So the main first view Controller is in ViewController.swift and the second is in secondViewController.swift? Commented Jun 11, 2014 at 15:45
  • Show the code you actually used that's giving you the black screen. Commented Jun 11, 2014 at 15:46
  • How are you actually implementing this? The way it's written here looks like a description of the presentViewController function. Seems like this should look like self.presentViewController(self.secondViewController, true, nil) or similar. Commented Jun 11, 2014 at 15:47
  • The code I have that is giving the black screen is: self.presentViewController(secondViewController, animated: true, completion: nil) Commented Jun 11, 2014 at 15:49

9 Answers 9

68

The problem is that your code is creating a blank UIViewController, not a SecondViewController. You need to create an instance of your subclass, not a UIViewController,

func transition(Sender: UIButton!) {   
    let secondViewController:SecondViewController = SecondViewController()

    self.presentViewController(secondViewController, animated: true, completion: nil)

 }

If you've overridden init(nibName nibName: String!,bundle nibBundle: NSBundle!) in your SecondViewController class, then you need to change the code to,

let sec: SecondViewController = SecondViewController(nibName: nil, bundle: nil)
Sign up to request clarification or add additional context in comments.

5 Comments

For those using Swift 3, "presentViewController" changes to just "present." Everything else stays the same
There is a way to use this code but show the "back button" in the opened ViewController?
@JCarlos, the back button is something that comes with a NavigationController. You need to embed your views in the navigation controller's array of view controllers, and it will supply a back button for you and manage its transition.
it's self.present(,,,) now
let secondViewController = SecondViewController() isn't going to work if you have a storyboard. Use the answer below instead.
40

This worked perfectly for me:

func switchScreen() {
    let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    if let viewController = mainStoryboard.instantiateViewController(withIdentifier: "yourVcName") as? UIViewController {
        self.present(viewController, animated: true, completion: nil)
    }
}

Comments

19

SWIFT

Usually for normal transition we use,

let next:SecondViewController = SecondViewController()
self.presentViewController(next, animated: true, completion: nil)

But sometimes when using navigation controller, you might face a black screen. In that case, you need to use like,

let next:ThirdViewController = storyboard?.instantiateViewControllerWithIdentifier("ThirdViewController") as! ThirdViewController
self.navigationController?.pushViewController(next, animated: true)

Moreover none of the above solution preserves navigationbar when you call from storyboard or single xib to another xib. If you use nav bar and want to preserve it just like normal push, you have to use,

Let's say, "MyViewController" is identifier for MyViewController

let viewController = MyViewController(nibName: "MyViewController", bundle: nil)
self.navigationController?.pushViewController(viewController, animated: true)

5 Comments

Why does it go blank? And why then do we need to use that?
When the entry point on my Story Board is a simple UIViewController and I try in its viewDidLoad() to write: self.navigationController?.pushViewController(viewController, animated: true) then self.navigationController? is always nil therefore no transition happens. I would appreciate any help.
@Maxim you have to embed your initial view controller into a navigation controller. Otherwise it will always get nil. To embed, Select InitViewController -> Editor -> Embed In -> Navigation Controller.
Hi @SazzadHissainKhan what did you mean by "Moreover none of the above solution preserves navigationbar when you call from storyboard or single xib to another xib."?
Got it. I have my VC's in the Storyboard; so, a combo of your stuff worked. Mine is launched from embedded VC inside UISegmentControl: let next:VCAutoPayments = storyboard?.instantiateViewController(withIdentifier: "VCAutoPayments") as! VCAutoPayments self.present(next, animated: true, completion: nil) see stackoverflow.com/questions/51105728/…
11

Your code is just fine. The reason you're getting a black screen is because there's nothing on your second view controller.

Try something like:

secondViewController.view.backgroundColor = UIColor.redColor();

Now the view controller it shows should be red.

To actually do something with secondViewController, create a subclass of UIViewController and instead of

let secondViewController:UIViewController = UIViewController()

create an instance of your second view controller:

//If using code
let secondViewController = MyCustomViewController.alloc()

//If using storyboard, assuming you have a view controller with storyboard ID "MyCustomViewController"
let secondViewController = self.storyboard.instantiateViewControllerWithIdentifier("MyCustomViewController") as UIViewController

1 Comment

Yes, this worked, but is there a way for me to implement this code for the new ViewController in a new .swift file after the transition has occurred? So I can make UITextFields and UILabels etc in the new file?
4

For those using a second view controller with a storyboard in a .xib file, you will want to use the name of the .xib file in your constructor (without the.xib suffix).

let settings_dialog:SettingsViewController = SettingsViewController(nibName: "SettingsViewController", bundle: nil)
self.presentViewController(settings_dialog, animated: true, completion: nil)

Comments

2

For anyone doing this on iOS8, this is what I had to do:

I have a swift class file titled SettingsView.swift and a .xib file named SettingsView.xib. I run this in MasterViewController.swift (or any view controller really to open a second view controller)

@IBAction func openSettings(sender: AnyObject) {
        var mySettings: SettingsView = SettingsView(nibName: "SettingsView", bundle: nil) /<--- Notice this "nibName" 
        var modalStyle: UIModalTransitionStyle = UIModalTransitionStyle.CoverVertical
        mySettings.modalTransitionStyle = modalStyle
        self.presentViewController(mySettings, animated: true, completion: nil)

    }

Comments

2

In Swift 2.0 you can use this method:

    let registrationView = LMRegistration()
    self.presentViewController(registrationView, animated: true, completion: nil)

Comments

1

Always use nibName file otherwise your preloaded content of Xib will not show .

vc : ViewController =  ViewController(nibName: "ViewController", bundle: nil) //change this to your class name

 self.presentViewController(vc, animated: true, completion: nil)

Comments

1

Updated for Swift 3, some of these answers are a bit outdated.

let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
        let vc : UIViewController = mainStoryboard.instantiateViewController(withIdentifier: "myStoryboardID") as UIViewController
        self.present(vc, animated: true, completion: nil)    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.