Segue adaptable en el guión gráfico Xcode 6. ¿Está el empuje obsoleto?

El constructor de interfaz Xcode 6 tiene de forma predeterminada una nueva checkbox “usar clases de tamaño”. Hace las vistas adaptativas. enter image description here

Cuando bash hacer segue entre 2 vistas en mi guión gráfico, tengo nuevas opciones: enter image description here

en lugar de viejo:

enter image description here

Ahora tenemos “mostrar” y “presentar de manera modal” en lugar de “presionar” y “modal”. Las opciones anteriores están marcadas como obsoletas. Elegí la opción “mostrar”, porque en la configuración segue se llamaba “mostrar (por ejemplo, pulsar)

enter image description here

Pero no hace presión. La animación Segue parece deslizarse desde la parte inferior (modal) y la barra de navegación desaparece.

La pregunta es: ¿cómo puedo hacer que “mostrar” funcione como push? ¿Es posible o debo usar “push (obsoleto)” en su lugar? ¿Dónde puedo encontrar información sobre nuevos tipos de segue? Lo único que encontré en la biblioteca de desarrolladores de iOS8 es Storyboards. Ayuda a diseñar su interfaz de usuario, pero no hay información sobre el “show” segue.

ACTUALIZAR

Traté de crear un nuevo proyecto y “show” realmente funciona como “push”. Creo que el problema en mi proyecto puede deberse a que reutilizo el controlador de navegación con un código como este, pero no sé cómo solucionarlo.

if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] ) { SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue; swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) { UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController; [navController setViewControllers: @[dvc] animated: NO ]; [self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES]; }; } 

Después de eso trato de empujar NewViewController después de MainViewController enter image description here

ACTUALIZACIÓN 2:

Parece ser solo iOS 7, iOS 7.1.

Sí, use ‘Mostrar’ en lugar de ‘Empujar’

¿Cómo puedo hacer que “show” funcione como push? ¿Es posible o debo usar “push (depricated)” en su lugar?

Debería; lo hace por mi Estoy usando Xcode 6 beta 2 y para probar utilicé la plantilla de vista única (llamando al controlador de vista preestablecido en IB ‘VC_A’). Luego agregué otro controlador de vista (‘VC_B’). Luego agregué un botón en VC_A para mostrar VC_B y otro de VC_B de vuelta a VC_A. Cuando agrego un controlador de navegación como el controlador de vista inicial en el guión gráfico y hago de VC_A el controlador de visualización raíz, tanto ‘push’ como ‘show’ tienen el mismo efecto. Si no tengo un controlador de navegación inicial y uso ‘mostrar’, obtengo lo que describiste en el sentido de que el VC_B se desliza hacia arriba desde abajo. Si trato de “presionar” obtengo un locking ya que para hacer un empuje debo tener un controlador de navegación. Por lo tanto, parece que ‘show’ hará un empujón en el caso en que se proporcione un controlador de navegación y presente un presente con un estilo de transición modal si el controlador de navegación no está presente.

¿Dónde puedo encontrar información sobre nuevos tipos de segue?

Así que encontré algo de información en la sesión ‘Novedades en Interface Builder’ aquí . Si miras las diapositivas, verás una diapositiva (41) que menciona el cambio. Al mirar el video de la sesión, puede saltar al minuto 38:00 donde comienzan a hablar de segues adaptativos. Explican que el segue adaptable ‘show’, por ejemplo, toma en cuenta el contexto cuando se decide cómo hacer la presentación de un nuevo controlador de vista.

Ya hay una respuesta aceptada, pero quería dar un poco más de información, posiblemente información que no estaba disponible antes.

Como se mencionó anteriormente, los segmentos “push” y “modal” fueron obsoletos, y han sido reemplazados por “show” y “present modally”, respectivamente. De acuerdo con la documentación de Apple, los nuevos segmentos se han dividido en segmentos que se adaptan a las clases de tamaño. Los anteriores solo deben usarse para admitir versiones de iOS anteriores a iOS 8.

El documento en el siguiente enlace explica eso y la descripción de todos los segmentos disponibles, antiguos y nuevos.

Agregar un Segue Between Scenes en un Storyboard

En caso de que la URL cambie en el futuro, esta es la explicación dada para cada nueva transición:

Espectáculo

