Wypchnij segue w xcode bez animacji

90

Używam normalnych scenorysów i wypychania płynów w xcode, ale chcę, aby sekcje pojawiały się po prostu w następnym widoku, a nie przesuwały następnego widoku (tak jak w przypadku korzystania z paska kart i po prostu pojawia się następny widok).

Czy istnieje prosty sposób na to, aby zwykłe segmenty wypychania po prostu „pojawiały się”, a nie „ślizgały”, bez konieczności dodawania niestandardowych segmentów?

Wszystko działa całkowicie dobrze, chcę tylko usunąć animację slajdu między widokami.

Richard
źródło
Właśnie próbowałem zmienić przejście wypychania na przejście modalne, ponieważ może to pozwolić mi usunąć animację, ale mam widok tabeli z górnym paskiem narzędzi, a ustawienie przejścia na modalne usuwa ten górny pasek i nie mogę znaleźć żadnego sposobu aby z powrotem dodać górny pasek! Dlatego potrzebuję rozwiązania, które nie animuje przejścia, ale nie psuje widoku tabeli.
Richard

Odpowiedzi:

143

Udało mi się to zrobić, tworząc niestandardową kolejkę (na podstawie tego linku ).

  1. Utwórz nową klasę płynną (patrz poniżej).
  2. Otwórz Storyboard i wybierz płyn.
  3. Ustaw klasę na PushNoAnimationSegue(lub jakkolwiek ją nazwałeś).

Określ klasę segue w Xcode

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

Cel 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
źródło
Dzięki za komentarz i wkład.
Richard
11
Najlepsza odpowiedź. Jakieś pomysły na osiągnięcie tego samego w animacji z tyłu?
Thomas
1
Działa jak marzenie. Jest to również „właściwy” sposób robienia tego z fragmentami scenorysu.
Jeff Richley,
1
Czy ktoś zatrzymał animację wsteczną dla powyższej odpowiedzi.
Imran
4
NIE ROZWIĄZANIE, niestandardowa płynność prezentuje się w całym układzie, podobnie jak wypychanie modalne, podczas gdy oryginalne okno wypychania segue honoruje. Nawigacja w ramce Karta kontrolera BarController itp. ... jak skonfigurować płynność tak, aby zachowywała się jak wypychanie, a nie jak modalne. ? lub ... pytanie o 1.000.000 $, jak określić animacje = NIE podczas konfigurowania zwykłego segue za pomocą STORYBOARDS
Pedro Borges,
49

Możesz odznaczyć „Animacje” w Interface Builder dla iOS 9

wprowadź opis obrazu tutaj

dtochetto
źródło
3
To jest odpowiedź na pierwotne pytanie! Inne odpowiedzi pokazują, jak to osiągnąć w kodzie objc / swift, podczas gdy dtochetto używa tylko Xcode (jak żądano w oryginalnym pytaniu).
drpawelo
jednak w przypadku odprężającego odcinka wydaje się, że nie działa
Nicolas Manzini
2
To najlepsze i najszybsze rozwiązanie, niestety to nie działa na iOS 8.
EricH206
2
@DanielT. Może możesz przeciągnąć 2 segmenty na scenorys, jeden ma animację, a drugi nie ma animacji. Nadaj im inne Identifierimię.
AechoLiu
1
Zauważ, że XCode po prostu dodaje atrybut do elementu segue w pliku .storyboard. Możesz ręcznie edytować plik .storyboard i dodawać animates = "NIE" do plików, na których Ci zależy, jeśli używasz programu Visual Studio, a znacznik wyboru nie jest dostępny w projektancie.
Wes
35

Odpowiedź Iana działa świetnie!

Oto szybka wersja Segue, jeśli ktoś potrzebuje:

ZAKTUALIZOWANO DO SWIFT 5, MAJ 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é
źródło
2
Prawdopodobnie ze względu na wersję Swift potrzebowałem "as!" zamiast „as” w dwóch miejscach, w których ich używasz.
Carlos
1
Hm może w Swift 1.2? Sprawdziłem Swift 2.0 w Xcode 7 Beta1 i skompilowałem bez żadnych ostrzeżeń.
zavié
6

