在自定义动画过渡期间淡入背景视图

Fade in a background view during custom animation transition

我想为我的应用程序添加一个自定义过渡,并按照找到的这个惊人答案进行操作

效果很好,但我想更进一步。我想在第一页上看到一个视图,该视图最初是 alpha 0 或隐藏的,但随着用户在两个页面之间向下滑动而慢慢淡入。顶视图将具有透明背景,因此看起来好像它带有背景颜色。 我的意思的一个很好的例子可以在 snapchat 中看到,当在页面之间滑动时,如下面的屏幕截图所示。

背景慢慢变成蓝色,当新视图出现时,背景变成纯蓝色。

我知道这段代码必须按照我遵循的原始问题答案中的说明进入演示控制器,但是我不确定我将如何实现它。此外,当将 shouldRemovePresentersView 设置为 false 时,我在这里遇到了崩溃

func animateTransition(using transitionContext: 
    UIViewControllerContextTransitioning) {
        let inView   = transitionContext.containerView
        let toView   = transitionContext.view(forKey: .to)!
        let fromView = transitionContext.view(forKey: .from)!
}

我在我的应用程序中做了类似的事情,在手势完成时显示图像。我确实在我的应用程序中淡出图像,但我修改了它以淡入淡出,只做了一个小改动。在我的情况下,我只是淡入或淡出图像。我在下面使用扩展,但下面的 animateWithDuration 示例可能会对您有所帮助。请参阅下面的代码:

    public extension UIImage {
    func showAndFadeOut(atPoint point: CGPoint, sender:UIViewController) {
        let buttonView = UIImageView(image: self)
        buttonView.center = point
        sender.view.addSubview(buttonView)

        UIView.animate(withDuration: 3.0, delay: 0.0, options: .curveEaseOut, animations: {
            buttonView.alpha = 0

        }, completion:  { finished in
            buttonView.removeFromSuperview()
        })
    }

    func showAndFadeIn(atPoint point: CGPoint, sender:UIViewController) {
        let buttonView = UIImageView(image: self)
        buttonView.center = point
        sender.view.addSubview(buttonView)
        buttonView.alpha = 0

        UIView.animate(withDuration: 3.0, delay: 0.0, options: .curveEaseIn, animations: {
            buttonView.alpha = 1
        }, completion:  { finished in
            buttonView.removeFromSuperview()
        })
    }
}

你可以这样使用它:

image.showAndFadeIn(atPoint: gestureEndPoint, sender: self)

希望对您有所帮助。我删除了完成块中的按钮,但如果您希望该视图保留在屏幕上,只需删除该行代码即可。

看起来您想做一些类似于 所做的事情。所以我将使用相同的来源来帮助您更好地理解。

要添加 fade-in/fade-out 动画,您只需在 func animateTransition(using transitionContext: UIViewControllerContextTransitioning) 方法中调整 alpha 值(不透明度)即可。

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    let inView   = transitionContext.containerView
    let toView   = transitionContext.view(forKey: .to)!
    let fromView = transitionContext.view(forKey: .from)!

    var frame = inView.bounds

    switch transitionType {
    case .presenting:
        frame.origin.y = -frame.size.height
        toView.frame = frame

        // set initial alpha value to 0.0
        toView.alpha = 0.0

        inView.addSubview(toView)
        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
            toView.frame = inView.bounds

            // animate to 1.0
            toView.alpha = 1.0

        }, completion: { finished in
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        })
    case .dismissing:
        toView.frame = frame
        inView.insertSubview(toView, belowSubview: fromView)

        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
            frame.origin.y = -frame.size.height
            fromView.frame = frame

            // animate to 0.0
            fromView.alpha = 0.0
        }, completion: { finished in
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        })
    }
}

进一步分解:

  • 呈现新的ViewController:这里的初始值为0.0,因为ViewController看起来先是淡出,然后慢慢淡入。因此在动画块中使用toView.alpha = 1.0所以淡入 ViewController.
  • 关闭当前ViewController:这里的初始值为1.0(隐含的,无需设置)因为ViewController一开始看起来是不透明的,然后慢慢淡出。因此在动画块中使用 toView.alpha = 0.0 所以在 ViewController.
  • 中淡入淡出

你可以在相应的动画块中放置任何其他动画,基本上就在 toView.alpha = 1.0fromView.alpha = 0.0 旁边。

关于设置shouldRemovePresentersView为false时出现的crash,我想答案的作者已经给出了解决方案。 您可以 check a comparison 了解如何修复崩溃。

编辑:从按钮转换:

@IBAction func didTapShowButton(_ sender: UIButton) {
    let controller = storyboard!.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
    present(controller, animated: true)
}

别忘了将此连接到按钮!