Utilisation de Swift 1.1 et Xcode 6.2.
J'ai un UIStoryboard contenant une UIViewController
sous-classe personnalisée et singulière . Sur celui-ci, j'ai une @IBOutlet
connexion de type UIView
de ce contrôleur à une UIView
sous - classe sur le storyboard. J'ai également des points de vente 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 assuré que j'ai connecté les prises dans Interface Builder.
Réflexions :
- Est-il possible que, parce que j'utilise une sous-classe d'une sous-classe, quelque chose gâche l'initialisation? Je ne remplace aucun initialiseur
awakeFromNib:
n'est pas appelé pour une raison quelconque- Peut-être qu'il ne se connecte pas aux sous-vues sur les sous-vues
Les choses que j'ai essayées:
- Correspondance
@IBOutlet
et types d'éléments de storyboard exactement (au lieu deUIView
) - Supprimer la propriété et le point de vente et les ajouter de nouveau
Figure A *
Figure B
* Le code masqué dans Figure A
est:
@IBOutlet private var annotationOptionsView: UIView!
@IBOutlet private var arrivingLeavingSwitch: UISegmentedControl!
Je vous remercie.
clearView
Je m'attends à être nul. C'est quelque chose que je n'ai pas encore refactorisé. Voir également la note de bas de page de la figure A. @ShaanSingh Ça devrait être! car les connexions des storyboards sont (supposées être) définies lors de l'exécution et ne doivent pas être nulles.let vc = UIStoryboard(name: "LocationPickerModal", bundle: nil) .instantiateViewControllerWithIdentifier("LocationPickerModalViewController") as LocationPickerModalViewController
Réponses:
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 ne charge sa hiérarchie de vues que lorsque quelque chose lui envoie le
view
message. Le système fait cela quand il est temps de mettre la hiérarchie des vues à l'écran, ce qui se produit après que des choses commeprepareForSegue:sender:
etviewWillAppear:
soient revenues.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
.la source
viewWillAppear:
appel, la première fois que je fais quoi que ce soit avec cette prise. Accéder à la vue ne fait rien pour moi. Toujours nul.UIViewcontroller.loadViewIfNeeded()
est la bonne méthode à utiliser ici.Avez-vous essayé d'exécuter Produit> Nettoyer. Résolu un problème très similaire pour moi.
la source
DerivedData
dossier du projet.Avez-vous instancié votre contrôleur de vue à partir d'un Storyboard ou NIB, ou l'avez-vous instancié directement via un initialiseur?
Si vous instanciez 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 encode ces instances en NIB et Storyboards pour un décodage répété, il ne définit pas les classes elles-mêmes. Si c'était votre problème, il vous suffit de changer le code dans lequel vous créez votre contrôleur pour utiliser à la place les méthodes sur UIStoryboard ou UINib.
la source
UIStoryboard
instance et j'y fais appelinstantiateViewControllerWithIdentifier
.Le storyboard ne reconnaissait pas d'autres éléments de l'interface utilisateur que j'y ajoutais. 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 fonctionné à nouveau.
la source
viewDidLoad()
toutes les connexions ont été établies, maisviewWillAppear()
presque toutes l'étaientnil
(parfois un ou deux étaient encore connectés). J'ai tout essayé et finalement supprimé le dossier de données dérivé, reconstruit, et tout allait bien.Cela m'arrivait avec ma cellule de vue de collection personnalisée. Il s'avère que j'ai dû remplacer ma méthode registerClassforReuseIdentifier par registerNib. Cela m'a arrangé.
la source
Cela s'est produit pour moi parce que j'instanciais accidentellement mon contrôleur de vue directement au lieu de l'instancier via le storyboard. Si vous instanciez directement via,
MyViewController()
les prises ne seront pas connectées.la source
Dans mon cas, cela s'est produit parce que
loadView
j'ai remplacé la méthode dans ma sous-classe ViewController, mais j'ai oublié d'ajouter[super loadView]
Lorsque vous remplacez la
loadView
méthode, il est de votre responsabilité de lancer vos sous-vues. Comme vous le remplacez, les vues du générateur d'interface n'ont pas la possibilité de se convertir en objets cacao et les points de vente restent donc nuls.Si vous implémentez loadView dans votre sous-classe de contrôleur de vue, il est de votre responsabilité de charger les éléments d'interface utilisateur de storyboard / xib dans le code.
Ou juste appeler
Pour que la superclasse ait la chance de charger storyboard / xib dans le code.
la source
Vous pouvez appeler
controller.view
pour forcer le chargement de la vue pour initialiser les IBOutlets, puis vous pourrez attribuer les valeurs.la source
Si vous instanciez
view controller
via un programme. Ensuite, essayez de le créer comme ci-dessousau lieu de directement
Cela a fonctionné pour moi.
la source
Pour moi, cela s'est produit lorsque j'ai accidentellement déclaré la classe de mon contrôleur de vue comme
(c'est-à-dire comme un
UINavigationController
pas aUIViewController
).Xcode ne capte pas sur cette erreur, la classe semble bien de construction, et les fonctions de remplacement telles que
viewDidLoad
,viewWillAppear
etc. correctement tous les travaux. Mais aucun desIBOutlet
s n'est connecté.Changer la déclaration en
corrigé complètement.
la source
Je rencontre ce problème récemment! Voici ma pensée. Le problème ne concerne pas votre storyboard ou un problème de lien. Il s'agit de la manière dont vous lancez 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()
classe de super ne peut pas lancer quoi que ce soit que vous avez travaillé avec le storyboard. Vous devez donc modifier l'initialisation du ViewController. Remplacerlet XXViewController = XXViewController()
parlet XXViewController = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("XXViewController") as! XXViewController
Ceci indique au programme d'aller dans le storyboard trouver XXViewController et lance toutIBOutlet
dans votre storyboard.J'espère que cette aide ~ GL
la source
2019, UNE POSSIBILITÉ POUR CE PROBLÈME HORRIBLE:
Supposons que vous ayez peut-être une vue de conteneur qui montre une sorte d'horloge. Alors tu as
Horloge de classe: UIViewController
Vous l'utilisez en fait à plusieurs endroits de l'application .
Sur l'écran principal, sur l'écran des détails, sur l'écran d'édition.
Vous avez une application moderne de type Snapchat compliquée.
En fait,
Clock
peut en fait être chargé plus d'une fois en même temps quelque part sur le même écran . (Peut-être que c'est caché dans certains cas.)Vous commencez à travailler sur une instance de
Clock
sur l'un de vos nombreux storyboards.Sur ce storyboard, vous ajoutez une étiquette, NewLabel.
Naturellement, vous ajoutez la sortie dans le code. Tout devrait fonctionner. Tous les autres points de vente fonctionnent parfaitement.
Vous avez définitivement lié le point de vente.
Mais l'application plante avec NewLabel comme nul.
Xcode vous indique clairement "vous avez oublié de connecter la prise".
La raison en est que .......... vous avez "NewLabel" sur une seule des utilisations du storyboard de Clock!
Le crash provient en fait >>> d'un autre endroit <<<< vous utilisez Clock !!!!
Xcode ne vous dit pas que le crash provient d' un autre endroit, pas de l'endroit où vous travaillez!
Le crash n'est en fait pas de l'endroit où vous travaillez - il vient d' un autre storyboard, où il n'y a pas d'élément "NewLabel" sur ce storyboard !!!
Frustrant.
la source
Pour Swift 3.
la source
Vous devez d'abord charger la hiérarchie de vues afin d'instancier les sorties dans le storyboard. Pour cela, vous pouvez appeler manuellement les méthodes loadView ou loadViewIfNeeded.
la source
Dans mon cas, l'application a commencé à planter tout d'un coup. Le débogage a révélé que tous les points de vente étaient encore
nil
au moment deviewDidLoad()
.Mon application utilise toujours des pointes (pas des storyboards) pour la plupart des contrôleurs de vue. Tout était en place, toutes les prises câblées correctement. J'ai revérifié.
Nous instancions généralement nos contrôleurs de vue comme
... qui , pour une raison qui semble fonctionner aussi longtemps que le .xib porte le même nom que la classe de contrôleur de vue (pas sûr de savoir comment cela fonctionne, bien. Nous ne réclamons
init(nibName:bundle:)
des arguments nuls ou impérieusesinit()
de le faire surself
comme il est généralement suggéré ...).Alors j'ai essayé d'appeler explicitement
... seulement pour être accueilli avec l'erreur d'exception d'exécution:
Et puis , je l'ai vu:
La case à cocher "Adhésion cible" du fichier .xib a été décochée.
Doit s'être produit lors de la résolution de l'un des conflits de fusion fréquents concernant le fichier de projet Xcode.
Apple doit absolument proposer un format de fichier de projet plus compatible avec SCM.
la source
Solution 100% fonctionnelle pour créer des ViewControllers à partir de XIB sans StoryBoards
7.1.
7.2.
7.3.
la source
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?)
et appeler l'étape 7.2self
directement dans la classe CustomViewController.Vérifiez votre connexion IBOutlet si elle est connectée au propriétaire du fichier ou à la vue. Il pourrait y avoir des erreurs.
la source
Autre cas:
Vos points de vente ne seront pas définis tant que la vue du contrôleur de vue ne sera pas réellement instanciée, ce qui dans votre cas se produit probablement peu de temps après initWithNibName: bundle: —à quel point elles seront toujours nulles. Toute configuration que vous effectuez qui implique ces prises doit se produire dans la méthode -viewDidLoad de votre contrôleur de vue.
la source
Pour moi, j'ai eu la même erreur sur un storyboard localisé, un élément a été ajouté dans certains paramètres régionaux et pas dans l'autre, donc j'avais une référence nulle pour cet élément lors du basculement vers les paramètres régionaux de l'élément manquant, j'ai dû supprimer la localisation (redondante) pour ce storyboard en utilisant https://stackoverflow.com/a/42256341/1356559 .
la source
Pour moi, c'était un crash parce que
containerView
c'était nul.Voici mon code avec Crash .
La chose manquante appelait le
super.loadView()
. Donc l'ajouter a résolu le problème pour moi.Code fixe :
la source
J'ai eu un problème similaire lorsque j'avais précédemment ajouté le registre (_: forCellReuseIdentifier :) pour la cellule personnalisée après avoir déjà défini l'identifiant dans le storyboard. Avait ce code dans la fonction viewDidLoad (). Une fois que je l'ai retiré, cela a bien fonctionné.
la source
Encore un autre cas que je viens de rencontrer. J'ai changé le nom de ma classe pour l'UIViewController, mais j'ai oublié de changer le nom du fichier .xib où l'interface a été construite.
Une fois que j'ai attrapé cela et que les noms de fichiers reflètent le nom de la classe, tout était bon!
J'espère que cela aide quelqu'un.
la source
J'en ai encore un ...
Si vous avez une classe personnalisée pour un UITableViewCell mais que vous oubliez de spécifier Custom dans le Style de la cellule.
la source
Vous pouvez valider si la vue est chargée.
la source
.h
et.m
affichez les fichiers du contrôleurla source
J'ai accidentellement sous-classé mon contrôleur de vue avec
AVPlayerViewController
au lieu deUIViewController
. En le rejouant pourUIViewController
revenir à la normale. Cela devrait aider.la source
J'ai eu le même problème après avoir copié une classe (liée à un xib) pour la réutiliser avec une autre classe de viewcontroller (liée à un storyboard). J'ai oublié de supprimer
et
méthodes.
Après les avoir supprimés, mes points de vente ont commencé à fonctionner.
la source
Je vois que vous utilisez
ViewController
!? enViewController
classe, vous devez utiliser-viewDidLoad
, non-awakeFromNib
,-awakeFromNib
utiliser pour laUIView
classela source
Vérifiez si vous avez des prises manquantes ou déconnectées.
la source
Si vous en avez deux
main.storyboards
et que vous modifiez le mauvais, cela peut arriver. Cela peut se produire à chaque fois que vous connectez une prise à partir d'un non-instanciéstoryboard
.la source