Wie kann ich ein Storyboard programmgesteuert aus dem Unterricht laden?

183

Mein Problem ist, dass ich nach einer Möglichkeit gesucht habe, sowohl Storyboard als auch xib zu verwenden . Aber ich kann keinen richtigen Weg finden, um das Storyboard programmgesteuert zu laden und anzuzeigen. Das Projekt wurde mit der Entwicklung von xib gestartet, und jetzt ist es sehr schwierig, alle xib-Dateien im Storyboard zu verschachteln. Also suchte ich nach einer Möglichkeit, dies im Code zu tun, wie bei alloc, init, pushviewControllers. In meinem Fall habe ich nur einen Controller im Storyboard: UITableViewControllermit statischen Zellen mit einigen Inhalten, die ich anzeigen möchte. Wenn jemand weiß, wie man mit xib und Storyboard ohne großes Refactoring richtig arbeitet, werde ich mich über jede Hilfe freuen.

Kokoko
quelle

Antworten:

370

Gehen Sie in Ihrem Storyboard zum Attributinspektor und legen Sie die Kennung des Ansichtscontrollers fest. Sie können diesen View Controller dann mit dem folgenden Code präsentieren.

UIStoryboard *sb = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:@"myViewController"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];
James Beith
quelle
65
[sb instantiateInitialViewController]ist praktisch, wenn Sie mit dem Standard-Ansichts-Controller der Szene beginnen möchten.
Zeichnen
James, danke! Ich habe lange gesucht, um herauszufinden, wie man die Ansicht eines Storyboards instanziiert. Ihre Antwort (und Kokokos Frage) ist am erfrischendsten zu finden.
Bejonbee
In James Beiths Code muss dieser UIViewControler * vc wiederverwendet werden, wenn er mit dem aktuellen Viewcontroller hin und her geschaltet wird. Ich habe herausgefunden, wie schwierig es ist, dass der VC herumsteht und mit der Storyboard-Feder verbunden ist, bis der Benutzer eine Taste in der neuen Ansicht drückt, und es gibt jetzt einen Speicherverlust mit diesem verworfenen VC aus den vorherigen Beschwörungsformeln dieses Codes.
SWoo
11
Falls jemand wissen möchte, wie dies im App-Delegaten zu tun ist, ersetzen Sie die [self presentViewcontroller]Logik durch diese Zeilen in der folgenden Reihenfolge: 1) self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];2) self.window.rootViewController = vc;und 3) [self.window makeKeyAndVisible];. Sie können die modalTransitionStyleLeitung wahrscheinlich auch entfernen , da dies kein modaler Übergang vom App-Delegaten ist.
Lewiguez
Zu Ihrer Information, wenn Sie das neue Storyboard "pushen" möchten, anstatt modal aufzutauchen, schauen Sie sich die Antwort von chaithraVeeresh an.
Adam Johns
76

Swift 3

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "viewController")
self.navigationController!.pushViewController(vc, animated: true)

Swift 2

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("viewController")
self.navigationController!.pushViewController(vc, animated: true)

Voraussetzung

Weisen Sie Ihrem View Controller eine Storyboard-ID zu.

Storyboard-ID

IB> Identitätsinspektor anzeigen> Identität> Storyboard-ID

Swift (Vermächtnis)

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("viewController") as? UIViewController
self.navigationController!.pushViewController(vc!, animated: true)

Edit: Swift 2 in einem Kommentar von Fred A. vorgeschlagen.

Wenn Sie ohne Navigationscontroller verwenden möchten, müssen Sie Folgendes verwenden:

    let Storyboard  = UIStoryboard(name: "Main", bundle: nil)
    let vc = Storyboard.instantiateViewController(withIdentifier: "viewController")
    present(vc , animated: true , completion: nil)
SwiftArchitect
quelle
1
In Swift 2 müssen Sie nicht "als? UIViewController" hinzufügen, der Compiler bestimmt es automatisch
Frédéric Adda
2
oder Sie können einfach self.storyboardLinie 1 & 2
Honey
17

Geben Sie im Attributinspektor die Kennung für diesen Ansichts-Controller an, und der folgende Code funktioniert für mich

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
DetailViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:@"DetailViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];
chaithraVeeresh
quelle
5

Versuche dies

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:@"Login"];

[[UIApplication sharedApplication].keyWindow setRootViewController:vc];
Adetiloye Philip Kehinde
quelle
Verwenden Sie diese Option, wenn Sie keinen UINavigationController verwenden, wie in anderen Antworten gezeigt
Latenitecoder
2

In Swift
NavigationController und PushController können Sie ersetzen

present(vc, animated:true , completion: nil)
Tarik
quelle
1

Für Swift 3 und 4 können Sie dies tun. Es wird empfohlen, den Namen des Storyboards gleich StoryboardID zu setzen.

enum StoryBoardName{
   case second = "SecondViewController"
}
extension UIStoryBoard{
   class func load(_ storyboard: StoryBoardName) -> UIViewController{
      return UIStoryboard(name: storyboard.rawValue, bundle: nil).instantiateViewController(withIdentifier: storyboard.rawValue)
   }
}

und dann können Sie Ihr Storyboard wie folgt in Ihren ViewController laden:

class MyViewController: UIViewController{
     override func viewDidLoad() {
        super.viewDidLoad()
        guard let vc = UIStoryboard.load(.second) as? SecondViewController else {return}
        self.present(vc, animated: true, completion: nil)
     }

}}

Wenn Sie ein neues Storyboard erstellen, setzen Sie einfach den gleichen Namen auf StoryboardID und fügen Sie den Storyboard-Namen in Ihre Aufzählung " StoryBoardName " ein.

Gandhi Mena
quelle
0

Sie können jederzeit direkt zum Root-Controller springen:

UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateInitialViewController];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];
user938797
quelle
0

Mit der folgenden Erweiterung können Sie a Storyboardund die zugehörige Erweiterung laden UIViewController. Beispiel: Wenn Sie ein UIViewControllerbenanntes ModalAlertViewControllerund ein Storyboard mit dem Namen "ModalAlert" haben, z

let vc: ModalAlertViewController = UIViewController.loadStoryboard("ModalAlert")

Lädt sowohl das als Storyboardund UIViewControllerund vcist vom Typ ModalAlertViewController. Hinweis Angenommen, die Storyboard-ID des Storyboards hat denselben Namen wie das Storyboard und das Storyboard wurde als Is Initial View Controller markiert .

extension UIViewController {
    /// Loads a `UIViewController` of type `T` with storyboard. Assumes that the storyboards Storyboard ID has the same name as the storyboard and that the storyboard has been marked as Is Initial View Controller.
    /// - Parameter storyboardName: Name of the storyboard without .xib/nib suffix.
    static func loadStoryboard<T: UIViewController>(_ storyboardName: String) -> T? {
        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        if let vc = storyboard.instantiateViewController(withIdentifier: storyboardName) as? T {
            vc.loadViewIfNeeded() // ensures vc.view is loaded before returning
            return vc
        }
        return nil
    }
}
normannisch
quelle