xcode swift uistoryboard null iboutlet

xcode - IBOutlet es nulo, pero está conectado en el guión gráfico, Swift



uistoryboard null (30)

2019, UNA POSIBILIDAD PARA ESTE HORRIBLE PROBLEMA:

  • Supongamos que tiene una vista de contenedor que muestra algún tipo de reloj. Así que tienes

    Reloj de clase: 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, Clock puede cargarse más de una vez al mismo tiempo en algún lugar de la misma pantalla . (Tal vez está oculto en algunos casos).

Comienza a trabajar en una instancia de Clock en uno de sus muchos guiones gráficos.

En ese guión gráfico agrega una etiqueta, NewLabel.

Naturalmente, agrega la salida en el 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 nula.

Xcode le dice claramente "olvidó conectar la toma de corriente".

¡La razón es esta .......... tienes "NewLabel" en solo uno de los usos de Storyboard de Clock!

El accidente es en realidad de >>> otro lugar <<<< estás usando Clock !!!!

¡Xcode no te dice que el accidente es de otro lugar, no de donde estás trabajando!

El bloqueo en realidad no es del lugar donde estás trabajando, ¡es de otro guión gráfico, donde no hay ningún elemento "NewLabel" en ese guión gráfico!

Frustrante.

Usando Swift 1.1 y Xcode 6.2.

Tengo un UIStoryboard que contiene una subclase UIViewController personalizada y singular. En él, tengo una conexión @IBOutlet de tipo UIView desde ese controlador a una subclase UIView 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 los enchufes en Interface Builder.

Pensamientos :

  • ¿Es posible que debido a que estoy usando una subclase de una subclase, algo se confunde con la inicialización? No estoy anulando ningún inicializador
  • awakeFromNib: no se llama por alguna razón
  • Tal vez no se conecta a subvistas en subvistas

Cosas que he probado:

  • Coincidencia de los tipos de elementos @IBOutlet y storyboard exactamente (en lugar de UIView )
  • Eliminar propiedad y salida y volver a agregarlos

Figura A *

Figura B

* El código oculto en la Figure A es:

@IBOutlet private var annotationOptionsView: UIView! @IBOutlet private var arrivingLeavingSwitch: UISegmentedControl!

Gracias.


  1. seleccione archivos de controlador de vista .h y .m
  2. eliminar la referencia de esos archivos
  3. vuelva a agregar los archivos a su árbol de proyecto
  4. abrir el guión gráfico, eventualmente reconstruir el proyecto

¿Has intentado ejecutar Producto> Limpiar? Resuelto un problema muy similar para mí.


¿Instanciaste tu controlador de vista desde un Storyboard o NIB, o lo instanciaste directamente a través de un inicializador?

Si crea una instancia de su clase directamente con el inicializador, las salidas no se conectarán. Interface Builder crea instancias personalizadas de sus clases y las codifica en NIB y Storyboards para la decodificación repetida, no define las clases en sí mismas. Si este fue su problema, solo necesita cambiar el código donde crea su controlador para utilizar los métodos en UIStoryboard o UINib.


El guión gráfico no reconocía más cosas de IU 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.


En mi caso, la aplicación comenzó a fallar de repente. La depuración reveló que todos los puntos de venta todavía eran nil en el momento de viewDidLoad() .

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, todos los enchufes estaban correctamente conectados. Lo comprobé dos veces.

Por lo general, instanciamos nuestros controladores de vista como

// creating instance let controller = CustomViewController()

... que por alguna razón parece funcionar siempre que el .xib tenga el mismo nombre que la clase de controlador de vista (aunque no estoy seguro de cómo funciona). No estamos llamando a init(nibName:bundle:) con argumentos nulos, o anular init() para hacerlo en self como se suele sugerir ...).

Entonces intenté llamar explícitamente

// connecting view/xib with controller instance let bundle = Bundle(for: type(of: controller)) bundle.loadNibNamed("CustomViewControllerView", owner: controller, options: nil)

