El módulo debería mostrar una ventana modal/UIViewController en el hilo principal, pero no funciona sin demora.
Estoy intentando presentar UIViewController en mi aplicación React Native desde el módulo de Swift. Lo estoy presentando de esta manera:
let screen = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
screen?.rootViewController?.present(payController!, animated: true, completion: nil);
y obtengo este error:
UIApplication.windows
solo debe ser utilizado desde el hilo principal.
Ok, tengo que añadirlo a mi hilo principal:
DispatchQueue.main.async {
let screen = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
screen?.rootViewController?.present(payController!, animated: true, completion: nil);
}
y funciona bien cuando llamo a esta función con un pequeño retraso:
setTimeout(() => {
showMyView();
}, 500);
o con un retraso en Swift de esta manera:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
let screen = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
screen?.rootViewController?.present(payController!, animated: true, completion: nil);
}
Pero si elimino el retraso, entonces este modal no se muestra. Pero debería estar ahí. Y veo esto en el registro de Swift que confirma mi teoría:
[Presentation] Attempt to present <pkaddpaymentpassviewcontroller: 0x103d6b2e0=""> on <uiviewcontroller: 0x103c25480=""> (from <uiviewcontroller: 0x103c25480="">) which is already presenting <rctmodalhostviewcontroller: 0x10e21df40="">.
PKAddPaymentPassViewController
es mi UIViewController.
No sé cómo solucionar este problema…
ACTUALIZACIÓN:
Basado en el primer comentario, hice esto:
DispatchQueue.main.async {
let screen = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
let controller = screen?.rootViewController?.presentedViewController;
if controller == nil {
screen?.rootViewController?.present(payController!, animated: true, completion: nil);
} else {
screen?.rootViewController?.presentedViewController?.present(payController!, animated: true, completion: nil)
}
}
Y la buena noticia es que el modal aparecerá, pero inmediatamente se cerrará. Veo el efecto de apertura y luego el efecto de cierre…
SOLUCIÓN:
1) todo en la sección de actualización
2) refactorizando el código de RN.
Resultó que hay otra modal abierta antes que la nueva. La modal anterior no se cerró antes de que abra la nueva… así que cierro la antigua más rápido y luego muestro la nueva y todo está bien.
davy.ai
Solución para presentar una UIViewController en una aplicación React Native desde un módulo Swift
Al presentar una UIViewController en una aplicación React Native desde un módulo Swift, es posible que se encuentre con el error “UIApplication.windows debe ser utilizado solo desde el hilo principal”. Para solucionarlo, puede agregar el código de presentación al hilo principal utilizando el método “DispatchQueue.main.async”.
Sin embargo, esto puede hacer que el modal no se muestre de inmediato. Para solucionarlo, puede agregar un retraso utilizando el método “setTimeout()” o el método “DispatchQueue.main.asyncAfter()”.
Si el modal aún no se muestra, puede que se encuentre con el error “Intento de presentar un UIViewController en otro UIViewController”. Para solucionarlo, puede comprobar si ya hay un controlador de vista presentado y presentar el nuevo encima de él.
Si el modal se abre y se cierra inmediatamente, puede haber un problema con otro modal ya abierto. Puede intentar cerrar el modal anterior antes de presentar el nuevo para solucionar este problema.
En general, refactorizar el código de React Native también puede ayudar a evitar estos problemas en el futuro.