ios - storyboard instantiateViewControllerWithIdentifier no configura IBOutlets
interface-builder uistoryboard (6)
Estoy usando storyboard instantiateViewControllerWithIdentifier:
y me doy cuenta de que todos los IBOutlets
que he conectado todavía son nulos. Sin embargo, las IBActions
que he cableado funcionan. La vista y el controlador están vinculados (es decir, controller.view no es nada), y si muestro la vista, se muestra lo que estoy esperando.
¿Qué me estoy perdiendo?
Aquí está mi configuración:
- Tengo un controlador de vista definido en mi guión gráfico. Le he dado un identificador que es el mismo identificador que uso al invocar
instantiateViewControllerWithIdentifier:
- Configuré el propietario de la vista haciendo clic en View Controller (justo debajo de First Responder) y en el Inspector de identidad configuré Custom Class para que sea el mismo nombre que la clase a la que quiero conectar la vista.
- Luego abro el editor asistente y el control arrastró los elementos de la interfaz de usuario para crear
IBOutlets
eIBActions
.
Establecer el marco para ViewController instanciado parece establecer IBOutlets.
ex:
DemoViewController *demoVC = [[self storyboard] instantiateViewControllerWithIdentifier:@"demoVC"];
demoVC.frame = self.view.frame; //or CGRectMake(0, 0, 1015, 604);
Esto inicializaría los IBOutlets de DemoViewController como Label, TextField, Button, Table, etc.
Espero que esto ayude.
La vista parece inicializarse correctamente solo después de que se acceda primero. El problema desaparece al llamar
[self presentViewController:vc animated:NO completion:nil];
o más simplemente
[vc view];
Las personas dieron una solución sobre cómo cargar la vista (algunas de las cuales nunca debes usar ( loadView()
) así que aquí hay una manera de verificar si tu vista ya está cargada.
Me encontré con el problema porque tenía una propiedad con un observador didSet
para actualizar la interfaz de usuario, lo que obviamente no funciona si las tomas aún no están configuradas, así que aquí hay un código de ejemplo sobre cómo didSet
:
var name: String? {
didSet {
updateNameLabel()
}
}
override func viewDidLoad() {
super.viewDidLoad()
updateNameLabel()
}
func updateRoomLabel() {
guard isViewLoaded() else {
return
}
[...]
}
Así que ahora cuando visualiza los puntos de venta se actualizan pero también cada vez que actualiza la propiedad
Los puntos de venta se establecen con Key Value Coding, puede poner esto en su subclase de controlador de vista:
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath {
[super setValue:value forKeyPath:keyPath];
}
- (void)setValue:(id)value forKey:(NSString *)key {
[super setValue:value forKeyPath:key];
}
Y pon un punto de interrupción en las dos llamadas a super.
En el depurador, probaría:
Comparando ''self'' con el controlador de vista al que crees que estás aplicando los puntos de venta. Quizás tu guión gráfico tenga un segundo controlador de vista que no estás esperando. Cuando dijiste que ''configuraste un dueño'' pensé que era una terminología extraña. ¿Arrastró uno de los objetos del cubo para representar su controlador de vista además de la representación que ya está allí?
Compare [self valueForKey: key] o [self valueForKeyPath: keyPath] o simplemente [self outletName] con el valor pasado después de la llamada a super. Tal vez has establecido que no está haciendo lo que quieres. He visto un error como este aparecer un par de veces donde la gente tiene una salida para un objeto con un nombre como "firstName" y luego una acción con el selector "setFirstName:". Eso confunde la codificación del valor clave, y termina con setFirstName: se llama durante la carga de la punta con la intención de establecer la salida, pero el setter para la salida se implementa como un método de acción, por lo que nunca se establece la salida.
Si el objeto al que se está vinculando es una entidad de nivel superior en la escena, como un ArrayController, la referencia debe ser fuerte (¡no débil!) Ya que no es retenida por la jerarquía de vistas. Una referencia débil puede causar un problema como el que describes.
Mire aquí para más información: ¿Deberían IBOutlets ser fuertes o débiles bajo ARC?
[Usarme como mal ejemplo]
Tal vez no sea una buena idea después de todo, funciona pero viola la carga normal haciendo que la aplicación sea inestable ^ _ ^.
Dejaré la respuesta aquí en caso de que alguien más quiera saber si lo haces.
Estaba teniendo el mismo problema, sin embargo, el componente personalizado que diseñé no se carga a través de presentViewController (cargar en superposición a la vista anterior)
Simplemente puede llamar
myViewController.loadView()
// Swift
[myViewController loadView]
// Obj-C