2

I have a nifty project I downloaded from GitHub (here) and I am playing around with it. The project has no storyboard or xibs whatsoever, and only one viewController, which is defined with just a viewController.h file and a viewController.m file.

Perhaps a noob question, but can I have viewController1.h/m programmatically segue to viewController2.h/m without using ANY xibs or storyboards? I found a lot of code on SO and elsewhere allowing one to segue programmatically from one view to another within a Storyboard, from one xib to another or from a scoreboard to a xib (though not the opposite) but nothing on how to segue from one totally code-based vc to another. All the code I found requires that you define the view in terms of the bundle location of the storyboard or xib file, but I want to use neither.

Note: I accepted the answer I did because of its ingenuity/interesting-ness, but for the sake of simplicity I personally ended up opting with this answer to the same question (mine was a duplicate it appears): iOS: present view controller programmaticallly

Community
  • 1
  • 1
Max von Hippel
  • 2,856
  • 3
  • 29
  • 46
  • "but can I have viewController1.h/m programmatically segue to viewController2.h/m without using ANY xibs or storyboards" -- this makes no sense. A segue is a storyboard creature, you can't have a segue without a storyboard. You can move from one controller to another in code, but that is not a segue. – rdelmar May 12 '15 at 00:32
  • @rdelmar ok clearly I am using the wrong term when I say "segue." I just mean I want to create views programmatically and then switch views programmatically. That's the essence of my question. – Max von Hippel May 14 '15 at 21:12

2 Answers2

3

You can use [viewController presentViewController:anotherController animated:YES completion:nil]; to present the view controller modally.

Another alternative is to use a UINavigationController and do [viewController.navigationController pushViewController:anotherController animated:YES];

The second method will only work if viewController is in the stack of a navigationController

EmilioPelaez
  • 18,758
  • 6
  • 46
  • 50
  • OK, I looked into this and my impression is that I still need a storyboard, just no segues. Can I do it without any storyboard at all? (where I got my impression that I need a storyboard): http://stackoverflow.com/questions/10522957/call-storyboard-scene-programmatically-without-needing-segue/10523076#10523076 – Max von Hippel May 14 '15 at 21:24
  • @MaxvonHippel As long as you have a reference to a view controller (it doesn't matter how you create it, either from a Storyboard or by instantiating the view controller "manually"), you can present them. So yeah, you can do it without a Storyboard, and it's a lot simpler than the answer you accepted. – EmilioPelaez May 15 '15 at 02:39
  • You're right, I tried your answer and pretty easily got it to work. Thanks. I feel kind of dumb for not understanding your very simple answer to begin with but I guess that's just what SO is for :) – Max von Hippel May 15 '15 at 03:13
  • (to clarify, your code didn't work for me at first because of a mistake I made- I deleted a xib file and didn't product->clean so it kept crashing looking for the view and I thought your code was responsible) – Max von Hippel May 15 '15 at 03:14
1

Here is my Context class which changes view controllers. It works with either your own view classes or storyboard view classes.

Specific to your question look at the open function. If there is no root controller when I call open, I assign it as the root view controller. Otherwise I present it from the root view controller.

import Foundation
import UIKit

private let _StoryBoard = UIStoryboard(name: "Main", bundle: nil)
private let _RootWindow = UIWindow(frame: UIScreen.mainScreen().bounds)
public var ROOT_VIEW_CONTROLLER:UIViewController = C_RootViewController()


//abstract base of context classes
class Context:NSObject
{
    class var STORYBOARD:UIStoryboard
    {
        return _StoryBoard
    }

    class var ROOTWINDOW:UIWindow
    {
        return _RootWindow
    }

    var _currentController:Controller!

    class func reassignRootViewController(controller:UIViewController)
    {
        Context.ROOTWINDOW.rootViewController = controller
        ROOT_VIEW_CONTROLLER = controller
    }

    func initController(controllerName:String)->Controller
    {
        return Context.STORYBOARD.instantiateViewControllerWithIdentifier(controllerName) as Controller
    }

    func initControllerFromStoryboard(storyboardName:String,controllerName:String)->Controller
    {
        var storyboard:UIStoryboard = UIStoryboard(name: storyboardName, bundle: nil)
        return storyboard.instantiateViewControllerWithIdentifier(controllerName) as Controller
    }

    func open(controller:UIViewController)
    {
        if(Context.ROOTWINDOW.rootViewController == nil)
        {
            Context.ROOTWINDOW.rootViewController = ROOT_VIEW_CONTROLLER
            Context.ROOTWINDOW.makeKeyAndVisible()
        }

        ROOT_VIEW_CONTROLLER.presentViewController(controller, animated: true, completion: {})
    }

    func close(controller:UIViewController)
    {
        ROOT_VIEW_CONTROLLER.dismissViewControllerAnimated(true, completion: nil)
    }
}
Aggressor
  • 13,323
  • 24
  • 103
  • 182
  • it seems your answer relies on Storyboards existing in the bundle, but my question was if I could switch views programmatically AND without any storyboard(s), empty or otherwise. Thanks though! – Max von Hippel May 14 '15 at 21:15
  • As I said, this handles BOTH Storyboards and Non-StoryBoards. Read it again. My projects dont use Xibs or Storyboards anymore. If you don't know how to instantiate a ViewController thats a whole other question. – Aggressor May 14 '15 at 21:24
  • OK, I understand now. I was too hung up on the word "storyboard" being in your code. I re-read the code and it makes sense to me now. Thanks! – Max von Hippel May 14 '15 at 21:26