如何在基于导航的应用程序中更改推送和弹出动画 [英] How to change the Push and Pop animations in a navigation based app

查看:24
本文介绍了如何在基于导航的应用程序中更改推送和弹出动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基于导航的应用程序,我想更改推送和弹出动画的动画.我该怎么做?

I have a navigation based application and I want to change the animation of the push and pop animations. How would I do that?

编辑 2018

这个问题有很多答案,现在已经有一段时间了,我重新选择了我认为现在最相关的答案.如果有人不这么认为,请在评论中告诉我

There have been many answers to this question and it's been quite awhile now, I have re-chosen the answer to what I believe to be the most relevant now. If there is anyone that thinks otherwise please let me know in comments

推荐答案

如何在基于导航的应用程序中更改推送和弹出动画...

How to change the Push and Pop animations in a navigation based app...

序言:

假设您是 iOS 开发的新手.令人困惑的是,Apple 提供了两个可以轻松使用的过渡.它们是:交叉淡入淡出";和翻转".

Say you are new to iOS development. Confusingly, Apple provide two transitions which can be used easily. These are: "crossfade" and "flip".

当然,交叉淡入淡出"和翻转"没用.它们从不使用.没有人知道为什么 Apple 提供了这两个无用的过渡!

But of course, "crossfade" and "flip" are useless. They are never used. Nobody knows why Apple provided those two useless transitions!

所以:

假设您想要一个普通的、常见的过渡,例如幻灯片".在这种情况下,你必须做大量的工作!.

Say you want to do an ordinary, common, transition such as "slide". In that case, you have to do a HUGE amount of work!.

这篇文章解释了这项工作.

That work, is explained in this post.

再重复一遍:

令人惊讶的是:对于 iOS,如果您想要最简单、最常见的日常过渡(例如普通幻灯片),您必须所有工作来实现完全自定义过渡.

Surprisingly: with iOS, if you want the simplest, most common, everyday transitions (such as an ordinary slide), you do have to all the work of implementing a full custom transition.

这是如何做到的......

Here's how to do it ...

  1. 你需要一个像 popStyle 这样的布尔值.(它是弹出还是弹出?)

  1. You need a bool of your own like popStyle . (Is it popping on, or popping off?)

你必须包含 transitionDuration(微不足道的)和主调用,animateTransition

You must include transitionDuration (trivial) and the main call, animateTransition

实际上,您必须animateTransition 内部编写两个不同的例程.一种用于推动,一种用于流行.可能将它们命名为 animatePushanimatePop.在 animateTransition 中,只需将 popStyle 分支到两个例程

In fact you must write two different routines for inside animateTransition. One for the push, and one for the pop. Probably name them animatePush and animatePop. Inside animateTransition, just branch on popStyle to the two routines

下面的例子做了一个简单的移动/移动

The example below does a simple move-over/move-off

在您的 animatePushanimatePop 例程中.您必须获得从视图"和查看".(如何做到这一点,如代码示例所示.)

In your animatePush and animatePop routines. You must get the "from view" and the "to view". (How to do that, is shown in the code example.)

并且您必须 addSubview 用于新的to"查看.

and you must addSubview for the new "to" view.

并且您必须在动画结束时调用completeTransition

所以..

  class SimpleOver: NSObject, UIViewControllerAnimatedTransitioning {
        
        var popStyle: Bool = false
        
        func transitionDuration(
            using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
            return 0.20
        }
        
        func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
            
            if popStyle {
                
                animatePop(using: transitionContext)
                return
            }
            
            let fz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
            let tz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!
            
            let f = transitionContext.finalFrame(for: tz)
            
            let fOff = f.offsetBy(dx: f.width, dy: 55)
            tz.view.frame = fOff
            
            transitionContext.containerView.insertSubview(tz.view, aboveSubview: fz.view)
            
            UIView.animate(
                withDuration: transitionDuration(using: transitionContext),
                animations: {
                    tz.view.frame = f
            }, completion: {_ in 
                    transitionContext.completeTransition(true)
            })
        }
        
        func animatePop(using transitionContext: UIViewControllerContextTransitioning) {
            
            let fz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
            let tz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!
            
            let f = transitionContext.initialFrame(for: fz)
            let fOffPop = f.offsetBy(dx: f.width, dy: 55)
            
            transitionContext.containerView.insertSubview(tz.view, belowSubview: fz.view)
            
            UIView.animate(
                withDuration: transitionDuration(using: transitionContext),
                animations: {
                    fz.view.frame = fOffPop
            }, completion: {_ in 
                    transitionContext.completeTransition(true)
            })
        }
    }

然后……

注意:奇怪的是,您只需要在第一"中执行此操作视图控制器.(在下面"的那个.)

Note: strangely, you only have to do this in the "first" view controller. (The one which is "underneath".)

用你在顶部弹出的那个,什么都不做.很简单.

With the one that you pop on top, do nothing. Easy.

所以你的班级...

class SomeScreen: UIViewController {
}

变成...

class FrontScreen: UIViewController,
        UIViewControllerTransitioningDelegate, UINavigationControllerDelegate {
    
    let simpleOver = SimpleOver()
    

    override func viewDidLoad() {
        
        super.viewDidLoad()
        navigationController?.delegate = self
    }

    func navigationController(
        _ navigationController: UINavigationController,
        animationControllerFor operation: UINavigationControllerOperation,
        from fromVC: UIViewController,
        to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        
        simpleOver.popStyle = (operation == .pop)
        return simpleOver
    }
}

就是这样.

完全像往常一样按下和弹出,没有变化.推...

Push and pop exactly as normal, no change. To push ...

let n = UIStoryboard(name: "nextScreenStoryboardName", bundle: nil)
          .instantiateViewController(withIdentifier: "nextScreenStoryboardID")
          as! NextScreen
navigationController?.pushViewController(n, animated: true)

并弹出它,如果您愿意,可以在下一个屏幕上执行此操作:

and to pop it, you can if you like just do that on the next screen:

class NextScreen: TotallyOrdinaryUIViewController {
    
    @IBAction func userClickedBackOrDismissOrSomethingLikeThat() {
        
        navigationController?.popViewController(animated: true)
    }
}

呸.

滚动到@AlanZeino 和@elias 的答案,了解有关如何在 iOS 应用程序中AnimatedTransitioning 的更多讨论!

Scroll to @AlanZeino and @elias answer for more discussion on how to AnimatedTransitioning in iOS apps these days!

这篇关于如何在基于导航的应用程序中更改推送和弹出动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