ios - prepareforsegue - prepare for segue swift 4
performSegueWithIdentifier muy lento cuando segue es modal (7)
Tengo una vista de tabla simple donde manejo la acción de selección en la vista de tabla. Esta acción sigue un segue.
Si el segue es un empujue segue, la vista siguiente muestra inmediatamente. Si el segue es un modal
segue, la siguiente vista:
- tarda 6 segundos más o menos para mostrar
- Muestra inmediatamente si vuelvo a tocar (segundo toque)
Intenté buscar algunas ideas, pero ninguna parece ser aplicable a mi situación. En particular:
- Estoy realizando el segue en el hilo principal de la interfaz de usuario
- Mi vista es muy simple (por lo que no hay ningún problema en
viewDidLoad
). Además, el hecho de que se muestre casi instantáneo cuando el segmento espush
indica que no hay problemas para cargar la vista de destino. - Intenté pasarle
nil
alsender
; mismo efecto
¿Alguien tiene alguna idea sobre esto?
Confía en mí y prueba esto. Me he encontrado con este problema un par de veces.
En Swift 2:
dispatch_async(dispatch_get_main_queue(),{
self.performSegue(withIdentifier:mysegueIdentifier,sender: self)
})
o para Swift 3:
DispatchQueue.main.async {
self.performSegue(withIdentifier: mysegueIdentifier,sender: self)
}
Espero que esta ayuda pueda crear una transición modal programática como esta en Swift:
let myStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let modalViewController = myStoryboard.instantiateViewControllerWithIdentifier("myModalViewController") as! myModalViewController
modalViewController.modalTransitionStyle = UIModalTransitionStyle.CoverVertical
let navController = UINavigationController(rootViewController: accountManager)
dispatch_async(dispatch_get_main_queue(),{
self.presentViewController(navController, animated: true, completion: nil)
})
Intenté arreglar esto de varias maneras, incluso moviéndolo al hilo principal de arriba. Esto funcionó para mí:
En el guión gráfico, seleccione la vista de tabla en cuestión, (selecciónela en el contorno del documento para asegurarse de que tiene lo correcto. Luego, en el inspector de atributos, podrá ver los atributos de la vista de tabla así como la vista de desplazamiento que se encuentra debajo. (todas las vistas de la tabla se basan en la vista de desplazamiento). Hay un pequeño cuadro estúpido que se llama "retrasa los toques de contenido". Desmarque. También hay un "permite toques cancelables" que me imagino que usted quiere asegurarse de que no esté marcado también, ya que creo que los dobles toques estaban arruinando los míos.
La solución aceptada funcionó para mí. Código actualizado para Swift 2.0 a continuación:
dispatch_async(dispatch_get_main_queue(),{
self.performSegueWithIdentifier(mysegueIdentifier, sender:self)
})
Para los desarrolladores que organizan su código a través de subclases, he llegado a una solución bastante simple que me gustaría compartir (Swift 4):
import UIKit
class ABCViewController: UIViewController {
// ... Other useful methods like overriding deinit and didReceiveMemoryWarning
// Performs a segue on the main thread to ensure it will
// transition once a UI-slot is available
func performSegueOnMainThread(with identifier: String, sender: Any?) {
DispatchQueue.main.async {
self.performSegue(with: identifier, sender: sender)
}
}
}
Entonces, simplemente llámelo desde su implementación:
myViewController.performSegueOnMainThread(with: "ShowDetailsSegue", sender: self)
Parece (para mí ...) que este problema ocurre solo cuando el tipo de selectionType
celda no es .none
.
Puede cambiarlo a cualquier otra opción (en el Attribute inspector
del guión gráfico, defina el campo Selection
) y funcionará bien (funcionando para mí ...). Los contras es que está arruinando la interfaz de usuario celular.
Puede llamar a segue en DispatchQueue.main.async{}
en la función didSelect
delegate de UITableViewDelegate
como la gente menciona anteriormente.
Utilicé la primera solución y la agregué en la propia celda.
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(false, animated: false)
}
Esto hará que la celda se ''destaque'' en el grifo, pero volverá a su interfaz de usuario habitual de inmediato y estará bien para mí ...
Parece que hay varias situaciones en las que realizar una sesión no funcionará correctamente. Por ejemplo, si llama a performSegue
desde el controlador de acción de un performSegue
de desenvolvimiento, se encontrará con varios problemas, incluso aunque esté en el hilo principal. En mi proyecto actual, estoy llamando a performSegue
desde el método didSelectRowAt
de una vista de tabla. Este es uno de los segmentos más básicos que existen y, por supuesto, estoy en el hilo principal, sin embargo, estaba viendo los síntomas exactos que describía el OP.
No sé por qué sucede esto en algunos casos y no en otros, pero he descubierto que aplazar la llamada performSegue
usando async
corrige cualquier problema potencial. Esto solía parecer un truco y me ponía nervioso, pero en este punto tengo varios proyectos maduros que utilizan este enfoque y ahora parece ser la forma "correcta" de hacer una sesión manual.
Aquí está la versión Swift 3 del código (vea las otras publicaciones para las versiones Swift 2 y Obj-C):
DispatchQueue.main.async {
self.performSegue(withIdentifier: "theIdentifier", sender: theSender)
}