Presente el contenido en el área principal o de detalle según el contenido de la pantalla. Si la aplicación muestra una vista maestra y de detalles, el contenido se coloca en el área de detalles. Si la aplicación solo muestra el maestro o el detalle, el contenido se coloca encima de la stack del controlador de vista actual.

Mostrar detalle

Presente el contenido en el área de detalles. Si la aplicación muestra una vista maestra y de detalles, el nuevo contenido reemplaza el detalle actual. Si la aplicación solo muestra el maestro o el detalle, el contenido reemplaza la parte superior de la stack del controlador de vista actual.

Presente Modally

Presente el contenido de forma modal. Hay opciones para elegir un estilo de presentación (UIModalPresentationStyle) y un estilo de transición (UIModalTransitionStyle).

Presente como Popover

Presente el contenido como un popover anclado a una vista existente. Existe una opción para especificar las posibles direcciones de la flecha que se muestra en un borde de la vista de popover (UIPopoverArrowDirection). También hay una opción para especificar la vista de anclaje.

tldr; Elimine el Segue que no está presionando correctamente y vuelva a crearlo en el guión gráfico arrastrando desde un UIView / UIControl al controlador de vista de destino.

No hay nada de malo con las otras respuestas, pero esta explica qué está sucediendo, cómo puede verificar que está sucediendo y cómo mitigar el problema en el futuro.

Fondo

En mi caso, ninguno de mis Segmentos de muestra funcionaba aunque ya tenía un UINavigationController como mi controlador de vista inicial (con mi contenido UIViewController ya que es raíz).

Por qué y cómo se rompe el Show Segue

La transición de la presentación se rompe cuando tiene una acción asociada con la segue dentro de la fuente XML del guión gráfico. Un escenario típico que podría causar esto podría ser si ha redefinido un segue de una transición manual previamente llamada en el código. Esto deja los siguientes bits en el guión gráfico xml.

    

Nota Bene Para ver el guión gráfico como xml; Haga clic con el botón derecho en el archivo del guión gráfico y elija Abrir como> Código fuente . Para revertir el uso Abrir como> Interface Builder – Storyboard

Para acomodar cualquier acción personalizada al usar la segue del guión gráfico, puede tocar prepareForSegue e interceptar el controlador de vista de destino y llamar a cualquier método desde esa ubicación. En cualquier caso, el efecto secundario de este pequeño error (el error es el hecho de que cuando redefine el segue no está configurado correctamente en xml ~ es decir, la acción permanece incluso después de cambiar el segue a uno que opera desde un UIView (o UIControl) a un controlador de vista de destino).

Lamentablemente, la solución más directa falla. Así que solo eliminar el atributo xml de la acción desde el Storyboard NO solucionará el problema. En su lugar, uno tiene que simplemente eliminar y volver a crear el segue en el guión gráfico.

Cuando se recrea, el guión gráfico xml ya no tendrá una acción asociada con el segue particular y el Show se ejecutará como un Push.

Ejemplo de Xml para el Show Segue correcto

     

Mitigación

Para evitar recurrencia uno solo necesita atenerse a los guiones del guión gráfico no manual, si es posible, usando prepareForSegue para agregar acciones requeridas basadas en el controlador de vista de destino. O si debe mezclar y combinar, tome la precaución de verificar que sus segmentaciones de muestra no tengan ninguna acción adjunta en el guión gráfico xml. Si está tratando con proyectos anteriores, debe prestar especial atención al código fuente de Storyboard, ya que he descubierto algunos problemas.

Como comentó Scott Robertson aquí , esto parece un error en iOS 7.

Parece que en iOS 8 la transición se deduce en tiempo de ejecución (comportamiento correcto), mientras que en iOS 7 la transición se deduce en el momento del diseño (comportamiento con errores).

La solución más simple es agregar un controlador de navegación no utilizado al guión gráfico y vincularlo para que el controlador de vista en cuestión sea parte de este controlador de navegación. En realidad, no tiene que crear una instancia del controlador de navegación, solo necesita que el controlador de vista defectuoso sepa que está incrustado en un controlador de navegación.

Nota: Simular una barra de navegación no es suficiente para estos fines; en realidad debe tener un controlador de navegación en su stack de inserción.

