Empuje segue en xcode sin animación

90

Estoy usando el guión gráfico normal y empujar segues en xcode, pero quiero tener segues que solo aparezcan en la siguiente vista, no deslice la siguiente vista (como cuando usas una barra de pestañas y simplemente aparece la siguiente vista).

¿Existe una forma sencilla y agradable de hacer que los segmentos de empuje normales simplemente "aparezcan" y no se "deslicen", sin necesidad de agregar segmentos personalizados?

Todo está funcionando completamente bien, solo quiero eliminar esa animación de diapositiva entre las vistas.

Ricardo
fuente
Acabo de intentar cambiar el segue de empuje a un segue modal, ya que eso me puede permitir eliminar la animación, pero tengo una vista de tabla con una barra de herramientas superior, y configurar el segue en modal elimina esta barra superior, y no puedo encontrar ninguna forma para volver a añadir la barra superior! Así que necesito una solución que no anime la transición, pero que no rompa mi vista de tabla.
Richard

Respuestas:

143

Pude hacer esto creando un segue personalizado (basado en este enlace ).

  1. Cree una nueva clase de segue (ver más abajo).
  2. Abra su Storyboard y seleccione el segue.
  3. Establece la clase en PushNoAnimationSegue(o como decidas llamarla).

Especifique la clase segue en Xcode

Rápido 4

import UIKit

/*
 Move to the next screen without an animation.
 */
class PushNoAnimationSegue: UIStoryboardSegue {

    override func perform() {
        self.source.navigationController?.pushViewController(self.destination, animated: false)
    }
}

C objetivo

PushNoAnimationSegue.h

#import <UIKit/UIKit.h>

/*
 Move to the next screen without an animation.
 */
@interface PushNoAnimationSegue : UIStoryboardSegue

@end

PushNoAnimationSegue.m

#import "PushNoAnimationSegue.h"

@implementation PushNoAnimationSegue

- (void)perform {

    [self.sourceViewController.navigationController pushViewController:self.destinationViewController animated:NO];
}

@end
Ian
fuente
Gracias por el comentario y la entrada.
Richard
11
La mejor respuesta. ¿Alguna idea sobre cómo lograr lo mismo para la animación trasera?
Thomas
1
Funciona de maravilla. Esta es también la forma "correcta" de hacerlo con los guiones gráficos.
Jeff Richley
1
¿Alguien ha detenido la animación trasera para la respuesta anterior?
Imran
4
No es LA solución, el segue personalizado se presenta en todo el diseño como un empuje modal mientras que el segue de empuje original honra window.frame navigationController tabBarController etc ... ¿Cómo se configura el segue para que se comporte como un segue push en lugar de como un segue modal? ? o ... la pregunta de $ 1.000.000, ¿cómo se especifican las animaciones = NO cuando se configura una transición regular usando STORYBOARDS
Pedro Borges
49

Puede desmarcar "Animaciones" en Interface Builder para iOS 9

ingrese la descripción de la imagen aquí

dtochetto
fuente
3
¡Esta es la respuesta a la pregunta original! Otras respuestas muestran cómo lograr esto en objc / código swift, mientras que dtochetto usa solo Xcode (como se solicitó en la pregunta original).
drpawelo
sin embargo, para la transición de relajación no parece funcionar
Nicolas Manzini
2
Esta es la mejor y más rápida solución, desafortunadamente no funciona en iOS 8.
EricH206
2
@DanielT. Tal vez, puede arrastrar 2 segue en el guión gráfico, uno tiene animación y otro no tiene animación. Dales un Identifiernombre diferente .
AechoLiu
1
Tenga en cuenta que XCode simplemente agrega un atributo al elemento segue en el archivo .storyboard. Puede editar manualmente el archivo .storyboard y agregar animates = "NO" a las secuencias que le interesan si está utilizando Visual Studio y la marca de verificación no está disponible en el diseñador.
Wes
35

¡La respuesta de Ian funciona muy bien!

Aquí hay una versión Swift de Segue, si alguien la necesita:

ACTUALIZADO PARA SWIFT 5, MAYO DE 2020

PushNoAnimationSegue.swift

import UIKit

/// Move to the next screen without an animation
class PushNoAnimationSegue: UIStoryboardSegue {
override func perform() {
    if let navigation = source.navigationController {
        navigation.pushViewController(destination as UIViewController, animated: false)
    }
}
zavié
fuente
2
Probablemente debido a la versión Swift, necesitaba "¡como!" en lugar de "como" en los dos lugares donde los usa.
Carlos
1
¿Quizás en Swift 1.2? Verifiqué con Swift 2.0 en Xcode 7 Beta1 y se compiló sin ninguna advertencia.
zavié
6

Ahora he logrado hacer esto usando el siguiente código:

CreditsViewController *creditspage = [self.storyboard instantiateViewControllerWithIdentifier:@"Credits"];
[UIView beginAnimations:@"flipping view" context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:YES];
[self.navigationController pushViewController:creditspage animated:NO];
[UIView commitAnimations];

¡Espero que esto ayude a alguien más!

Ricardo
fuente
Puede agregar esto a la acción de un UIButton o lo que sea. Si desea saltar a un nuevo controlador de vista sin animación, puede usar: - void (yourUIButtonAction) {CreditsViewController * Creditpage = [self.storyboard instantiateViewControllerWithIdentifier: @ "Credits"]; [self.navigationController pushViewController: página de créditos animada: NO]; }
Richard
Esto ni siquiera responde a la pregunta. ¡No estás usando segue aquí!
KIDdAe
4

Aquí está la versión Swift adaptada para presentar modalmente un ViewController sin animación:

import UIKit

/// Present the next screen without an animation.
class ModalNoAnimationSegue: UIStoryboardSegue {