... solo para ser recibido con el error de excepción de tiempo de ejecución:

*** Finalización de la aplicación debido a la excepción no detectada ''NSInternalInconsistencyException'', razón: ''No se pudo cargar NIB en el paquete:'' NSBundle </ Users / nicolasmiari / Library / Developer / CoreSimulator / Devices / 3DA3CF21-108D-498F-9649-C4FC9E3C1A8D / data /Containers/Bundle/Application/C543DDC1-AE86-4D29-988C-9CCE89E23543/MyApp.app> (cargado) ''con el nombre'' MYCustomViewController ''''

Y luego , lo vi:

La casilla de verificación "Membresía de destino" del archivo .xib no estaba marcada.

Debe haber sucedido al resolver uno de los frecuentes conflictos de fusión con respecto al archivo del proyecto Xcode.

Apple definitivamente necesita crear un formato de archivo de proyecto que sea más compatible con SCM.


En mi caso, sucedió porque loadView método loadView en mi subclase ViewController, pero olvidé agregar [super loadView]

-(void)loadView { // blank }

Cuando anula el método loadView , es su responsabilidad iniciar sus subvistas. Como lo anula, las vistas del generador de interfaces no tienen la oportunidad de convertirse en objetos de cacao 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 del guión gráfico / xib en el código.

O simplemente llama

[super loadView];

Para que la superclase tenga la oportunidad de cargar storyboard / xib en el código.


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ó.


Esto me sucedió porque accidentalmente estaba instanciando mi controlador de vista directamente en lugar de instanciarlo a través del guión gráfico. Si MyViewController() instancia directamente a través de MyViewController() , las salidas no se conectarán.


Me encuentro con este problema recientemente! Aquí está mi pensamiento. El problema no es sobre su guión gráfico o cualquier problema de enlace. Se trata de cómo iniciar su ViewController. Especialmente cuando está usando Swift. (No hay casi nada en el editor cuando crea un archivo de clase)

Simplemente usando init() de super class no puede iniciar nada de lo que trabajó con el storyboard. Entonces, lo que debe hacer es cambiar la inicialización de ViewController. Reemplace let XXViewController = XXViewController() por let XXViewController = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("XXViewController") as! XXViewController let XXViewController = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("XXViewController") as! XXViewController Esto le dice al programa que vaya al guión gráfico y encuentre XXViewController e inicia todos los IBOutlet en su guión gráfico.

Espero que esta ayuda ~ GL


Otro caso más que acabo de encontrar. Cambié el nombre de mi clase para UIViewController, pero olvidé cambiar el nombre del archivo .xib donde se creó la interfaz.

Una vez que entendí esto e hice que los nombres de los archivos reflejaran el nombre de la clase, ¡todo estuvo bien!

Espero que ayude a alguien.


Otro caso:

Sus puntos de venta no se configurarán hasta que la vista del controlador de vista esté realmente instanciada, lo que en su caso probablemente suceda poco después de initWithNibName: paquete: en ese 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.


Para Swift 3.

let initialVC = InitialVC()


Para mí, esto ocurrió cuando accidentalmente declaró la clase de mi controlador de vista como

class XYZViewController: UINavigationController { }

(es decir, como UINavigationController no como UIViewController ).

Xcode no viewDidLoad este error, la clase parece compilarse bien y anula funciones como viewDidLoad , viewWillAppear , etc., todo funciona correctamente. Pero ninguno de los IBOutlet se conecta.

Cambiar la declaración a

class XYZViewController: UIViewController { }

Lo arreglé por completo.


Para mí, esto se estaba bloqueando porque containerView era nulo.

Aquí está mi código con Crash .

if isViewLoaded && view.window != nil { //self.annotationOptionsView. }

Lo que faltaba era llamar a super.loadView() . Así que agregarlo resolvió el problema para mí.

Código fijo :

let newVC = MYCustomViewController()


Para mí, tuve el mismo error en un guión gráfico localizado, se agregó un elemento en una configuración regional y no en la otra, por lo que tenía una referencia nula para ese elemento cuando cambié a la configuración regional del elemento faltante, tuve que eliminar la localización (redundante) para ese guión gráfico usando https://.com/a/42256341/1356559 .


Por lo general, 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 mensaje de view . El sistema hace esto cuando es el momento de poner realmente la jerarquía de vistas en la pantalla, lo que sucede después de que cosas como prepareForSegue:sender: y viewWillAppear: han regresado.

Como su VC aún no ha cargado su jerarquía de vistas, sus puntos de venta siguen siendo nulos.

Puede forzar al VC a cargar su jerarquía de vistas diciendo _ = self.view .


Primero debe cargar la jerarquía de vistas para crear instancias de los puntos de venta en el guión gráfico. Para esto, puede llamar manualmente a los métodos loadView o loadViewIfNeeded.


Puede llamar a controller.view para forzar la carga de la vista para inicializar los IBOutlets, luego podrá asignar los valores.

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 } }


Puede validar si la vista is está cargada.

let newVC = MYCustomViewController(nibName: "MYCustomViewController", bundle: .main)


Si crea una instancia del view controller mediante programación. Luego intenta crearlo como a continuación

func configureView() { let _ = self.view }

en lugar de directamente

let initialVC = self.storyboard?.instantiateViewController(withIdentifier: "InitialVC") as! InitialVC

Esto funcionó para mí.


Si tiene dos main.storyboards y está realizando cambios en el incorrecto, esto puede suceder. Esto puede suceder cada vez que conecte una salida de un storyboard desinstalado.


Tengo uno más ...

Si tiene una clase personalizada para un UITableViewCell pero olvida especificar Custom en el estilo de la celda.


Tuve el mismo problema después de copiar una clase (vinculada a un xib) para reutilizarla con otra clase de control de vista (vinculada a un guión gráfico). Olvidé eliminar

override var nibName

y

override var nibBundle

métodos

Después de eliminarlos, mis puntos de venta comenzaron a funcionar.


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.


Veo que usas ViewController ! en la clase ViewController debe usar -viewDidLoad , no -awakeFromNib , -awakeFromNib para la clase UIView


Verifique si le faltan enchufes o están desconectados.


Verifique su conexión IBOutlet si está conectada al propietario del archivo o la vista. Podría haber errores.


Accidentalmente subclasifiqué mi controlador de vista con AVPlayerViewController lugar de UIViewController . Al reproducirlo en UIViewController cosas vuelven a la normalidad. Esto debería ayudar.

Sin limpieza de compilación (normal y completa), eliminar carpetas de datos derivadas y salir de Xcode funcionó para mí.


Solución 100% funcional para crear ViewControllers desde XIB sin StoryBoards

  1. Crear clase CustomViewController: UIViewController
  2. Crear vista CustomViewControllerView.xib
  3. En CustomViewControllerView.xib en Interface Builder, seleccione Marcadores de posición -> Propietario del archivo
  4. En "Inspector de atributos" establezca Clase en CustomViewController
  5. En "Inspector de conexiones", conecte la "vista" a la vista de nivel superior de xib (asegúrese de que la clase de la vista de nivel superior no apunte a CustomViewController)
  6. En "Inspector de conexiones", conecte otras salidas (si es necesario / existe)
  7. Cree una instancia de CustomViewController en el controlador de vista principal / delegado de la aplicación

7.1.

// get/set outlets controller.labelOutlet.text = "title" controller.imageOutlet.image = UIImage(named: "image1")

7.2.

@IBOutlet private var containerView: UIView! // Connected to Storyboard override open func loadView() { containerView.addSubview(anotherView) }

7.3.

@IBOutlet private var containerView: UIView! override open func loadView() { super.loadView() containerView.addSubview(anotherView) }