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
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?
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 .
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
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)
}
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];
// "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
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)
Schnell 4:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let yourVC: YourVC = storyboard.instantiateViewController(withIdentifier: "YourVC") as! YourVC
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)
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)
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
Swift 3
let settingStoryboard : UIStoryboard = UIStoryboard(name: "SettingViewController", bundle: nil)
let settingVC = settingStoryboard.instantiateViewController(withIdentifier: "SettingViewController") as! SettingViewController
self.present(settingVC, animated: true, completion: {
})
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)
}
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
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.