Segue adaptativo en storyboard Xcode 6. ¿Está en desuso push?


Xcode 6 interface builder por defecto tiene una nueva casilla de verificación "usar clases de tamaño". Hace que las vistas se adapten. introduzca la descripción de la imagen aquí

Cuando trato de hacer segue entre 2 vistas en mi storyboard Tengo nuevas opciones: introduzca la descripción de la imagen aquí

En lugar de viejo:

introduzca la descripción de la imagen aquí

Ahora tenemos "show" y "present modally" en lugar de "push" y "modal". Las opciones antiguas están marcadas como obsoletas. He elegido la opción "show", porque en la configuración de segue se llama "show (e. g. push)

introduzca la descripción de la imagen aquí

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

La pregunta es: ¿Cómo puedo hacer que" mostrar " funcione como empujar? ¿Es posible o debería usar "push (obsoleto)" en su lugar? ¿Dónde puedo encontrar información sobre nuevos tipos de segue? Lo único que he encontrado en IOS8 developer library es Los storyboards Lo Ayudan a Diseñar Su Interfaz de Usuario pero no hay información sobre "show" segue.

ACTUALIZACIÓN

Traté de crear un nuevo proyecto y "mostrar" es realmente funciona como "empujar". Creo que el problema en mi proyecto puede ser porque reutilizo el controlador de navegación con código como este, pero no se 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 intento empujar NewViewController después de MainViewController introduzca la descripción de la imagen aquí

ACTUALIZACIÓN 2:

Parece ser solo iOS 7, iOS 7.1 problema.

Author: inorganik, 2014-06-12

7 answers

Sí, usa ' Show 'en lugar de'Push'

¿Cómo puedo hacer que" mostrar " funcione como empujar? Es posible o debo usar "empuje (depricated)" en su lugar?

Debería; lo hace para mí. Estoy usando Xcode 6 beta 2 y para probar usé la plantilla de vista única (llamando al controlador de vista pre hecho 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 storyboard y hacer VC_A el rootViewController, tanto 'push' como 'show' tienen el mismo efecto. Si no tengo un controlador de navegación inicial y uso 'show' obtengo lo que describiste en que el VC_B hace una diapositiva hacia arriba desde la parte inferior. Si intento 'empujar' me sale un crash ya que para hacer push debo tener un controlador de navegación. Por lo tanto, parecería que 'show' hará un push en el caso de que se proporcione un controlador de navegación y hará un presente con un modal estilo de transición si un 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 'Qué hay de nuevo en Interface Builder' aquí. Si usted mira las diapositivas verá una diapositiva (41) mencionar el cambio. Al ver ese video de la sesión, puede saltar al minuto 38: 00 donde comienzan a hablar sobre las secuencias adaptativas. Ellos explican que el 'show' adaptive segue, por ejemplo, toma en cuenta el contexto al decidir cómo hacer la presentación de un nuevo controlador de vista.

 93
Author: Spencer Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-06 06:36:38

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, las secuencias "push" y "modal" fueron obsoletas, y han sido reemplazadas por "show" y "present modally" respectivamente. Según la documentación de Apple, los nuevos segues se han dividido en segues que se adaptan a las clases de tamaño. Los más antiguos 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 segues disponibles, antiguos y nuevos.

Agregar una secuencia Entre Escenas en un Storyboard

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

Mostrar

Presente el contenido en el área de detalle o maestro dependiendo del contenido de la pantalla. Si la aplicación muestra una vista maestra y de detalle, el contenido se envía en el área de detalle. Si la aplicación solo muestra el maestro o el detalle, el contenido se coloca en la parte superior de la pila de view controller actual.

Mostrar detalle

Presente el contenido en el área de detalles. Si la aplicación muestra una vista maestra y de detalle, 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 pila actual de view controller.

Presente Modalmente

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

Presente como Popover

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

 32
Author: alondono,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-02 23:18:48

Tldr; Elimine el Segue que no se está empujando correctamente y vuelva a crearlo en el guion gráfico arrastrando desde un UIView / UIControl al destino controlador de vista.

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

Antecedentes

En mi caso, ninguno de mis Segues de Show estaba funcionando a pesar de que ya tenía un UINavigationController como mi controlador de vista inicial (con mi contenido UIViewController como root).

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

El Show segue se rompe cuando tiene una acción asociada con el segue dentro del xml de origen del guion gráfico. Un escenario típico que causa esto podría ser si ha redefinido un segue de un segue manual previamente llamado en código. Esto deja los siguientes bits en el xml del guion gráfico.

<connections>
    <segue destination="85t-Z1-hxf" kind="show" identifier="ToOptions" action="showDetailViewController:sender:" id="gdZ-IX-KcN">
</connections>

Nota Bene Para ver el guion gráfico como xml; Haga clic con el botón derecho en el archivo del guion gráfico y elija Abrir como > Código fuente . Para revertir el uso Abrir como > Constructor de interfaz-Storyboard

Para acomodar cualquier acción personalizada al usar el segue del guion gráfico, uno puede simplemente aprovechar 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 se redefine el segue no es configurar 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).

Desafortunadamente la solución más directa falla. Así que simplemente eliminando el atributo xml para la acción desde el Storyboard NO solucionará el problema. En su lugar, uno tiene que simplemente eliminar y recrear el segue en el guion gráfico.

Cuando se recrea el xml del storyboard ya no tendrá una acción asociado con el segue particular y el Espectáculo se ejecutará como un Empuje.

