Usando Swift 1.1 y Xcode 6.2.
Tengo un UIStoryboard que contiene una UIViewController
subclase personalizada singular . En él, tengo una @IBOutlet
conexión de tipo UIView
desde ese controlador a una UIView
subclase en el guión gráfico. También tengo salidas similares para subvistas de esa vista. Ver figura A.
Pero en tiempo de ejecución, estas propiedades son nulas (Figura B). Aunque he asegurado que he conectado las salidas en Interface Builder.
Pensamientos :
- ¿Es posible que debido a que estoy usando una subclase de una subclase, algo se estropee con la inicialización? No anularé ningún inicializador
awakeFromNib:
no es llamado por alguna razón- Tal vez no se conecte a subvistas en subvistas
Cosas que he probado:
@IBOutlet
Tipos de elementos coincidentes y del guión gráfico exactamente (en lugar deUIView
)- Eliminar propiedad y salida y volver a agregarlos
Figura A *
Figura B
* El código oculto en Figure A
es:
@IBOutlet private var annotationOptionsView: UIView!
@IBOutlet private var arrivingLeavingSwitch: UISegmentedControl!
Gracias.
clearView
Espero ser nulo. Es algo que todavía tengo que refactorizar. Consulte también la nota al pie de la figura A. @ShaanSingh ¡Debería serlo! porque las conexiones de los guiones gráficos se establecen (se supone que están) en tiempo de ejecución y no deberían ser nulas.let vc = UIStoryboard(name: "LocationPickerModal", bundle: nil) .instantiateViewControllerWithIdentifier("LocationPickerModalViewController") as LocationPickerModalViewController
Respuestas:
Normalmente, esto sucede porque su controlador de vista aún no ha cargado su jerarquía de vista. Un controlador de vista solo carga su jerarquía de vista cuando algo le envía el
view
mensaje. El sistema hace esto cuando es el momento de poner realmente la jerarquía de vista en la pantalla, lo que sucede después de que cosas comoprepareForSegue:sender:
yviewWillAppear:
hayan regresado.Dado que su VC aún no ha cargado su jerarquía de vistas, sus puntos de venta siguen siendo nulos.
Puede obligar al VC a cargar su jerarquía de vistas diciendo
_ = self.view
.fuente
viewWillAppear:
se llama, la primera vez que hago algo con esa salida. Acceder a la vista no me hace nada. Todavía nulo.UIViewcontroller.loadViewIfNeeded()
es el método correcto para usar aquí.¿Ha intentado ejecutar Producto> Limpiar? Me resolvió un problema muy similar.
fuente
DerivedData
carpeta del proyecto.¿Instaló su controlador de vista desde un Storyboard o NIB, o lo creó directamente a través de un inicializador?
Si creó una instancia de su clase directamente con el inicializador, las salidas no se conectarán. Interface Builder crea instancias personalizadas de sus clases y codifica esas instancias en NIB y Storyboards para decodificación repetida, no define las clases en sí. Si este fue su problema, solo necesita cambiar el código donde crea su controlador para usar los métodos en UIStoryboard o UINib.
fuente
UIStoryboard
instancia y la invocoinstantiateViewControllerWithIdentifier
.El guión gráfico no reconocía más elementos de la interfaz de usuario que le agregué. En tiempo de ejecución, todas las referencias eran nulas. Así que borré mi carpeta de datos derivados y luego esas conexiones funcionaron nuevamente.
fuente
viewDidLoad()
todas las conexiones se hicieron, pero enviewWillAppear()
casi todas sínil
(a veces una o dos seguían conectadas). Probé todo y finalmente eliminé la carpeta de datos derivados, la reconstruí y todo estuvo bien.Esto me estaba sucediendo con mi celda de vista de colección personalizada. Resulta que tuve que reemplazar mi método registerClassforReuseIdentifier con registerNib. Eso me lo arregló.
fuente
Esto sucedió para mí porque accidentalmente estaba instanciando mi controlador de vista directamente en lugar de instanciarlo a través del guión gráfico. Si crea una instancia directamente a través de
MyViewController()
, las salidas no se conectarán.fuente
En mi caso, sucedió porque anulé el
loadView
método en mi subclase ViewController, pero olvidé agregar[super loadView]
Cuando anula el
loadView
método, es su responsabilidad iniciar sus subvistas. Como lo anula, las vistas del generador de interfaces no tienen la oportunidad de convertirse en objetos cocoa y, por lo tanto, las salidas permanecen nulas.Si implementa loadView en su subclase de controlador de vista, entonces es su responsabilidad cargar los elementos de la interfaz de usuario desde el guión gráfico / xib al código.
O simplemente llama
Para que la superclase tenga la oportunidad de cargar el guión gráfico / xib en el código.
fuente
Puede llamar
controller.view
para forzar la carga de la vista para inicializar los IBOutlets, luego podrá asignar los valores.fuente
Si crea una instancia
view controller
mediante programación. Entonces intente crearlo como a continuaciónen lugar de directamente
Esto funcionó para mí.
fuente
Para mí, esto ocurrió cuando declaré accidentalmente la clase de mi controlador de vista como
(es decir, como
UINavigationController
no aUIViewController
).Xcode no se recupera en este error, la clase de construcción parece bien, y funciones de mando, tales como
viewDidLoad
,viewWillAppear
, etc. todo el trabajo correctamente. Pero ninguno de losIBOutlet
s se conecta.Cambiar la declaración a
lo arregló por completo.
fuente
¡Encontré este problema recientemente! Aquí está mi pensamiento. El problema no se trata de su guión gráfico ni de ningún problema de enlace. Se trata de cómo inicia su ViewController. Especialmente cuando estás usando Swift (apenas hay nada en el editor cuando creas un archivo de clase)
Con el simple uso de la
init()
superclase from no se puede iniciar nada que haya trabajado con el storyboard. Entonces, lo que debe hacer es cambiar la inicialización del ViewController. Reemplazarlet XXViewController = XXViewController()
porlet XXViewController = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("XXViewController") as! XXViewController
Esto le dice al programa que vaya al guión gráfico, busque XXViewController e inicie todoIBOutlet
en su guión gráfico.Espero que esto ayude ~ GL
fuente
2019, UNA POSIBILIDAD PARA ESTE HORRIBLE PROBLEMA:
Supongamos que tiene quizás una vista de contenedor que muestra una especie de reloj. Así que tienes
clase Clock: UIViewController
De hecho, lo usa en varios lugares de la aplicación .
En la pantalla principal, en la pantalla de detalles, en la pantalla de edición.
Tienes una aplicación moderna complicada similar a Snapchat.
De hecho, es
Clock
posible que se carguen más de una vez al mismo tiempo en algún lugar de la misma pantalla . (Quizás esté oculto en algunos casos).Empieza a trabajar en una instancia de
Clock
uno de sus muchos guiones gráficos.En ese guión gráfico, agrega una etiqueta, NewLabel.
Naturalmente, agrega la salida en código. Todo debería funcionar. Todos los demás puntos de venta funcionan perfectamente.
Definitivamente has vinculado la salida.
Pero la aplicación se bloquea con NewLabel como nulo.
Xcode le dice claramente "se olvidó de conectar el tomacorriente".
La razón es esta ... ¡tienes "NewLabel" en solo uno de los usos del guión gráfico de Clock!
El bloqueo es en realidad de >>> otro lugar <<<< ¡¡¡¡¡estás usando Clock !!!!
Xcode no te dice que el bloqueo es de otro lugar, ¡ no de donde estás trabajando!
En realidad, el bloqueo no es del lugar en el que estás trabajando, ¡es de otro guión gráfico, donde no hay un elemento "NewLabel" en ese guión gráfico!
Frustrante.
fuente
Para Swift 3.
fuente
Primero debe cargar la jerarquía de vistas para crear una instancia de los puntos de venta en el guión gráfico. Para esto, puede llamar manualmente a los métodos loadView o loadViewIfNeeded.
fuente
En mi caso, la aplicación comenzó a fallar de repente. La depuración reveló que todos los puntos de venta estaban todavía
nil
en el momento deviewDidLoad()
.Mi aplicación todavía usa plumillas (no guiones gráficos) para la mayoría de los controladores de vista. Todo estaba en su lugar, todas las salidas conectadas correctamente. Lo comprobé dos veces.
Normalmente, instanciamos nuestros controladores de vista como
... que por alguna razón parece que funciona siempre y cuando el .xib tiene el mismo nombre que la clase controlador de vista (no sé cómo funciona, sin embargo. Estamos no un llamado
init(nibName:bundle:)
con argumentos nulos, o anulandoinit()
de hacerlo enself
guste se sugiere típicamente ...).Así que intenté llamar explícitamente
... solo para ser recibido con el error de excepción de tiempo de ejecución:
Y luego , lo vi:
La casilla de verificación "Membresía de destino" del archivo .xib estaba desmarcada.
Debe haber ocurrido al resolver uno de los frecuentes conflictos de fusión relacionados con el archivo de proyecto de Xcode.
Apple definitivamente necesita crear un formato de archivo de proyecto que sea más compatible con SCM.
fuente
Solución 100% funcional para crear ViewControllers desde XIB sin StoryBoards
7.1.
7.2.
7.3.
fuente
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?)
y llamar al paso 7.2self
directamente en la clase CustomViewController.Verifique su conexión de IBOutlet si se conectó al propietario del archivo o la vista. Puede haber errores.
fuente
Otro caso:
Sus puntos de venta no se configurarán hasta que se cree una instancia de la vista del controlador de vista, lo que en su caso probablemente sucederá poco después de initWithNibName: bundle: —en cuyo punto todavía serán nulos. Cualquier configuración que haga que involucre esos puntos de venta debería estar sucediendo en el método -viewDidLoad de su controlador de vista.
fuente
Para mí, tuve el mismo error en un guión gráfico localizado, se agregó un elemento en alguna configuración regional y no en la otra, por lo que tenía una referencia nula para ese elemento cuando cambié a la ubicación del elemento faltante, tuve que eliminar la localización (redundante) para ese guión gráfico usando https://stackoverflow.com/a/42256341/1356559 .
fuente
Para mí, esto se colapsaba porque
containerView
era nulo.Aquí está mi código con Crash .
Lo que faltaba era llamar al
super.loadView()
. Así que agregarlo resolvió el problema para mí.Código fijo :
fuente
Tuve un problema similar cuando agregué previamente el registro (_: forCellReuseIdentifier :) para la celda personalizada después de haber definido el identificador en el guión gráfico. Tenía este código en la función viewDidLoad (). Una vez que lo quité, funcionó bien.
fuente
Otro caso más que acabo de encontrar. Cambié el nombre de mi clase por el UIViewController, pero olvidé cambiar el nombre del archivo .xib donde se construyó la interfaz.
Una vez que capté esto e hice que los nombres de los archivos reflejaran el nombre de la clase, ¡todo estuvo bien!
Espero que ayude a alguien.
fuente
Tengo uno más ...
Si tiene una clase personalizada para un UITableViewCell pero se olvida de especificar Personalizado en el Estilo de la celda.
fuente
Puede validar si la vista is está cargada.
fuente
.h
y.m
ver los archivos del controladorfuente
Accidentalmente subclasé mi controlador de vista con en
AVPlayerViewController
lugar deUIViewController
. Repitiéndolo a todoUIViewController
normal. Esto debería ayudar.fuente
Tuve el mismo problema después de copiar una clase (vinculada a un xib) para reutilizarla con otra clase de controlador de vista (vinculada a un guión gráfico). Me olvidé de quitar
y
métodos.
Después de quitarlos, mis enchufes comenzaron a funcionar.
fuente
¡Te veo usar
ViewController
!? enViewController
clase debes usar-viewDidLoad
, no-awakeFromNib
,-awakeFromNib
usar paraUIView
clasefuente
Verifique si tiene algún tomacorriente faltante o desconectado.
fuente
Si tiene dos
main.storyboards
y está haciendo cambios en el incorrecto, esto puede suceder. Esto puede suceder en cualquier momento que conecte una toma de un no autenticadostoryboard
.fuente