xcode 如何禁用导航栏动画?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8717742/
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-09-14 22:53:27  来源:igfitidea点击:

How to disable navigationBar animation?

iosobjective-cxcodeuinavigationbarnavigationbar

提问by Ser Pounce

I have two UITableViewControllers such that when I click next on the first UITableViewController, the second UITableViewController gets pushed on the navigation stack and animates the transition like normal. I'd like to make it so when I push next, only the views animate, and the navigation bar doesn't (stays the same). I've gotten very close to doing this with the code below:

我有两个 UITableViewController,这样当我在第一个 UITableViewController 上单击 next 时,第二个 UITableViewController 会被推送到导航堆栈上,并像平常一样为过渡设置动画。我想这样做,当我按下下一步时,只有视图有动画,导航栏没有(保持不变)。我已经非常接近使用下面的代码来做到这一点:

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    CATransition *navTransition = [CATransition animation];
    navTransition.duration = .5;
    navTransition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    navTransition.type = kCATransitionPush;
    navTransition.subtype = kCATransitionPush;
    [self.navigationController.navigationBar.layer addAnimation:navTransition forKey:nil];

}

I put this code, and I also make it so the title and buttons on both navigation bars are exactly same in each UITableViewController. It almost works, problem is, the navigation bar blinks when the animation occurs. Is there anyway to get it to not blink, or is there any other good way to prevent the animation of the navbar from occurring (ie disabling the animation on the layer or something)?

我放了这段代码,我也做了它,所以两个导航栏上的标题和按钮在每个 UITableViewController 中都完全相同。它几乎可以工作,问题是,当动画发生时导航栏会闪烁。无论如何让它不闪烁,或者有没有其他好的方法来防止导航栏的动画发生(即禁用图层上的动画或其他东西)?

UPDATE: Anyone got any other ideas? Still struggling with this.

更新:有人有其他想法吗?还在为此苦苦挣扎。

采纳答案by Ser Pounce

This is what I came up with. Here is the code for the first viewController in the sequence:

这就是我想出的。这是序列中第一个 viewController 的代码:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
        if (viewController == self)
        {
                if (self.isInitialized)
                {
                        CATransition *navigationBarAnimation = [CATransition animation];
                        navigationBarAnimation.duration = 1.5;
                        navigationBarAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];;
                        navigationBarAnimation.type = kCATransitionFade;
                        navigationBarAnimation.subtype = kCATransitionFade;
                        navigationBarAnimation.removedOnCompletion = YES;
                        [self.navigationController.navigationBar.layer addAnimation:navigationBarAnimation forKey:nil];
                }
                else 
                {
                        self.isInitialized = YES;
                }
        }
}

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
        if (viewController == self)
        {
                if (self.isInitialized)
                {
                        [self.navigationController.navigationBar.layer removeAllAnimations];
                }
        }
}

Here is the code for the 2nd view controller:

这是第二个视图控制器的代码:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
        if (viewController == self)
        {
                if (!self.isInitialized)
                {
                        CATransition *navigationBarAnimation = [CATransition animation];
                        navigationBarAnimation.duration = 1.5;
                        navigationBarAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];;
                        navigationBarAnimation.type = kCATransitionFade;
                        navigationBarAnimation.subtype = kCATransitionFade;
                        navigationBarAnimation.removedOnCompletion = YES;
                        [self.navigationController.navigationBar.layer addAnimation:navigationBarAnimation forKey:nil];
                        self.isInitialized = YES;
                }
        }
}

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
        if (viewController == self)
        {
                if (self.isInitialized)
                {
                        [self.navigationController.navigationBar.layer removeAllAnimations];
                }
        }
}

You have to use the UINavigationControllerdelegate methods to figure out when the UIViewControlleris being shown. Then for each UIViewController, need to make a BOOLisInitializedproperty so it helps you determine when the UIViewControlleris being pushed on the stack, or when it's being shown because you pushed back on the next UIViewController.

您必须使用UINavigationController委托方法来确定何时UIViewController显示 。然后对于每个UIViewController,需要创建一个BOOLisInitialized属性,以便它帮助您确定何时将UIViewController推入堆栈,或者何时显示因为您推回了下一个UIViewController

回答by Cyprian

This may not be the best answer/idea but you could just mask the UINavigationBar during the animation.

这可能不是最好的答案/想法,但您可以在动画期间屏蔽 UINavigationBar。

Create a UINavigationBarthat looks exactly the same way as your current UNavigationBaradd it to the keyWindowjust before the transition takes place, then after it is finished remove it. This will essentially cover just the UINavigationBarand hide its animation.

创建一个UINavigationBar看起来与当前完全相同的方式,UNavigationBar将其添加到keyWindow过渡发生之前,然后在完成后将其删除。这将基本上只覆盖UINavigationBar并隐藏其动画。

回答by Krunal

Swift

迅速

Here is solution in swift

这是快速的解决方案

var isInitialized = false

Your FirstViewController:

你的 FirstViewController:

func navigationController(_ navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
        if viewController == self {
            if self.isInitialized {
                var navigationBarAnimation = CATransition()
                navigationBarAnimation.duration = 1.5
                navigationBarAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
                navigationBarAnimation.type = kCATransitionFade
                navigationBarAnimation.subtype = kCATransitionFade
                navigationBarAnimation.removedOnCompletion = true
                self.navigationController?.navigationBar?.layer?.addAnimation(navigationBarAnimation, forKey: nil)
                }
                else 
                {
                        self.isInitialized = true;
                }
        }
}

func navigationController(_ navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
        if viewController == self {
            if self.isInitialized {
                self.navigationController?.navigationBar?.layer?.removeAllAnimations()
            }
        }
}

Your SecondViewController:

你的第二个视图控制器:

func navigationController(_ navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
        if viewController == self {
            if !self.isInitialized {
                var navigationBarAnimation = CATransition()
                navigationBarAnimation.duration = 1.5
                navigationBarAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
                navigationBarAnimation.type = kCATransitionFade
                navigationBarAnimation.subtype = kCATransitionFade
                navigationBarAnimation.removedOnCompletion = true
                self.navigationController?.navigationBar?.layer?.addAnimation(navigationBarAnimation, forKey: nil)
                        self.isInitialized = true;
                }
        }
}

func navigationController(_ navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
        if viewController == self {
            if self.isInitialized {
                self.navigationController?.navigationBar?.layer?.removeAllAnimations()
            }
        }
}