Problema de UINavigation de iPhone: la animación de inserción anidada puede dar como resultado una barra de navegación dañada


Answers

INICIANDO ACCIDENTALMENTE EL MISMO SEGUTO DOS VECES Una vez en el código, y una vez desde el constructor de interfaz, pero ambas al mismo tiempo ...

Estaba recibiendo el mismo error que el resto de ustedes. Solo mi problema fue que estaba disparando accidentalmente la misma secuencia, dos veces. Una vez desde el constructor de interfaz, y una vez desde mi código.

Tengo una UITableView. Cuando se selecciona una celda, se dispara una transición en el generador de interfaz. Aquí está mi problema, hice configurar el segue para ser disparado directamente haciendo clic en CELL ITSELf, dentro del constructor de la interfaz, luego en mi código, lo hice bajo didSelectRowAtIndexPath, código que dispararía ese mismo segue ... como ese ...

[self performSegueWithIdentifier:@"MySegue" sender:tableView];

Eso significa que cuando se llama a selectRowAtIndexPath porque se seleccionó una fila, se activa el segue con la línea de código anterior. A continuación, el generador de interfaz también desencadena la segue porque está conectado directamente al objeto de celda en el constructor de interfaz. Para evitar que el constructor de interfaz active directamente el cambio. Debe conectar la transición desde la parte superior del controlador de visualización, no anidada dentro de la celda.

Entonces, si tiene este problema por la misma razón que yo, es decir, está llamando al mismo segue dos veces, puede solucionarlo desconectando la conexión de CELL DIRECTLY, a su segue, y haciendo que la conexión segue se origine en el encabezado de la jerarquía de tablas en IB, en lugar de anidado dentro de la celda. Conecte la segue de usted Ver el controlador en sí, a la segue. Si ha hecho esto correctamente, cuando selecciona el segue, debe resaltar la vista ENTERA de la que proviene, no solo la celda.

Ahora, la documentación de Apples declara así bajo performSegueWithIdentifier: sender: reference:

Normalmente, las aplicaciones no necesitan desencadenar los segmentos directamente. En su lugar, configura un objeto en el Creador de interfaz asociado con el controlador de vista, como un control incrustado en su jerarquía de vista, para activar el segue. Sin embargo, puede llamar a este método para desencadenar un cambio programático, tal vez en respuesta a alguna acción que no se puede especificar en el archivo de recursos del guión gráfico. Por ejemplo, puede llamarlo desde un controlador de acción personalizado que se usa para procesar eventos shake o acelerómetro.

En mi caso, tengo un botón de búsqueda para mi UITableView, y se debe determinar si se llama a la segue cuando está presente la tabla de resultados de búsqueda, o si está presente la vista de tabla normal. Entonces necesité disparar el segue directamente.

Por lo tanto, elimine el control incorporado del constructor de interfaz, y simplemente colóquelo en el controlador de vista, ¡luego active la transición en su código!

¡Ahora, no más dobles segues! Y no más errores

Espero que eso ayude, me tomó unas buenas horas para abordar este.

Question

Sigo recibiendo los siguientes errores:

2011-04-02 14:55:23.350 AppName[42430:207] nested push animation can result in corrupted navigation bar
2011-04-02 14:55:23.352 AppName[42430:207] nested push animation can result in corrupted navigation bar
2011-04-02 14:55:23.729 AppName[42430:207] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
2011-04-02 14:55:23.729 AppName[42430:207] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.

Esto es lo que estoy haciendo. Desde un controlador de vista, invoco lo siguiente cuando se presiona un botón determinado:

