Push segue dans xcode sans animation

90

J'utilise le storyboard normal et les ségues push dans xcode, mais je veux avoir des segues qui apparaissent simplement dans la vue suivante, et non dans la vue suivante (comme lorsque vous utilisez une barre d'onglets et que la vue suivante apparaît juste).

Existe-t-il un moyen simple et agréable de faire "apparaître" des segments push normaux et non de "glisser", sans avoir besoin d'ajouter des segments personnalisés?

Tout fonctionne parfaitement, je veux simplement supprimer cette animation de diapositive entre les vues.

Richard
la source
Je viens d'essayer de changer la séquence de poussée en une séquence modale, car cela peut me permettre de supprimer l'animation, mais j'ai une vue de table avec une barre d'outils supérieure, et la définition de la séquence sur modale supprime cette barre supérieure, et je ne trouve aucun moyen pour rajouter la barre supérieure! J'ai donc besoin d'une solution qui n'anime pas la transition, mais qui ne brise pas ma tableview.
Richard

Réponses:

143

J'ai pu le faire en créant une séquence personnalisée (basée sur ce lien ).

  1. Créez une nouvelle classe segue (voir ci-dessous).
  2. Ouvrez votre Storyboard et sélectionnez la séquence.
  3. Définissez la classe sur PushNoAnimationSegue(ou ce que vous avez décidé de l'appeler).

Spécifier la classe segue dans Xcode

Swift 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)
    }
}

Objectif c

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
la source
Merci pour le commentaire et la contribution.
Richard
11
Meilleure réponse. Des idées pour réaliser la même chose pour l'animation arrière?
Thomas
1
Fonctionne comme un charme. C'est aussi la manière «correcte» de le faire avec les séquences de storyboard.
Jeff Richley
1
Quelqu'un at-il arrêté l'animation de retour pour la réponse ci-dessus.
Imran
4
Pas LA solution, le segue personnalisé se présente sur toute la mise en page comme un push modal tandis que le push segue original honore window.frame navigationController tabBarController etc ... comment configurer le segue pour qu'il se comporte comme un push segue au lieu de comme un modal segue ? ou ... la question à $ 1.000.000, comment spécifie-t-on des animations = NON lors de la configuration d'une séquence régulière à l'aide de STORYBOARDS
Pedro Borges
49

Vous pouvez décocher "Animation" dans Interface Builder pour iOS 9

entrez la description de l'image ici

dtochetto
la source
3
C'est la réponse à la question initiale! D'autres réponses montrent comment y parvenir en code objc / swift, tandis que dtochetto n'utilise que Xcode (comme demandé dans la question d'origine).
drpawelo
cependant, pour la séquence de déroulement, cela ne semble pas fonctionner
Nicolas Manzini
2
C'est la solution la meilleure et la plus rapide, malheureusement cela ne fonctionne pas sur iOS 8.
EricH206
2
@DanielT. Peut-être que vous pouvez faire glisser 2 segue sur le storyboard, l'un avec une animation et l'autre sans animation. Donnez-leur un Identifiernom différent .
AechoLiu
1
Notez que XCode ajoute simplement un attribut à l'élément segue dans le fichier .storyboard. Vous pouvez modifier manuellement le fichier .storyboard et ajouter animates = "NO" aux segues qui vous intéressent si vous utilisez Visual Studio et que la coche n'est pas disponible dans le concepteur.
Wes
35

La réponse d'Ian fonctionne très bien!

Voici une version Swift de la Segue, si quelqu'un en a besoin:

MISE À JOUR POUR SWIFT 5, MAI 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é
la source
2
Probablement à cause de la version Swift, j'avais besoin de "as!" au lieu de "comme" dans les deux endroits où vous les utilisez.
Carlos
1
Hm peut-être dans Swift 1.2? J'ai vérifié avec Swift 2.0 dans Xcode 7 Beta1 et il a été compilé sans aucun avertissement.
zavié
6

J'ai maintenant réussi à le faire en utilisant le code suivant:

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];

J'espère que ceci aide quelqu'un d'autre!

Richard
la source
Vous pouvez simplement ajouter ceci à l'action d'un UIButton ou autre. Si vous voulez passer à un nouveau contrôleur de vue sans animation, vous pouvez utiliser: - void (yourUIButtonAction) {CreditsViewController * creditspage = [self.storyboard instantiateViewControllerWithIdentifier: @ "Credits"]; [self.navigationController pushViewController: page de crédits animée: NON]; }
Richard
Cela ne répond même pas à la question. Vous n'utilisez pas segue ici!
KIDdAe
4

Voici la version Swift adaptée pour présenter modalement un ViewController sans animation:

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
la source
1
Ce code est copié à partir de la réponse @ zavié, sans rien ajouter, mais c'est en effet pire: pas de chèque pour les options incluses
Diego Freniche
Ceci est différent de la réponse de @ zavié car elle montre comment présenter de manière modale un ViewController sans animation.
n.Drake
2

réponse en utilisant Swift3 -

pour "push" segue:

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

pour la séquence "modale":

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

Pour toute personne utilisant Xamarin iOS, votre classe de segue personnalisée doit ressembler à ceci:

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

    }

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

N'oubliez pas que vous devez toujours définir une séquence personnalisée dans votre storyboard et définir la classe sur la classe PushNoAnimationSegue.

JacobK
la source
0

Pour moi, le moyen le plus simple de le faire est:

UIView.performWithoutAnimation { 

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

    }

Disponible à partir d'iOS 7.0

LironXYZ
la source
Si vous utilisez des segues adaptatives, je crois bien que performWithoutAnimation définit les animations désactivées, avant que la segue ne soit effectuée, les animations sont à nouveau activées si la segue a coché "animates". Après avoir exécuté, il les désactive cependant à nouveau si auparavant.
malhal
Mais vous pouvez contourner cela en créant une sous-classe UIStoryboardSegue et en désactivant à nouveau les animations avant l'exécution (par exemple en utilisant le constructeur pour vérifier si elles sont désactivées et en les stockant dans une propriété).
malhal
0

J'utilise Visual Studio avec Xamarin et le concepteur ne fournit pas la coche «Animates» dans la réponse de dtochetto.

Notez que le concepteur XCode appliquera l'attribut suivant à l'élément segue dans le fichier .storyboard: animates = "NO"

J'ai édité manuellement le fichier .storyboard et ajouté animates = "NO" aux éléments de segue, et cela a fonctionné pour moi.

Exemple:

 <segue id="1234" destination="ZB0-vP-ctU" kind="modal" modalTransitionStyle="crossDissolve" animates="NO" identifier="screen1ToScreen2"/>
Nous s
la source
0

PUSH SANS ANIMATION: Swift Voici ce qui a fonctionné pour moi.

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)
        }
    }
}

Utilisation : définissez la classe segue à partir du storyboard comme indiqué dans l'image. définissez isAnimationRequired de votre viewcontroller sur false à partir de l'endroit où vous souhaitez appeler performSegue, lorsque vous souhaitez pousser segue sans animation et redéfini sur true après avoir appelé self.performSegue. Bonne chance....

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

définir la classe segue à partir du storyboard comme indiqué dans l'image.

Usman
la source
-1

Il suffit de régler animated faux sur UINavigationController.pushViewControllerSwift

self.navigationController!.pushViewController(viewController, animated: false)
Michael
la source