Нажмите segue в xcode без анимации

90

Я использую обычную раскадровку и нажимаю сегменты в xcode, но я хочу, чтобы сегменты отображались только в следующем представлении, а не в следующем представлении (например, когда вы используете панель вкладок и только что появляется следующее представление).

Есть ли хороший простой способ, чтобы обычные переходы push просто «появлялись», а не «скользили», без необходимости добавлять пользовательские переходы?

Все работает нормально, я просто хочу удалить эту анимацию слайдов между представлениями.

Ричард
источник
Я только что попытался изменить push segue на модальный segue, так как это может позволить мне удалить анимацию, но у меня есть tableview с верхней панелью инструментов, и установка segue на модальный удаляет эту верхнюю панель, и я не могу найти никакого способа чтобы снова добавить верхнюю панель! Поэтому мне нужно решение, которое не анимирует переход, но не нарушает мой вид таблицы.
Ричард

Ответы:

143

Я смог сделать это, создав собственный переход (на основе этой ссылки ).

  1. Создайте новый класс перехода (см. Ниже).
  2. Откройте раскадровку и выберите переход.
  3. Задайте для класса значение PushNoAnimationSegue(или как вы его решили назвать).

Укажите класс перехода в 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)
    }
}

Цель 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
Ян
источник
Спасибо за комментарий и вклад.
Ричард
11
Лучший ответ. Есть идеи, как добиться того же для задней анимации?
Thomas
1
Работает как шарм. Это также «правильный» способ сделать это с сегментами раскадровки.
Джефф Ричли 06
1
Кто-нибудь остановил обратную анимацию для вышеуказанного ответа.
Имран
4
Это не решение, пользовательский переход представляет собой весь макет, как модальный push, в то время как исходный push segue уважает window.frame navigationController tabBarController и т.д ... как настроить segue так, чтобы он вел себя как push segue, а не как модальный segue ? или ... вопрос $ 1.000.000, как указать анимацию = NO при настройке обычного перехода с помощью STORYBOARDS
Педро Борхес
49

Вы можете снять флажок «Анимация» в Интерфейсном Разработчике для iOS 9.

введите описание изображения здесь

dtochetto
источник
3
Это ответ на исходный вопрос! Другие ответы показывают, как добиться этого в коде objc / swift, в то время как dtochetto использует только Xcode (например, запрошенный в исходном вопросе).
drpawelo
однако для расслабляющего перехода это, похоже, не работает
Николас Манзини
2
Это лучшее и самое быстрое решение, к сожалению, оно не работает на iOS 8.
EricH206,
2
@DanielT. Возможно, вы можете перетащить 2 сегмента на раскадровку, у одного есть анимация, а у другого нет анимации. Дайте им другое Identifierимя.
AechoLiu
1
Обратите внимание, что XCode просто добавляет атрибут к элементу segue в файле .storyboard. Вы можете вручную отредактировать файл .storyboard и добавить animates = "NO" к интересующим вас сегментам, если вы используете Visual Studio и галочка недоступна в дизайнере.
Уэс
35

Ответ Яна отлично работает!

Вот Swift-версия Segue, если кому-то понадобится:

ОБНОВЛЕНО ДЛЯ SWIFT 5 МАЯ 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)
    }
}
завие
источник
2
Видимо из-за версии Swift мне понадобилось "as!" вместо "as" в двух местах, где вы их используете.
Карлос
1
Хм может быть в Swift 1.2? Я проверил Swift 2.0 в Xcode 7 Beta1, и он скомпилирован без каких-либо предупреждений.
zavié
6

Теперь мне удалось это сделать, используя следующий код:

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

Надеюсь, это поможет кому-то другому!

Ричард
источник
Вы можете просто добавить это к действию UIButton или чего-то еще. Если вы хотите перейти к новому контроллеру представления без анимации, вы можете использовать: - void (yourUIButtonAction) {CreditsViewController * creditspage = [self.storyboard instantiateViewControllerWithIdentifier: @ "Credits"]; [self.navigationController pushViewController: анимированная страница кредитов: НЕТ]; }
Ричард
Это даже не ответ на вопрос. Вы здесь не используете segue!
KIDdAe
4

Вот версия Swift, адаптированная для модального представления ViewController без анимации:

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

}
Дэниел Маклин
источник
1
Этот код скопирован из ответа @ zavié, ничего не добавляя, но на самом деле хуже: проверка дополнительных опций не включена
Диего Френиче
Это отличается от ответа @zavié, потому что он показывает, как модально представить ViewController без анимации. Приятно иметь его здесь в качестве ссылки, поскольку он несколько связан с вопросом.
n.Drake
2

ответ с помощью Swift3 -

для перехода "push":

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

для "модального" перехода:

class ModalNoAnimationSegue: UIStoryboardSegue
{
    override func perform() {
        self.source.present(destination, animated: false, completion: nil)
    }
}
Elkorb
источник
1

Для всех, кто использует Xamarin iOS, ваш собственный класс segue должен выглядеть так:

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

    }

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

Не забывайте, что вам все еще нужно установить пользовательский переход в своей раскадровке и установить для класса PushNoAnimationSegue.

Яков К.
источник
0

Для меня самый простой способ сделать это:

UIView.performWithoutAnimation { 

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

    }

Доступно с iOS 7.0

LironXYZ
источник
Я считаю, что при использовании адаптивных переходов, хотя PerformWithoutAnimation устанавливает анимацию отключенной, перед выполнением перехода анимация снова включается, если для перехода установлен флажок «animates». Однако после выполнения он снова отключает их, если раньше.
malhal
Но вы можете обойти это, создав подкласс UIStoryboardSegue и снова отключив анимацию перед выполнением (например, используя конструктор, чтобы проверить, отключены ли они, и сохранив его в свойстве).
malhal
0

Я использую Visual Studio с Xamarin, и дизайнер не поставил галочку «Animates» в ответе dtochetto.

Обратите внимание, что дизайнер XCode применит к элементу segue в файле .storyboard следующий атрибут: animates = "NO"

Я вручную отредактировал файл .storyboard и добавил animates = "NO" к элементам segue, и у меня это сработало.

Пример:

 <segue id="1234" destination="ZB0-vP-ctU" kind="modal" modalTransitionStyle="crossDissolve" animates="NO" identifier="screen1ToScreen2"/>
Уэс
источник
0

НАЖАТЬ БЕЗ АНИМАЦИИ: Swift Вот что у меня сработало.

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

Использование : Установите класс перехода из раскадровки, как показано на рисунке. установите для isAnimationRequired в вашем контроллере просмотра значение false, откуда вы хотите вызвать performSegue, если вы хотите отправить segue без анимации и вернуть значение true после вызова self.performSegue. Удачи....

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

установите класс segue из раскадровки, как показано на рисунке.

Усмань
источник
-1

Просто установите animated ЛОЖЬ на UINavigationController.pushViewControllerв Swift

self.navigationController!.pushViewController(viewController, animated: false)
Майкл
источник