ios 如何在视图控制器之间进行淡入淡出/无过渡

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10961926/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:41:51  来源:igfitidea点击:

How do I do a Fade/No transition between view controllers

objective-ciosuistoryboardsegue

提问by Sjors

Is it possible to do a fade in and fade out transition between View Controllers in Storyboard. Or without transition.

是否可以在 Storyboard 中的视图控制器之间进行淡入和淡出过渡。或者没有过渡。

If it's possible, what's the code for it?

如果可能,它的代码是什么?

回答by Rob

If presenting a modal view controller, you can specify a modalTransitionStyleof UIModalTransitionStyleCrossDissolve. If doing this with a segue in your storyboard, select the attributes inspector for the segue, and specify the transition style there:

如果呈现一个模态视图控制器,您可以指定一个modalTransitionStyleof UIModalTransitionStyleCrossDissolve。如果在故事板中使用 segue 执行此操作,请选择 segue 的属性检查器,并在那里指定过渡样式:

enter image description here

在此处输入图片说明

If presenting the view controller programmatically, you can define your modal segue between the view controllers in your storyboard with a "Transition" of "Cross Dissolve" and then have the source view controller perform this segue:

如果以编程方式呈现视图控制器,您可以使用“Cross Dissolve”的“Transition”在故事板中的视图控制器之间定义模态转场,然后让源视图控制器执行此转场:

[self performSegueWithIdentifier:@"presentSegue" sender:sender];

Or, if you are calling presentViewController:

或者,如果您正在致电presentViewController

UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"YourStoryboardID"];
controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:controller animated:YES completion:nil];


In iOS 7, Apple has provided a new technology that provides a rich and robust control for highly customized transitions. For more information, refer to WWDC 2013 video Custom Transitions Using View Controllers.

在 iOS 7 中,Apple 提供了一项新技术,可为高度自定义的过渡提供丰富而强大的控件。有关更多信息,请参阅 WWDC 2013 视频使用视图控制器自定义过渡

But, for instance, if you want to customize the push and pop animations in iOS 7 to fade, you would specify a delegatefor the navigation controller

但是,例如,如果您想自定义 iOS 7 中的推送和弹出动画以淡入淡出,您可以delegate为导航控制器指定 a

- (void)viewDidLoad {
    [super viewDidLoad];

    self.navigationController.delegate = self;
}

You would then implement animationControllerForOperationthat specified the animator objects for pushing and popping:

然后animationControllerForOperation,您将实现指定用于推送和弹出的动画对象:

- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                  animationControllerForOperation:(UINavigationControllerOperation)operation
                                               fromViewController:(UIViewController*)fromVC
                                                 toViewController:(UIViewController*)toVC
{
    if (operation == UINavigationControllerOperationPush)
        return [[PushAnimator alloc] init];

    if (operation == UINavigationControllerOperationPop)
        return [[PopAnimator alloc] init];

    return nil;
}

You'd obviously have to implement your custom push and pop animators, such as:

你会明显地要实现自定义的push和pop动画,如:

@interface PushAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@end

@implementation PushAnimator

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return 0.5;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController* toViewController   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    [[transitionContext containerView] addSubview:toViewController.view];

    toViewController.view.alpha = 0.0;

    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        toViewController.view.alpha = 1.0;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];
}

@end

And

@interface PopAnimator : NSObject <UIViewControllerAnimatedTransitioning>

@end

@implementation PopAnimator

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return 0.5;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController* toViewController   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    [[transitionContext containerView] insertSubview:toViewController.view belowSubview:fromViewController.view];

    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        fromViewController.view.alpha = 0.0;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];
}

@end

