Utiliser Swift 1.1 et Xcode 6.2.
J'ai un tableau UIStory contenant une sous-classe singulière et personnalisée UIViewController
. Sur celui-ci, j'ai une connexion @IBOutlet
de type UIView
depuis ce contrôleur vers une UIView
sous-classe sur le storyboard. J'ai également des sorties similaires pour les sous-vues de cette vue. Voir la figure A.
Mais au moment de l'exécution, ces propriétés sont nulles (figure B). Même si j'ai la certitude d'avoir connecté les prises dans Interface Builder.
Pensées :
awakeFromNib:
n'est pas appelé pour une raison quelconqueCe que j'ai essayé:
@IBOutlet
et de storyboard (au lieu de UIView
)Figure A *
Figure B
* Le code masqué dans Figure A
est:
@IBOutlet private var annotationOptionsView: UIView!
@IBOutlet private var arrivingLeavingSwitch: UISegmentedControl!
Je vous remercie.
Le story-board ne reconnaissait pas d'autres éléments de l'interface utilisateur que j'y ai ajoutés. Au moment de l'exécution, toutes les références étaient nulles. J'ai donc effacé mon dossier de données dérivées, puis ces connexions ont à nouveau fonctionné.
Cela se produit généralement parce que votre contrôleur de vue n'a pas encore chargé sa hiérarchie de vues. Un contrôleur de vue charge uniquement sa hiérarchie de vues lorsque quelque chose lui envoie le message view
. Le système procède ainsi lorsqu'il est temps de placer la hiérarchie de vues à l'écran, ce qui se produit après le retour d'éléments tels que prepareForSegue:sender:
et viewWillAppear:
.
Puisque votre VC n'a pas encore chargé sa hiérarchie de vues, vos points de vente sont toujours nuls.
Vous pouvez forcer le VC à charger sa hiérarchie de vues en disant _ = self.view
.
Avez-vous essayé d'exécuter Product> Clean. Résolu un problème très similaire pour moi.
Avez-vous instancié votre contrôleur de vue à partir d'un Storyboard ou d'une carte NIB, ou l'avez-vous instancié directement via un initialiseur?
Si vous avez instancié votre classe directement avec l'initialiseur, les prises ne seront pas connectées. Interface Builder crée des instances personnalisées de vos classes et les code dans des NIB et des Storyboards pour un décodage répété. Il ne définit pas les classes elles-mêmes. Si tel était votre problème, il vous suffit de modifier le code dans lequel vous créez votre contrôleur pour utiliser plutôt les méthodes sur UIStoryboard, ou UINib.
Dans mon cas, cela s'est produit parce que j'ai surchargé la méthode loadView
dans ma sous-classe ViewController, mais j'ai oublié d'ajouter [super loadView]
.
-(void)loadView {
// blank
}
Lorsque vous substituez la méthode loadView
, il vous incombe de lancer vos sous-vues. Étant donné que vous la remplacez, les vues du constructeur d’interface n’ont pas la possibilité de convertir des objets en cacao et les points de vente restent nuls.
Si vous implémentez loadView dans votre sous-classe de contrôleur de vue, il vous incombe alors de charger les éléments d'interface utilisateur à partir de storyboard/xib dans le code.
Ou appelez simplement
[super loadView];
Pour que la super-classe ait la chance de charger le storyboard/xib dans le code.
Cela m'arrivait avec ma cellule d'affichage de collection personnalisée. Il s'avère que j'ai dû remplacer ma méthode registerClassforReuseIdentifier par registerNib. Cela a réglé le problème pour moi.
Vous pouvez appeler controller.view
pour forcer le chargement de la vue afin d'initialiser les IBOutlets, vous pourrez ensuite affecter les valeurs.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "identifier") {
let controller = segue.destinationViewController as! YourController
let _ = controller.view //force to load the view to initialize the IBOutlets
controller.your_IBOutlet_property = xxx
...
controller.delegate = self
}
}
Pour moi, cela s’est produit lorsque j’ai accidentellement déclaré la classe de mon contrôleur de vue:
class XYZViewController: UINavigationController {
}
(c.-à-d. en tant que UINavigationController
pas un UIViewController
).
Xcode ne comprend pas cette erreur, la classe semble bien fonctionner et remplacer les fonctions telles que viewDidLoad
, viewWillAppear
, etc. fonctionnent correctement. Mais aucun des IBOutlet
s ne se connecte.
Changer la déclaration en
class XYZViewController: UIViewController {
}
résolu complètement.
Cela m’est arrivé parce que j’ai accidentellement instancié directement mon contrôleur de vue au lieu de l’instancier dans le scénarimage. Si vous instanciez directement via MyViewController()
, les prises ne seront pas connectées.
Je rencontre ce problème récemment! Voici ma pensée ... Le problème ne concerne pas votre storyboard ni aucun problème de lien. Il s'agit de la façon dont vous démarrez votre ViewController. Surtout lorsque vous utilisez Swift (il n'y a presque rien dans l'éditeur lorsque vous créez un fichier de classe)
En utilisant simplement la init()
de la classe supérieure, vous ne pouvez rien initier avec lequel vous avez travaillé avec le scénario. Vous devez donc modifier l’initialisation du ViewController. Remplacez let XXViewController = XXViewController()
Par let XXViewController = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("XXViewController") as! XXViewController
Cela indique au programme d'aller dans le storyboard rechercher XXViewController et de lancer tous les IBOutlet
de votre storyboard.
J'espère que cette aide ~ GL
Pour Swift 3.
func configureView() {
let _ = self.view
}
Solution de travail à 100% pour la création de ViewControllers à partir de XIB sans StoryBoards
7.1.
// creating instance
let controller = CustomViewController()
7.2.
// connecting view/xib with controller instance
let bundle = Bundle(for: type(of: controller))
bundle.loadNibNamed("CustomViewControllerView", owner: controller, options: nil)
7.3.
// get/set outlets
controller.labelOutlet.text = "title"
controller.imageOutlet.image = UIImage(named: "image1")
Pour moi, la même erreur se produisait sur un storyboard localisé: un élément avait été ajouté dans certaines langues et pas dans l'autre. ce storyboard en utilisant https://stackoverflow.com/a/42256341/1356559 .
Encore un autre cas que je viens de rencontrer. J'ai changé le nom de ma classe pour UIViewController, mais j'ai oublié de changer le nom du fichier .xib où l'interface a été construite.
Une fois que j'ai compris cela et fait en sorte que les noms de fichiers reflètent le nom de la classe, tout était bien!
J'espère que cela aide quelqu'un.
Vous devez d'abord charger la hiérarchie des vues afin d'instancier les points de vente dans le storyboard. Pour cela, vous pouvez appeler manuellement les méthodes loadView ou loadViewIfNeeded.
Autre cas:
Vos prises ne seront pas configurées tant que la vue du contrôleur de vue ne sera pas instanciée, ce qui dans votre cas se produira probablement peu de temps après initWithNibName: bundle: - à ce stade, elles seront toujours nil. Toute configuration impliquant ces sorties doit avoir lieu dans la méthode -viewDidLoad de votre contrôleur de vue.
Vérifiez votre connexion IBOutlet si elle est connectée au propriétaire du fichier ou à la vue ..__ Il pourrait y avoir des erreurs.
Si vous instanciez view controller
par programme. Ensuite, essayez de le créer comme ci-dessous
let initialVC = self.storyboard?.instantiateViewController(withIdentifier: "InitialVC") as! InitialVC
au lieu de directement
let initialVC = InitialVC()
Cela a fonctionné pour moi.
Pour moi, cela se bloquait parce que containerView
était nul.
Voici mon code avec Crash .
@IBOutlet private var containerView: UIView! // Connected to Storyboard
override open func loadView() {
containerView.addSubview(anotherView)
}
La chose manquante appelait la super.loadView()
. Donc, l'ajouter a résolu le problème pour moi.
Code fixe :
@IBOutlet private var containerView: UIView!
override open func loadView() {
super.loadView()
containerView.addSubview(anotherView)
}
J'ai encore un ...
Si vous avez une classe personnalisée pour un UITableViewCell mais oubliez de spécifier Custom dans le style de la cellule.
Vous pouvez valider si la vue est chargée.
if isViewLoaded && view.window != nil {
//self.annotationOptionsView.
}
.h
et .m
J'ai eu le même problème après avoir copié une classe (liée à une xib) pour la réutiliser avec une autre classe viewcontroller (liée à un storyboard) .
override var nibName
et
override var nibBundle
méthodes.
Après les avoir enlevés, mes points de vente ont commencé à fonctionner.
Accidentellement J'ai sous-classé mon contrôleur de vue avec AVPlayerViewController
au lieu de UIViewController
. En le rejouant à UIViewController
, les choses reviennent à la normale. Cela devrait aider.
Aucun nettoyage de construction (normal et complet), la suppression des dossiers de données dérivés et la fermeture de Xcode ont fonctionné pour moi.
Je vois que vous utilisez ViewController
!? dans la classe ViewController
vous devez utiliser -viewDidLoad
, pas -awakeFromNib
, -awakeFromNib
utiliser pour UIView
classe
Dans mon cas, l'application s'est effondrée soudainement . Le débogage de celle-ci a révélé que toutes les prises étaient encore nil
au moment de viewDidLoad()
.
Mon application utilise toujours nibs (pas de storyboards) pour la plupart des contrôleurs de vue. Tout était en place, tous les points de vente câblés correctement. J'ai vérifié deux fois.
Nous instancions généralement nos contrôleurs de vue comme
let newVC = MYCustomViewController()
... qui, pour une raison quelconque, semble fonctionner tant que le fichier .xib porte le même nom que la classe du contrôleur de vue (vous ne savez pas comment cela fonctionne. Nous sommes pas en train d'appeler init(nibName:bundle:)
avec des arguments nil ou de remplacer init()
pour le faire sur self
comme il est généralement suggéré ...).
Alors j'ai essayé d'appeler explicitement
let newVC = MYCustomViewController(nibName: "MYCustomViewController", bundle: .main)
... uniquement pour être accueilli avec l'erreur d'exception d'exécution:
*** Application de terminaison en raison d'une exception non interceptée 'NSInternalInconsistencyException', raison: 'Impossible de charger la NIB dans le lot:' NSBundle </ Users/nicolasmiari/Bibliothèque/Développeur/CoreSimulator/Devices/3DA3CF21-108D-498F-9649-C4FC9E3C1A8D/data /Containers/Bundle/Application/C543DDC1-AE86-4D29-988C-9CCE89E23543/MyApp.app> (chargé) 'avec le nom' MYCustomViewController ''
Et alors, je l'ai vu:
La case à cocher "Adhésion à la cible" du fichier .xib a été décochée.
Cela doit être arrivé lors de la résolution d'un des conflits de fusion fréquents concernant le fichier de projet Xcode.
Apple certainement doit proposer un format de fichier de projet plus convivial.
J'avais un problème similaire lorsque j'avais précédemment ajouté register (_: forCellReuseIdentifier :) pour la cellule personnalisée après avoir défini l'identifiant dans le storyboard. Avait ce code dans la fonction viewDidLoad (). Une fois que je l'ai enlevé, cela a bien fonctionné.
Si vous avez deux main.storyboards
et que vous apportez des modifications au mauvais, cela peut arriver. Cela peut arriver chaque fois que vous connectez un point de vente à partir d'une storyboard
non instanciée.