Ejemplo de Xml para mostrar correctamente Segu

  <connections>
    <segue destination="RbV-Au-WV9" kind="show" identifier="ToOptions" id="5dm-os-bcS"/>
  </connections>

Mitigación

Para evitar la recurrencia, solo tiene que atenerse a secuencias de guion gráfico no manuales si es posible mediante el uso de prepareForSegue para agregar las acciones necesarias basadas en el controlador de vista de destino. O si debe mezclar y combinar, tome la precaución de verificar que las secuencias de su programa no tengan ninguna acción adjunta en el guion gráfico XML. Si está tratando con proyectos más antiguos, debe prestar especial atención al código fuente del guion gráfico, ya que he descubierto algunos problemas.

 23
Author: Tommie C.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-27 19:23:41

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

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

La solución más simple es agregar un controlador de navegación no utilizado al guion gráfico y vincularlo para que el controlador de vista en cuestión sea parte de este controlador de navegación. En realidad no tienes que crear una instancia de la navegación controlador, solo necesita el controlador de vista con errores para saber que está incrustado en un controlador de navegación.

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

Para reproducir el error:

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

introduzca la descripción de la imagen aquí

Para arreglar el error:

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

introduzca la descripción de la imagen aquí

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 que no sea usando su identificador de controlador de vista).

 20
Author: Senseful,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:32

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 empuje un controlador de vista programáticamente en la pila antes de llamar al segue Show.

Si solo envías a la pila usando conexiones de storyboard, funcionará; pero aparentemente si envías a través de código de alguna manera la propiedad navigationController del empujado UIViewController será nil y cuando llame a Show asumirá que es un modal porque no hay navegación para controlar la pila.

Hasta ahora, la única solución alternativa no es push vía código (no es factible) o usar el ahora obsoleto Push.

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

 13
Author: esttorhe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-19 01:36:33

Tuve el mismo problema con las secuencias en Xcode 7 y iOS 7.1.2. Mostrar segues (nueva característica de iOS 8) funciona como segues modales en iOS 7 y no le permite empujar sus Controladores de vista en la pila de controladores de navegación cuando define el tipo de segue con Xcode en su guion gráfico. Por eso eres tú mismo.NavigationController devolverá nil, porque el Controlador de vista no fue empujado a la pila y no se puede pop.

No entiendo por qué Apple no agregó ninguna notificaciones 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:

He creado la clase MYShowSegue con .h

#import <UIKit/UIKit.h>

@interface MYShowSegue : UIStoryboardSegue

@end

Y .archivo m con solo un método perform :

#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

Entonces necesitas establecer un tipo Personalizado para cada segue en tu Storyboard y seleccionar una nueva clase para él, en mi caso fue MYShowSegue.

Ejemplo de Segue personalizado

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

No olvides hacer lo mismo con todas tus segues en tu Storyboard.

 2
Author: Igor Tikhonov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-17 10:29:56

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

Eliminar y reinstalar segues no solucionó nada para mí:

Problema: La funcionalidad Requred era de 7 segues que solo funcionan como un 'push' (en realidad un Detalle de show) pero de hecho solo el primer segue que agregué empujaría, los otros se comportarían modalmente. Esto es a pesar de que Interface Builder describe cada una de las secuencias de forma idéntica.

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

ORIGINAL Storyboard XML

<connections>
  <segue destination="tIr-4a-WfZ" kind="showDetail" identifier="A" action="showViewController:sender:" id="8yd-Ne-7KA"/>
  <segue destination="4mB-YE-5dM" kind="showDetail" identifier="B" id="Uod-JC-786"/>
  <segue destination="Qh5-bJ-KcE" kind="showDetail" identifier="C" id="3PW-nV-hWl"/>
  <segue destination="EI6-f4-QBB" kind="showDetail" identifier="D" id="WUK-ju-KDm"/>
  <segue destination="nTz-N4-fpW" kind="showDetail" identifier="E" id="Id6-bW-Huc"/>
  <segue destination="JEp-CH-6dW" kind="showDetail" identifier="F" id="G0L-XW-7f4"/>
  <segue destination="AET-S1-O6h" kind="showDetail" identifier="G" id="3NK-93-wTy"/>
</connections>

Cambié esto añadiendo showViewController: sender

<connections>
  <segue destination="tIr-4a-WfZ" kind="showDetail" identifier="A" action="showViewController:sender:" id="8yd-Ne-7KA"/>
  <segue destination="4mB-YE-5dM" kind="showDetail" identifier="B" action="showViewController:sender:" id="Uod-JC-786"/>
  <segue destination="Qh5-bJ-KcE" kind="showDetail" identifier="C" action="showViewController:sender:" id="3PW-nV-hWl"/>
  <segue destination="EI6-f4-QBB" kind="showDetail" identifier="D" action="showViewController:sender:" id="WUK-ju-KDm"/>
  <segue destination="nTz-N4-fpW" kind="showDetail" identifier="E" action="showViewController:sender:" id="Id6-bW-Huc"/>
  <segue destination="JEp-CH-6dW" kind="showDetail" identifier="F" action="showViewController:sender:" id="G0L-XW-7f4"/>
  <segue destination="AET-S1-O6h" kind="showDetail" identifier="G" action="showViewController:sender:" id="3NK-93-wTy"/>
</connections>
 1
Author: Damo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-23 12:10:50