There is a similar, but slightly different technique for customizing modal transitions, too (though if you were just doing a face, you'd probably just use the modalTransitionStylediscussed above unless there was some other subtle customization you wanted to employ). See the aforementioned Custom Transitions Using View Controllersfor more information.

也有一种类似但略有不同的自定义模态转换技术(尽管如果您只是做一个人脸,您可能只使用modalTransitionStyle上面讨论的方法,除非您想使用其他一些微妙的自定义)。有关更多信息,请参阅上述使用视图控制器的自定义过渡

Bottom line, custom transitions for iOS 7 are a slightly complicated, but very robust way to provide tremendous control over the animations for transitions.

最重要的是,iOS 7 的自定义过渡是一种稍微复杂但非常强大的方式,可以为过渡动画提供巨大的控制。

回答by Yaroslav Babenko

For creating Custom Segue create subclass of UIStoryboard segue. For example:

要创建自定义转场,请创建 UIStoryboard 转场的子类。例如:

// MCFadeSegue.h
#import <UIKit/UIKit.h>

@interface MCFadeSegue : UIStoryboardSegue

@end

// MCFadeSegue.m
#import <QuartzCore/QuartzCore.h>
#import "MCFadeSegue.h"

@implementation MCFadeSegue

- (void)perform
{
  CATransition *transition = [CATransition animation];
  transition.duration = 0.5;
  transition.type = kCATransitionFade;

  [[[[[self sourceViewController] view] window] layer] addAnimation:transition
      forKey:kCATransitionFade];

  [[self sourceViewController]
      presentViewController:[self destinationViewController]
      animated:NO completion:NULL];
}

@end

Then in MainStoryboard.storyboard choose segue and set Style:Custom and Class:MCFadeSegue.

然后在 MainStoryboard.storyboard 中选择 segue 并设置 Style:Custom 和 Class:MCFadeSegue。

回答by Eugene Braginets

Push/Pop UIVIewController FadeIn/FadeOut in Swift

Swift 中的推送/弹出 UIVIewController 淡入/淡出

class FadeInPushSegue: UIStoryboardSegue {

    var animated: Bool = true

    override func perform() {

        if var sourceViewController = self.sourceViewController as? UIViewController, var destinationViewController = self.destinationViewController as? UIViewController {

            var transition: CATransition = CATransition()

            transition.type = kCATransitionFade; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
            sourceViewController.view.window?.layer.addAnimation(transition, forKey: "kCATransition")
            sourceViewController.navigationController?.pushViewController(destinationViewController, animated: false)


        }
    }

}

class FadeOutPopSegue: UIStoryboardSegue {

    override func perform() {

        if var sourceViewController = self.sourceViewController as? UIViewController, var destinationViewController = self.destinationViewController as? UIViewController {

            var transition: CATransition = CATransition()

            transition.duration = 0.4
            transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
            transition.type = kCATransitionFade; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade

            sourceViewController.view.window?.layer.addAnimation(transition, forKey: "kCATransition")
            sourceViewController.navigationController?.popViewControllerAnimated(false)
        }
    }

}

回答by Brandon Roberts

Without needing to create a custom segue, I put together this code to present the view...

无需创建自定义转场,我将这段代码放在一起来呈现视图......

UIViewController *nextView = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"YOUR_VIEW_CONTROLLER_STORYBOARD_NAME"];

nextView.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;

[self.navigationController presentViewController:nextView animated:YES completion:nil];
// (For a cross dissolve, set animated:YES.  For no transition, set animated:NO.)

Hope this helps anyone who comes across this question!

希望这可以帮助遇到这个问题的任何人!

回答by S R Nayak

Try this one.

试试这个。

    let transition: CATransition = CATransition()
    transition.duration = 0.4
    transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    transition.type = kCATransitionFade
    self.navigationController!.view.layer.addAnimation(transition, forKey: nil)

    let vc = self.storyboard?.instantiateViewControllerWithIdentifier("vcID") as! My_ViewController
    self.navigationController?.pushViewController(vc, animated: false)

回答by ioopl

My Swift Version with optional checking offcourse!

我的 Swift 版本带有可选的检查offcourse!

    let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
    if let stView = storyboard.instantiateViewControllerWithIdentifier("STVC") as? STVC {
        stView.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve
        self.navigationController?.presentViewController(stView, animated: true, completion: nil)
    }