Teraz udało mi się to zrobić za pomocą następującego kodu:

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

Mam nadzieję, że to pomoże komuś innemu!

Richard
źródło
Możesz po prostu dodać to do działania UIButton lub cokolwiek innego. Jeśli chcesz przejść do nowego kontrolera widoku bez animacji, możesz użyć: - void (yourUIButtonAction) {CreditsViewController * creditspage = [self.storyboard instantiateViewControllerWithIdentifier: @ "Credits"]; [self.navigationController pushViewController: animacja strony kredytowej: NIE]; }
Richard
To nawet nie jest odpowiedzią na pytanie. Nie używasz tutaj segue!
KIDdAe
4

Oto wersja Swift przystosowana do modalnego prezentowania ViewController bez animacji:

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
źródło
1
Ten kod jest kopiowany z @ zavié answer, nie dodając niczego, ale jest rzeczywiście gorszy: brak sprawdzania opcji opcjonalnych
Diego Freniche
Różni się to od odpowiedzi @ zavié, ponieważ pokazuje, jak modalnie przedstawić kontroler ViewController bez animacji. Dobrze jest mieć go tutaj jako odniesienie, ponieważ jest w pewnym stopniu powiązany z pytaniem.
n.Drake
2

odpowiedz używając Swift3 -

dla „wypychania” segue:

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

dla przejścia „modalnego”:

class ModalNoAnimationSegue: UIStoryboardSegue
{
    override func perform() {
        self.source.present(destination, animated: false, completion: nil)
    }
}
elkorb
źródło
1

Dla każdego, kto korzysta z platformy Xamarin iOS, Twoja niestandardowa klasa płynna musi wyglądać następująco:

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

    }

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

Nie zapominaj, że nadal musisz ustawić niestandardową ścieżkę w swojej tablicy scenariuszy i ustawić klasę na klasę PushNoAnimationSegue.

JacobK
źródło
0

Dla mnie najłatwiej to zrobić:

UIView.performWithoutAnimation { 

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

    }

Dostępne od iOS 7.0

LironXYZ
źródło
Jeśli korzystasz z adaptacyjnych segmentów, uważam, że chociaż performWithoutAnimation ustawia animacje wyłączone, przed wykonaniem płynności animacje są ponownie włączane, jeśli płynność ma zaznaczoną opcję „animates”. Po wykonaniu jednak wyłącza je ponownie, jeśli wcześniej były.
malhal
Ale można to obejść, tworząc podklasę UIStoryboardSegue i wyłączając animacje ponownie przed wykonaniem (np. Używając konstruktora, aby sprawdzić, czy są wyłączone i przechowując je we właściwości).
malhal
0

Używam programu Visual Studio w / Xamarin, a projektant nie zapewnia znacznika wyboru „Animates” w odpowiedzi dtochetto.

Zwróć uwagę, że projektant XCode zastosuje następujący atrybut do elementu płynnego w pliku .storyboard: animates = "NIE"

Ręcznie wyedytowałem plik .storyboard i dodałem animates = "NIE" do elementu (ów) płynnych i to zadziałało.

Przykład:

 <segue id="1234" destination="ZB0-vP-ctU" kind="modal" modalTransitionStyle="crossDissolve" animates="NO" identifier="screen1ToScreen2"/>
Wes
źródło
0

PUSH BEZ ANIMACJI: Swift Oto, co zadziałało dla mnie.

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

Użycie : Ustaw klasę płynną z serii ujęć, jak pokazano na rysunku. ustaw isAnimationRequired z kontrolera widoku na false z miejsca, w którym chcesz wywołać performSegue, gdy chcesz wypchnąć płynnie bez animacji i ustawić z powrotem na true po wywołaniu self.performSegue. Powodzenia....

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

ustaw klasę segue z storyboardu, jak pokazano na rysunku.

Usman
źródło
-1

Wystarczy ustawić animated false na UINavigationController.pushViewControllerw Swift

self.navigationController!.pushViewController(viewController, animated: false)
Michał
źródło