2017-10-18 9 views
2

Je voulais instancier des contrôleurs de vue à partir de notifications push, la plupart des tutoriels semblent suggérer de passer l'identifiant pour le VC et de les faire correspondre avec le storyboardID.Créer une instance de classe UIViewController à partir d'une chaîne (voir le nom de la chaîne du contrôleur) sans utiliser Storyboards ou NIB/XIB?

Problème est mon application est faite par programme et donc je ne peux pas ajouter des identifiants de storyboard.

Comment puis-je résoudre ce problème par programme afin que je puisse référencer un VC via une chaîne? Mon point est que si la notification analyse une chaîne de ce que VC à instancier, par exemple. "Deashboard" je ne peux pas charger via l'identificateur qui correspond à cette chaîne, id a besoin d'une instruction massive pour chaque possibilité qui exécute ensuite votre code dans chaque cas

+0

Avez-vous story-board (pas de connexion Segue) pour votre point de vue conception du contrôleur? – Krunal

+0

non son tout programme – jackdm

+0

"afin que je puisse référencer un VC" Et comment l'initiez-vous? Vous n'avez pas besoin d'utiliser un storyboardID, vous pouvez faire 'MyVCForPush * vc = [[MyVCForPush alloc] init]'; 'MyVCForPush * vc = [[MyVCForPush alloc] initWithXibName: @someName]', puis '[vc setPushInfo: myPushInfo]', puis le présenter. – Larme

Répondre

0

Lorsqu'un contrôleur de vue n'est pas associé à un fichier storybaord ou nib, il est (class) initiazer par défaut fournit une instance de view controller.

Essayez et Voir:

Objective-C

ViewController *viewController = [[ViewController alloc] init]; 
[self.navigationController pushViewController:viewController animated:true]; 

Swift

let viewController = ViewController() 
navigationController?.pushViewController(viewController, animated: true) 


Mise à jour
Pour convertir le nom de votre classe de chaînes en contrôleur de vue, essayez l'extension suivante.

extension NSObject { 

    func viewControllerFromString(viewControllerName: String) -> UIViewController? { 

     if let appName = Bundle.main.infoDictionary?["CFBundleName"] as? String { 
      print("CFBundleName - \(appName)") 
      if let viewControllerType = NSClassFromString("\(appName).\(viewControllerName)") as? UIViewController.Type { 
       return viewControllerType.init() 
      } 
     } 

     return nil 
    } 

} 

Maintenant, obtenez votre contrôleur de vue de la classe string

if let viewController = viewControllerFromString(viewControllerName: "ViewController") as? ViewController { 
    navigationController?.pushViewController(viewController, animated: true) 
} 

fonctionnalités similaires avec extension chaîne:

extension String { 

    func getViewController() -> UIViewController? { 

     if let appName = Bundle.main.infoDictionary?["CFBundleName"] as? String { 
      print("CFBundleName - \(appName)") 
      if let viewControllerType = NSClassFromString("\(appName).\(self)") as? UIViewController.Type { 
       return viewControllerType.init() 
      } 
     } 

     return nil 
    } 

} 


if let viewController = "ViewController".getViewController() as? ViewController { 
    navigationController?.pushViewController(viewController, animated: true) 
} 
+0

ouais c'est ce que je fais, mais mon point est que si la notification analyse une chaîne de ce que VC instancier par exemple "Deashboard" je ne peux pas charger via identifiant qui correspond à cette chaîne, id besoin d'une énorme déclaration de commutateur pour chaque possibilité qui ensuite exécute votre code dans chaque cas – jackdm

+0

Essayez avec une réponse mise à jour – Krunal

+0

@Krunal Qu'est-ce que ce CFBundleName? D'où vient-il? – ArgaPK