Instanciez et présentez un viewController dans Swift
Problème
j'ai commencé à regarder le nouveau Swift
sur Xcode 6
, et j'ai essayé quelques projets de démonstration et des tutoriels. Maintenant je suis coincé à:
Instanciation et puis la présentation d'un viewController
à partir d'un storyboard
Objective-C Solution
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"myStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"myVCID"];
[self presentViewController:vc animated:YES completion:nil];
comment y parvenir sur Swift?
12 réponses
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 avez des problèmes avec init(coder:)
, veuillez vous référer à réponse D'EridB .
pour les personnes qui utilisent la réponse de @akashivskyy instantiate UIViewController
et ont l'exception:
erreur fatale: l'utilisation de mises au placard de l'initialiseur 'init(coder:)" pour la classe
astuce:
implémenter manuellement required init?(coder aDecoder: NSCoder)
à 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:
Swift:
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 a le code pour lancer viewcontroller dans le même 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)
}
la réponse d'akashivskyy fonctionne très bien! Mais, dans le cas où vous avez quelques difficultés à revenir du contrôleur de vue présenté, cette alternative peut être utile. Il a travaillé pour moi!
Swift:
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 modalement, vous devriez avoir quelque chose comme ci-dessous:
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewControllerID")
self.showDetailViewController(vc as! YourViewControllerClassName, sender: self)
si vous avez un Viewcontroller n'utilisant pas de storyboard/Xib, vous pouvez appuyer sur cette VC particulière comme ci-dessous appel:
let vcInstance : UIViewController = yourViewController()
self.present(vcInstance, animated: true, completion: nil)
Swift 4:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let yourVC: YourVC = storyboard.instantiateViewController(withIdentifier: "YourVC") as! YourVC
je sais que c'est un vieux thread, mais je pense que la solution actuelle (en utilisant un identifiant de chaîne de caractères codé en dur pour un contrôleur de vue donné) est très sujette aux erreurs.
j'ai créé un script de temps de construction (auquel vous pouvez accéder ici ), qui créera un moyen sûr de compiler pour accéder et instancier les contrôleurs de vue de tous les storyboards dans le projet donné.
par exemple, contrôleur de vue nommé vc1 dans Principal.storyboard sera instancié comme suit:
let vc: UIViewController = R.storyboard.Main.vc1^ // where the '^' character initialize the controller
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é, ça ne marcherait pas pour moi - pas d'erreurs, mais pas de nouveau contrôleur de vue sur mon écran non plus. Je ne sais pas pourquoi, mais le fait de l'emballer dans la fonction timeout 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 voudrais suggérer une beaucoup plus propre. Cela sera utile lorsque nous aurons plusieurs storyboards
1.Créez une structure avec tous vos storyboards
struct Storyboard {
static let main = "Main"
static let journey = "login"
static let journey = "profile"
static let journey = "home"
}
2. Créer une extension UIStoryboard comme ceci
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)
}
}
donne l'identifiant du storyboard comme nom de classe, et utilise le code ci-dessous pour instancier
let loginVc = UIStoryboard.login.instantiateViewController(withIdentifier: "\(LoginViewController.self)") as! LoginViewController