Just make sure to set the Storyboard ID of the "View controller" in IB

只需确保在 IB 中设置“视图控制器”的 Storyboard ID

回答by Septronic

What I did was to use Storyboard in Interface Builder, connected the two viewcontroller you need to move to /from and back (hold ctrl and drag click from the origin viewcontroller to destination viewcontroller), and changed the segue properties. I used the following:

我所做的是在Interface Builder中使用Storyboard,连接您需要移动到/从和返回的两个视图控制器(按住ctrl并将单击从原始视图控制器拖动到目标视图控制器),并更改segue属性。我使用了以下内容:

enter image description here

在此处输入图片说明

I then used the following:

然后我使用了以下内容:

[self performSegueWithIdentifier:@"showMovieDetailSegue" sender:self];

when you want to remove it, just call this from the origin viewcontroller:

当你想删除它时,只需从原始视图控制器调用它:

[self dismissViewControllerAnimated:YES completion:nil];

Simple and very quick.

简单而且非常快。

回答by Maverick

Push/Pop UIVIewController FadeIn/FadeOut in Swift 3syntax, based on Eugene Braginets's answer

Push/Pop UIVIewController FadeIn/FadeOut in Swift 3语法,基于Eugene Braginets回答

class FadeInPushSegue: UIStoryboardSegue {

    var animated: Bool = true

    override func perform() {

        let sourceViewController = self.source
        let destinationViewController = self.destination

        let transition: CATransition = CATransition()

        transition.type = kCATransitionFade; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
        sourceViewController.view.window?.layer.add(transition, forKey: "kCATransition")
        sourceViewController.navigationController?.pushViewController(destinationViewController, animated: false)

    }

}

class FadeOutPopSegue: UIStoryboardSegue {

    override func perform() {

        let sourceViewController = self.source

        let transition: CATransition = CATransition()

        transition.duration = 0.4
        transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition.type = kCATransitionFade; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade

        sourceViewController.view.window?.layer.add(transition, forKey: "kCATransition")
        _ = sourceViewController.navigationController?.popViewController(animated: false)
    }

}

回答by Connor

This drove me absolutely nuts for several hours. None of these solutions seemed to be what I wanted, and I was losing my mind. Finally came up with the following, which swaps view controllers within a single NSWindow using a fade out/fade in transition. First it performs a fade out, then, in the completion handler, it sets the view for the window to the new view and performs a fade in. Maybe there's a better way to do this, but this is the simplest way I could hack together.

这让我彻底疯了几个小时。这些解决方案似乎都不是我想要的,我正在失去理智。最后提出了以下内容,它使用淡出/淡入过渡在单个 NSWindow 中交换视图控制器。首先它执行淡出,然后在完成处理程序中,它将窗口的视图设置为新视图并执行淡入。也许有更好的方法来做到这一点,但这是我可以一起破解的最简单的方法.

class CustomSegue : NSStoryboardSegue {
    override func perform() {
        guard let fromController = sourceController as? NSViewController else {
            return;
        }
        guard let toController = destinationController as? NSViewController else {
            return;
        }
        let animationDuration = 0.5;
        NSAnimationContext.runAnimationGroup({
            ##代码##.duration = animationDuration;
            fromController.view.animator().alphaValue = 0.0;
        }, completionHandler: {
            fromController.view.window?.contentViewController = toController;
            toController.view.alphaValue = 0.0;
            NSAnimationContext.runAnimationGroup({
                ##代码##.duration = animationDuration;
                toController.view.animator().alphaValue = 1.0;
            })
        });

    }
}

The lack of examples in Apple documentation makes me want to tear my brain out, and the mix of Objective C and Swift everywhere is just... bah!

Apple 文档中缺少示例让我想绞尽脑汁,Objective C 和 Swift 的混合无处不在,简直是……呸!