Push segue no xcode sem animação

90

Estou usando o storyboard normal e as segues push no xcode, mas quero que as segues apareçam apenas na próxima exibição, não deslizando a próxima exibição (como quando você usa uma barra de guias e a próxima exibição simplesmente aparece).

Existe uma maneira simples e agradável de fazer com que segues push normais apenas "apareçam" e não "deslize", sem a necessidade de adicionar segues personalizados?

Tudo está funcionando perfeitamente bem, eu só quero remover aquela animação de slide entre as visualizações.

Richard
fonte
Acabei de tentar mudar a segue push para uma segue modal, pois isso pode me permitir remover a animação, mas eu tenho um tableview com uma barra de ferramentas superior, e definir a segue como modal remove esta barra superior e não consigo encontrar nenhuma maneira para adicionar a barra superior de volta! Portanto, preciso de uma solução que não anime a transição, mas não interrompa meu tableview.
Richard,

Respostas:

143

Consegui fazer isso criando uma segue personalizada (com base neste link ).

  1. Crie uma nova classe segue (veja abaixo).
  2. Abra seu Storyboard e selecione a segue.
  3. Defina a classe como PushNoAnimationSegue(ou como você decidiu chamá-la).

Especifique a classe segue no 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)
    }
}

Objetivo 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
fonte
Obrigado pelo comentário e contribuição.
Richard
11
Melhor resposta. Alguma idéia de conseguir o mesmo para a animação de fundo?
Thomas,
1
Funciona como um encanto. Essa também é a maneira "correta" de fazer isso com segues de storyboard.
Jeff Richley
1
Alguém parou a animação de fundo para a resposta acima?
Imran
4
Não é a solução, a segue personalizada se apresenta em todo o layout como um push segue modal, enquanto o segue push original honra a janela.frame navigationController tabBarController etc ... como alguém configura a segue para se comportar como um segue push em vez de um modal ? ou ... a pergunta de $ 1.000.000, como especificar animações = NÃO ao configurar uma segue regular usando STORYBOARDS
Pedro Borges,
49

Você pode desmarcar "Animates" no Interface Builder para iOS 9

insira a descrição da imagem aqui

dtochetto
fonte
3
Esta é a resposta à pergunta original! Outras respostas mostram como fazer isso em código objc / swift, enquanto dtochetto usa apenas Xcode (como solicitado na pergunta original).
drpawelo
no entanto, para uma sequência descontraída, não parece funcionar
Nicolas Manzini
2
Esta é a solução melhor e mais rápida, infelizmente não funciona no iOS 8.
EricH206
2
@DanielT. Talvez você possa arrastar 2 segue no storyboard, um com animação e outro sem animação. Dê a eles um Identifiernome diferente .
AechoLiu
1
Observe que o XCode apenas adiciona um atributo ao elemento segue no arquivo .storyboard. Você pode editar manualmente o arquivo .storyboard e adicionar animates = "NO" às sequências que lhe interessam se estiver usando o Visual Studio e a marca de seleção não estiver disponível no designer.
Wes
35

A resposta de Ian funciona muito bem!

Esta é uma versão Swift do Segue, se alguém precisar:

ATUALIZADO PARA SWIFT 5, MAIO 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é
fonte
2
Provavelmente devido à versão Swift, eu precisava "como!" em vez de "como" nos dois lugares em que você os usa.
Carlos
1
Hm talvez em Swift 1.2? Eu verifiquei com o Swift 2.0 no Xcode 7 Beta1 e ele compilou sem quaisquer avisos.
zavié
6

Agora consegui fazer isso usando o seguinte 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 isso ajude mais alguém!

Richard
fonte
Você pode apenas adicionar isso à ação de um UIButton ou qualquer outra coisa. Se você deseja pular para um novo controlador de visualização sem animação, pode usar: - void (yourUIButtonAction) {CreditsViewController * creditspage = [self.storyboard instantiateViewControllerWithIdentifier: @ "Credits"]; [self.navigationController pushViewController: página de créditos animada: NÃO]; }
Richard
Isso nem mesmo está respondendo à pergunta. Você não está usando segue aqui!
KIDdAe
4

Esta é a versão do Swift adaptada para apresentar modalmente um ViewController sem animação:

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
fonte
1
Este código foi copiado da resposta de @zavié, não adicionando nada, mas é pior: sem verificação de opcionais incluídos
Diego Freniche
Isso é diferente da resposta de @ zavié porque mostra como modal apresentar um ViewController sem animation.Nice para tê-lo aqui como referência, já que é algo relacionado à pergunta.
n.Drake
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
fonte
1

Para qualquer pessoa que use o Xamarin iOS, sua classe segue personalizada precisa ser assim:

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

    }

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

Não se esqueça de que você ainda precisa definir um segue personalizado em seu storyboard e definir a classe para a classe PushNoAnimationSegue.

JacobK
fonte
0

Para mim, a maneira mais fácil de fazer isso é:

UIView.performWithoutAnimation { 

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

    }

Disponível no iOS 7.0

LironXYZ
fonte
Se estiver usando segues adaptáveis, acredito que, embora performWithoutAnimation defina animações desabilitadas, antes que a segue seja realizada, as animações são habilitadas novamente se a segue tiver "animates" marcado. Depois de executar, no entanto, ele os desativa novamente, se antes.
malhal
Mas você pode contornar isso criando uma subclasse UIStoryboardSegue e desabilitando as animações novamente antes de executar (por exemplo, usando o construtor para verificar se elas estão desabilitadas e armazenando-as em uma propriedade).
malhal
0

Estou usando o Visual Studio c / Xamarin e o designer não fornece a marca de seleção "Animates" na resposta de dtochetto.

Observe que o designer XCode aplicará o seguinte atributo ao elemento segue no arquivo .storyboard: animates = "NO"

Eu editei manualmente o arquivo .storyboard e adicionei animates = "NO" ao (s) elemento (s) segue, e funcionou para mim.

Exemplo:

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

PUSH SEM ANIMAÇÃO: Swift Aqui está o que funcionou para mim.

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 : Defina a classe segue do storyboard como mostrado na imagem. defina isAnimationRequired de seu viewcontroller como false de onde você deseja chamar performSegue, quando você deseja empurrar segue sem animação e definir novamente como true após chamar self.performSegue. Boa sorte ....

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

definir a classe segue do storyboard, conforme mostrado na imagem.

Usman
fonte
-1

Basta definir animated falsa sobre UINavigationController.pushViewControllerem Swift

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