Para reproducir el error:

  1. Crea un nuevo guión gráfico que use clases de tamaño.
  2. Cree dos controladores de vista (sin controladores de navegación).
  3. Haga que el controlador de primera vista muestre el segundo controlador de vista a través de una transición de Mostrar (por ejemplo, pulsar) vinculada a un botón, por ejemplo.
  4. En el código, muestre el primer controlador de vista, pero initWithRootViewController: en un controlador de navegación a través del método initWithRootViewController: .
  5. Ejecute la aplicación en iOS 7.
  6. Toca el botón que debe realizar el empuje.
  7. Obtendrás una transición modal en lugar de un push en iOS 7. En iOS 8 obtendrás el comportamiento de push correcto.

enter image description here

Para arreglar el error:

  1. Agregue un controlador de navegación al guión gráfico y configure el primer controlador de vista para que sea el controlador de la vista raíz. (Nota: agregar el segundo porque el controlador de vista raíz NO solucionará este error).
  2. Proporcione un identificador de basura para suprimir la advertencia de que el controlador de navegación es inaccesible y para documentarse que existe únicamente como una solución alternativa. (por ejemplo, workaround for show segues in iOS 7 ).

enter image description here

Observe cómo se agregó el controlador de navegación en la segunda imagen y cómo no tiene ninguna flecha entrante (es decir, no hay forma de instanciarlo de otra forma que no sea usar su identificador de controlador de vista).

Sé que llego tarde a esto, pero quería compartir lo que aprendí. Esto es de hecho un error y todavía está presente hoy (2014-12-18).

Escribí un artículo sobre esto aquí .

Es fácilmente reproducible; en iOS8 funcionará bien e incluso en iOS7.x, siempre y cuando no coloques un controlador de vista programáticamente en la stack antes de llamar a Show segue.

Si solo presionas a la stack con las conexiones del guión gráfico, funcionará; pero aparentemente, si presionas el código de algún modo, la propiedad navigationController del UIViewController presionado será nil y cuando llamas a Show asumirá que es un modal porque no hay navegación para controlar la stack.

Hasta ahora, la solución alternativa no es enviar por código (no es factible) o usar la versión ahora obsoleta.

Archivé un radar (enlace en el artículo). Siéntase libre de presentar duplicados con la esperanza de que Apple solucione este problema.

Tuve el mismo problema con los segmentos en Xcode 7 y iOS 7.1.2. Mostrar segues (nueva función de iOS 8) funciona como segues modales en iOS 7 y no le permite insertar sus Controladores de Vista en la stack del Controlador de Navegación cuando define el tipo de segue con Xcode en su Guión Gráfico. Es por eso que su controlador self.navigation devolverá nil, porque el controlador de vista no fue empujado a la stack y no se puede abrir.

No entiendo por qué Apple no agregó ninguna notificación para este caso en Xcode cuando necesita que su aplicación funcione en iOS 7. Dicen que el método Push está obsoleto, pero Show no funciona correctamente con iOS 7.

¿Qué he hecho para resolver el problema?

Creé la clase MYShowSegue con .h

 #import  @interface MYShowSegue : UIStoryboardSegue @end 

Y archivo .m con solo un método de ejecución :

 #import "MYShowSegue.h" @implementation MYShowSegue - (void) perform { if ([[[self sourceViewController] navigationController] respondsToSelector:@selector(showViewController:sender:)]) { id sender = nil; [[[self sourceViewController] navigationController] showViewController:[self destinationViewController] sender:sender]; }else{ [[[self sourceViewController] navigationController] pushViewController:[self destinationViewController] animated:YES]; } } @end 

De lo que necesita es configurar un tipo personalizado para cada transición en su Storyboard y seleccionar una nueva clase para él, en mi caso fue MYShowSegue.

Ejemplo personalizado de Segue

Esta solución le ayudará a obtener un soporte completo de sus aplicaciones iOS 7, usarán el método pushViewController para impulsar sus Vistas y para iOS 8,9 etc. su transición funcionará con el nuevo método (iOS 8) showViewController

No olvide hacer lo mismo con todos sus segmentos en su Storyboard.

Esto todavía está sucediendo en iOS 10.x

Eliminar y volver a instalar segues no me solucionó nada:

Problema: la funcionalidad requerida era de 7 segues que solo funcionan como un ‘push’ (en realidad un show Detail) pero, de hecho, solo el primer segue que añadí sería push, los demás se comportarían de forma modal. Esto a pesar de que Interface Builder describe cada uno de los segmentos de forma idéntica.

Solución: Tuve que agregar la acción a los 6 segmentos que no la tenían.

Original Storyboard XML

          

Cambié esto agregando showViewController: remitente