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?

248
demandé sur EridB 2014-06-04 15:16:57

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 .

535
répondu akashivskyy 2017-05-23 12:34:54

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

41
répondu EridB 2017-07-13 13:02:56

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)

}
14
répondu Abhijeet 2017-05-23 11:47:29

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];
10
répondu Nahuel Roldan 2016-03-07 18:29:47
// "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

6
répondu Maxxafari 2015-01-08 17:17:49

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)
5
répondu Hamid 2016-05-26 20:41:01

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)
2
répondu Aks 2017-03-14 20:19:07

Swift 4:

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let yourVC: YourVC = storyboard.instantiateViewController(withIdentifier: "YourVC") as! YourVC
2
répondu drew.. 2018-05-18 19:36:13

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
1
répondu Nadav96 2017-02-25 19:17:25

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
répondu Giang 2017-05-13 03:39:42

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)
}
1
répondu Starwave 2018-03-08 11:58:23

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
0
répondu vijeesh 2018-08-13 11:14:10