EventsViewController *viewController = [[EventsViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
navController.navigationBar.tintColor = [UIColor blackColor];
[self presentModalViewController:navController animated:YES];
[viewController release];
[navController release];

Luego, si se presiona un botón determinado en EventsController, llamo a:

SingleEventViewController *viewController = [[SingleEventViewController alloc] initWithEvent:[currentEvents objectAtIndex:indexPath.row]];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];

Luego, si se presiona un botón determinado en SingleEventViewController, llamo a:

EventMapView* viewController = [[EventMapView alloc] initWithCoordinates];
[[self navigationController] pushViewController:viewController animated:YES];
[viewController release];

Así que sí, es obvio que hay animaciones push anidadas, pero ¿no es esta la manera correcta de hacerlo? Comprobé el código DrillDownSave de Apple y parece que así es como lo están haciendo. ¿Importa que use métodos init en lugar de los métodos viewDidLoad?




En mi caso, yo establecía la transición de inserción desde el guión gráfico y programáticamente. Espero que eso ayude a cualquiera




1) Quizás podría tratar de pasar las variables necesarias como propiedades antes de presionar el UIViewController lugar de usar los métodos init con parámetros. Lo más probable es que necesite estos parámetros más allá de su método init de todos modos.

Además, en su método initWithCoordinates: le faltan los parámetros. Posiblemente sus métodos de inicio personalizados sean parte del problema.

2) Solo porque mencionó viewDidLoad : este método es para la inicialización después de que se cargó una vista. Si crea UIViewController en el código, como parece que lo hace, debe usar loadView para configurar sus subvistas.




Mi solución fue

[self performSelector: @selector (moveTo) withObject: nil afterDelay: 0.5];




¿A qué te refieres cuando dices que usas métodos init en lugar de los métodos viewDidLoad?

Si está presionando un nuevo controlador de vista antes de que el antiguo impulso tenga una mala probabilidad de acción, obtendrá este tipo de error. Así que poner cierto código en init y hacer cosas prematuramente sin duda podría hacerte llegar el error.

¡En el punto donde init se está ejecutando en un controlador de vista, la vista no se ha cargado todavía!




Mi problema tiene que ver con que el teclado esté activo.

Esto fue causado por mí al presionar un ViewController desde un método delegado textField:

-(void)textFieldDidBeginEditing:(UITextField *)textField{

        FilterLocationViewController *destViewController = (FilterLocationViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"FilterLocationViewController"];

        [self.navigationController pushViewController:destViewController animated:YES];

}

Al cambiar el código a esto:

-(void)textFieldDidBeginEditing:(UITextField *)textField{

        [_textFieldLocation resignFirstResponder]; //adding this line

        FilterLocationViewController *destViewController = (FilterLocationViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"FilterLocationViewController"];

        [self.navigationController pushViewController:destViewController animated:YES];

}

(agregando la línea [textField resignFirstResponder]; ) el problema desapareció.

Básicamente, la lección es que no debe modificar la pila de NavigationController si el teclado está apagado.




Sé que esto fue respondido, pero podría ayudar a otros.

Tuve el mismo problema, pero fue causado porque estaba usando un mal evento para un botón de información. Estaba usando "UIControlEventAllTouchEvents" y esto generó dos impulsos de la misma vista en el controlador de navegación. El evento correcto fue "UIControlEventTouchUpInside". Soy nuevo en iOS.




Solo para completar la lista, esta es otra razón que puede causar que "la animación de inserción anidada pueda dar como resultado una barra de navegación dañada":

Configuré varios NavigationController dentro de un TabBarController y establecí el selectedIndex dentro del guión gráfico Identifiy Properties. Después de mover la pestaña activa a Código, el error desapareció.




Esto ya ha sido respondido, pero pensé que esto podría ayudar a otros ya que obtuve el mismo error pero sin usar vistas de tabla. Finalmente descubrí el problema.

Tenía un botón existente cuya IBAction invocaba un pushViewController. Creé un nuevo botón copiando el botón existente. El nuevo botón también tenía una acción que invocaba pushViewController. Cuando se tocó el nuevo botón (retoque adentro) y se presionó el controlador de vista, obtuve este error. Eliminé el nuevo botón, lo creé desde cero, lo vinculé a las salidas y acciones existentes, y el error desapareció.




Lo he descubierto. Aparentemente si llama a -pushViewController desde fuera del método -didSelectRowAtIndexPath de un UITableViewDelegate, no funciona. Mover la llamada a esa función funcionó. Extraño.




Related