it-swarm.com.de

Instantiieren und Präsentieren Sie einen viewController in Swift

Problem

Ich habe mir die neue Swift auf Xcode 6 angesehen und einige Demo-Projekte und Tutorials ausprobiert. Jetzt bin ich fest bei:

Instanziieren und Darstellen einer viewController aus einem bestimmten Storyboard

Ziel-C-Lösung

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"myStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"myVCID"];
[self presentViewController:vc animated:YES completion:nil];

Wie erreicht man das auf Swift?

261
EridB

Es ist alles eine Frage der neuen Syntax, die Funktionalität hat sich nicht geändert:

// Swift 3.0

let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "someViewController")
self.present(controller, animated: true, completion: nil)

Wenn Sie Probleme mit init(coder:) haben, lesen Sie bitte die Antwort von EridB .

571
akashivskyy

Für Personen, die @ akashivskyys Antwort verwenden um UIViewController zu instanziieren und die Ausnahme haben

schwerwiegender Fehler: Verwendung des unimplementierten Initialisierers 'init (coder :)' für die Klasse

Kurzer Tipp:

Implementieren Sie required init?(coder aDecoder: NSCoder) manuell an Ihrem Ziel UIViewController, das Sie instanziieren möchten

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

Wenn Sie mehr Beschreibung benötigen, beziehen Sie sich bitte auf meine Antwort hier

41
EridB

Dieser Link hat beide Implementierungen:

Schnell:

let viewController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("ViewController") as UIViewController
self.presentViewController(viewController, animated: false, completion: nil)

Ziel c

UIViewController *viewController = [[UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:@"ViewController"];

Dieser Link enthält Code zum Starten des Viewcontrollers im selben Storyboard .

/*
 Helper to Switch the View based on StoryBoard
 @param StoryBoard ID  as String
*/
func switchToViewController(identifier: String) {
    let viewController = self.storyboard?.instantiateViewControllerWithIdentifier(identifier) as! UIViewController
    self.navigationController?.setViewControllers([viewController], animated: false)

}
16
Abhijeet

akashivskyys Antwort funktioniert gut! Falls Sie jedoch Probleme haben, vom angezeigten View-Controller zurückzukehren, kann diese Alternative hilfreich sein. Es hat für mich funktioniert!

Schnell:

let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("someViewController") as! UIViewController
// Alternative way to present the new view controller
self.navigationController?.showViewController(vc, sender: nil)

Obj-C:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MyStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"someViewController"];
[self.navigationController showViewController:vc sender:nil];
11
Nahuel Roldan
// "Main" is name of .storybord file "
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
// "MiniGameView" is the ID given to the ViewController in the interfacebuilder
// MiniGameViewController is the CLASS name of the ViewController.Swift file acosiated to the ViewController
var setViewController = mainStoryboard.instantiateViewControllerWithIdentifier("MiniGameView") as MiniGameViewController
var rootViewController = self.window!.rootViewController
rootViewController?.presentViewController(setViewController, animated: false, completion: nil)

Dies funktionierte gut für mich, wenn ich es in AppDelegate stecke 

7
Maxxafari

Wenn Sie es modal präsentieren möchten, sollten Sie Folgendes haben:

let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewControllerID")
self.showDetailViewController(vc as! YourViewControllerClassName, sender: self)
6
Hamid

Schnell 4:

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let yourVC: YourVC = storyboard.instantiateViewController(withIdentifier: "YourVC") as! YourVC
3
drew..

Swift 4.2 aktualisierter Code ist

let storyboard = UIStoryboard(name: "StoryboardNameHere", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "ViewControllerNameHere")
self.present(controller, animated: true, completion: nil)
2

Wenn Sie über einen Viewcontroller verfügen, der kein Storyboard/Xib verwendet, können Sie den folgenden Aufruf an diesen VC vornehmen:

 let vcInstance : UIViewController   = yourViewController()
 self.present(vcInstance, animated: true, completion: nil)
2
Aks

Ich möchte einen viel saubereren Weg vorschlagen. Dies ist nützlich, wenn wir mehrere Storyboards haben

1.Eine Struktur mit all deinen Storyboards erstellen

struct Storyboard {
      static let main = "Main"
      static let login = "login"
      static let profile = "profile" 
      static let home = "home"
    }

2. Erstellen Sie eine UIStoryboard-Erweiterung wie diese

extension UIStoryboard {
  @nonobjc class var main: UIStoryboard {
    return UIStoryboard(name: Storyboard.main, bundle: nil)
  }
  @nonobjc class var journey: UIStoryboard {
    return UIStoryboard(name: Storyboard.login, bundle: nil)
  }
  @nonobjc class var quiz: UIStoryboard {
    return UIStoryboard(name: Storyboard.profile, bundle: nil)
  }
  @nonobjc class var home: UIStoryboard {
    return UIStoryboard(name: Storyboard.home, bundle: nil)
  }
}

Geben Sie den Storyboard-Bezeichner als Klassennamen an und verwenden Sie den folgenden Code zum Instanziieren

let loginVc = UIStoryboard.login.instantiateViewController(withIdentifier: "\(LoginViewController.self)") as! LoginViewController
2
vijeesh

Swift 3 Storyboard

let settingStoryboard : UIStoryboard = UIStoryboard(name: "SettingViewController", bundle: nil)
let settingVC = settingStoryboard.instantiateViewController(withIdentifier: "SettingViewController") as! SettingViewController
self.present(settingVC, animated: true, completion: {

})
1
Giang

Egal was ich ausprobiert habe, es würde für mich einfach nicht funktionieren - keine Fehler, aber auch kein neuer View-Controller auf meinem Bildschirm. Ich weiß nicht warum, aber durch die Timeout-Funktion konnte es endlich funktionieren:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.0) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let controller = storyboard.instantiateViewController(withIdentifier: "TabletViewController")
    self.present(controller, animated: true, completion: nil)
}
1
Starwave

Ich weiß, dass es sich um einen alten Thread handelt, aber ich denke, dass die aktuelle Lösung (die einen fest codierten String-Bezeichner für einen bestimmten View-Controller verwendet) sehr fehleranfällig ist.

Ich habe ein Erstellungszeitskript erstellt (auf das Sie hier zugreifen können ), das einen compilersicheren Weg für den Zugriff auf und die Instanziierung von Ansichtscontrollern aus allen Storyboards im angegebenen Projekt bietet.

Beispielsweise wird der View-Controller mit dem Namen vc1 in Main.storyboard instanziiert wie so:

let vc: UIViewController = R.storyboard.Main.vc1^  // where the '^' character initialize the controller
1
Nadav96

Ich habe eine Bibliothek erstellt, die dies mit einer besseren Syntax viel einfacher handhaben kann: 

https://github.com/Jasperav/Storyboardable

Ändern Sie einfach Storyboard.Swift und lassen Sie die ViewControllers mit Storyboardable übereinstimmen.

0
J. Doe