J'ai commencé à regarder la nouvelle Swift
sur Xcode 6
et j'ai essayé des projets de démonstration et des tutoriels. Maintenant je suis coincé à:
Instanciation puis présentation d'une viewController
à partir d'un storyboard spécifique
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"myStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"myVCID"];
[self presentViewController:vc animated:YES completion:nil];
Comment y parvenir sur Swift?
Tout est une question de nouvelle syntaxe, la fonctionnalité n'a pas changé:
// Swift 3.0
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "someViewController")
self.present(controller, animated: true, completion: nil)
Si vous rencontrez des problèmes avec init(coder:)
, veuillez vous référer à La réponse d'EridB .
Pour les personnes qui utilisent @ akashivskyy answer pour instancier UIViewController
et qui ont l'exception:
erreur fatale: utilisation d'initialiseur non implémenté 'init (codeur :)' pour la classe
Conseil rapide:
Implémentez manuellement required init?(coder aDecoder: NSCoder)
sur votre destination UIViewController
que vous essayez d'instancier
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
Si vous avez besoin de plus de description s'il vous plaît se référer à ma réponse ici
Ce lien a les deux implémentations:
Rapide:
let viewController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("ViewController") as UIViewController
self.presentViewController(viewController, animated: false, completion: nil)
Objectif c
UIViewController *viewController = [[UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:@"ViewController"];
Ce lien contient du code permettant d'initier viewcontroller dans le même scénario
/*
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)
}
la réponse d'akashivskyy fonctionne très bien! Toutefois, si vous rencontrez des difficultés pour revenir du contrôleur de vue présenté, cette alternative peut être utile. Cela a fonctionné pour moi!
Rapide:
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)
Cela a bien fonctionné pour moi quand je l'ai mis dans AppDelegate
Si vous voulez le présenter de manière modale, vous devriez avoir quelque chose comme ci-dessous:
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewControllerID")
self.showDetailViewController(vc as! YourViewControllerClassName, sender: self)
Swift 4:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let yourVC: YourVC = storyboard.instantiateViewController(withIdentifier: "YourVC") as! YourVC
Swift 4.2 mis à jour le code est
let storyboard = UIStoryboard(name: "StoryboardNameHere", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "ViewControllerNameHere")
self.present(controller, animated: true, completion: nil)
Si vous avez un Viewcontroller n'utilisant pas de storyboard/Xib, vous pouvez pousser vers ce VC particulier comme ci-dessous:
let vcInstance : UIViewController = yourViewController()
self.present(vcInstance, animated: true, completion: nil)
Je voudrais suggérer une manière beaucoup plus propre. Cela sera utile lorsque nous avons plusieurs story-boards
1.Créez une structure avec tous vos story-boards
struct Storyboard {
static let main = "Main"
static let login = "login"
static let profile = "profile"
static let home = "home"
}
2. Créez une extension UIStoryboard comme celle-ci
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)
}
}
Indiquez l'identifiant du storyboard comme nom de classe et utilisez le code ci-dessous pour instancier
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: {
})
Peu importe ce que j'ai essayé, cela ne fonctionnerait tout simplement pas pour moi - pas d'erreur, mais pas de nouveau contrôleur de vue sur mon écran. Je ne sais pas pourquoi, mais l'envelopper dans la fonction de délai d'attente l'a finalement fait fonctionner:
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)
}
Je sais que c'est un ancien fil de discussion, mais je pense que la solution actuelle (utilisant l'identifiant de chaîne codé en dur pour un contrôleur de vue donné) est très sujette aux erreurs.
J'ai créé un script de génération (auquel vous pouvez accéder ici ), qui créera un moyen sûr pour le compilateur d'accéder et d'instancier les contrôleurs de vue de tous les story-boards d'un projet donné.
Par exemple, le contrôleur de vue nommé vc1 dans Main.storyboard sera instancié de la manière suivante:
let vc: UIViewController = R.storyboard.Main.vc1^ // where the '^' character initialize the controller
J'ai créé une bibliothèque qui va gérer cela beaucoup plus facilement avec une meilleure syntaxe:
https://github.com/Jasperav/Storyboardable
Il suffit de changer Storyboard.Swift et de laisser le ViewControllers
se conformer à Storyboardable
.