    override func perform() {
        self.sourceViewController.presentViewController(
            self.destinationViewController as! UIViewController,
            animated: false,
            completion: nil)
    }

}
Daniel McLean
fuente
1
Este código se copia de la respuesta de @ zavié, sin agregar nada, pero de hecho es peor: no se incluye verificación de opciones
Diego Freniche
Esto es diferente de la respuesta de @ zavié porque muestra cómo modal presentar un ViewController sin animation.Nice tenerlo aquí como referencia ya que es algo relacionado con la cuestión.
n
2

responder usando Swift3 -

para segue "push":

class PushNoAnimationSegue: UIStoryboardSegue
{
    override func perform()
    {
       source.navigationController?.pushViewController(destination, animated: false)
    }
}

para segue "modal":

class ModalNoAnimationSegue: UIStoryboardSegue
{
    override func perform() {
        self.source.present(destination, animated: false, completion: nil)
    }
}
elkorb
fuente
1

Para cualquiera que use Xamarin iOS, su clase segue personalizada debe tener este aspecto:

[Register ("PushNoAnimationSegue")]
public class PushNoAnimationSegue : UIStoryboardSegue
{
    public PushNoAnimationSegue(IntPtr handle) : base (handle)
    {

    }

    public override void Perform ()
    {
        SourceViewController.NavigationController.PushViewController (DestinationViewController, false);
    }
}

No olvide que todavía necesita establecer una transición personalizada en su guión gráfico y establecer la clase en la clase PushNoAnimationSegue.

JacobK
fuente
0

Para mí, la forma más sencilla de hacerlo es:

UIView.performWithoutAnimation { 

        self.performSegueWithIdentifier("yourSegueIdentifier", sender: nil)

    }

Disponible desde iOS 7.0

LironXYZ
fuente
Si utilizo segues adaptables, creo que aunque performWithoutAnimation establece las animaciones deshabilitadas, antes de que se realice la segue, las animaciones se habilitan nuevamente si la segue tiene "animates" marcada. Después de realizarlo, sin embargo, los vuelve a deshabilitar si anteriormente lo estaba.
malhal
Pero puede solucionarlo creando una subclase UIStoryboardSegue y deshabilitando las animaciones nuevamente antes de la ejecución (por ejemplo, usando el constructor para verificar si están deshabilitadas y almacenándolas en una propiedad).
Malhal
0

Estoy usando Visual Studio con Xamarin y el diseñador no proporciona la marca de verificación "Animates" en la respuesta de dtochetto.

Tenga en cuenta que el diseñador de XCode aplicará el siguiente atributo al elemento segue en el archivo .storyboard: animates = "NO"

Edité manualmente el archivo .storyboard y agregué animates = "NO" a los elementos de segue, y funcionó para mí.

Ejemplo:

 <segue id="1234" destination="ZB0-vP-ctU" kind="modal" modalTransitionStyle="crossDissolve" animates="NO" identifier="screen1ToScreen2"/>
Wes
fuente
0

PUSH SIN ANIMACIÓN: Swift Esto es lo que funcionó para mí.

import ObjectiveC

private var AssociatedObjectHandle: UInt8 = 0
    extension UIViewController {

        var isAnimationRequired:Bool {
            get {
        return (objc_getAssociatedObject(self, &AssociatedObjectHandle) as? Bool) ?? true
            }
            set {
                objc_setAssociatedObject(self, &AssociatedObjectHandle, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
    }

    -------------------- SilencePushSegue --------------------

class SilencePushSegue: UIStoryboardSegue {

    override func perform() {
        if self.source.isAnimationRequired == false {
            self.source.navigationController?.pushViewController(self.destination, animated: false)
        }else{
            self.source.navigationController?.pushViewController(self.destination, animated: true)
        }
    }
}

Uso : configure la clase de segue del guión gráfico como se muestra en la imagen. establezca isAnimationRequired de su viewcontroller en false desde donde desea llamar a performSegue, cuando desee presionar segue sin animación y vuelva a establecer en true después de llamar a self.performSegue. La mejor de las suertes....

DispatchQueue.main.async {
                self.isAnimationRequired = false
                self.performSegue(withIdentifier: "showAllOrders", sender: self);
                self.isAnimationRequired = true
            }

establezca la clase de segue del guión gráfico como se muestra en la imagen.

Usman
fuente
-1

Sólo hay que establecer animated falsa sobre UINavigationController.pushViewControlleren Swift

self.navigationController!.pushViewController(viewController, animated: false)
Miguel
fuente