我如何“合法地”淡出应用程序中的导航栏?

时间:2013-07-28 22:38:45

标签: ios objective-c uiview uinavigationcontroller uinavigationbar

似乎删除动画导航栏的唯一方法是向上滑动。我想让它褪色,就像在Photos.app。中一样。

最简单的方法是更改​​alpha,但Apple's guidelines state

  

在iOS v5.0之前,与导航一起使用时   控制器,你可以只有少数直接自定义   进入导航栏。具体来说,可以修改   barStyle,tintColor和半透明属性,但绝对不能   直接更改UIView级属性,如框架,边界,   alpha或隐藏的属性。

该语言有点奇怪,因为它在iOS 5之前表示,但它声明您不允许直接更改alpha值,并且它从未声明您现在被允许。

我不希望我的应用被拒绝。

如何像状态栏一样淡出导航栏?

6 个答案:

答案 0 :(得分:11)

这是一个有趣的解决方案。

应该非常简单:使用UIView transitionWithView在导航栏的隐藏和非隐藏状态之间执行交叉淡入淡出,由公共API setNavigationBarHidden:animated:设置。事实上,这适用于“淡出”导航栏,但是将其淡入还有一个问题。问题是,除非您指定UIView +transitionWithView:,否则导航栏将滑入到位,而frame不会为可动画属性设置动画(例如UIViewAnimationOptionAllowAnimatedContent)。

对我而言,这表示UINavigationController内部动态块中的UINavigationBar重新定位,无论是否在setNavigationBarHidden:animated:的调用中指定了动画。当animate:设置为NO时,此动画块的持续时间可能设置为“0”。

解决方案是在交叉淡入淡出过渡之前将导航栏设置为可见(无动画)。这样可以确保导航栏在正确的位置开始交叉淡入淡出,并且交叉淡入淡出只会显示新的非隐藏状态。

我的示例项目是标准的单视图应用程序。在故事板上是UINavigationController,这是切入点。我将此控制器的UINavigationBar的条形样式设置为黑色半透明(类似于照片应用程序)。导航控制器rootViewController是一个简单的UIViewControllerUIImageView填充整个边界(也像照片应用)。我在视图中添加了UITapGestureRecognizer以在视图控制器中调用以下代码:

- (IBAction) onShowHideNavbar: (id) sender
{
    BOOL hide = !self.navigationController.navigationBarHidden;

    if ( !hide)
    {
        [self.navigationController setNavigationBarHidden: hide animated: NO];
    }

    [UIView transitionWithView: self.navigationController.view
                      duration: 1
                       options: UIViewAnimationOptionTransitionCrossDissolve
                    animations: ^{

                        [self.navigationController setNavigationBarHidden: hide animated: NO];
                    }
                    completion: nil ];
}

所有这些都说,我不认为你会因为直接弄乱UINavigationBar的隐藏或alpha属性而遇到任何麻烦(Apple拒绝)。文档警告不要触摸它们,因为它们由UINavigationController管理并且更改它们可能会产生看不见的后果。但在我的意见中,他们是公共API,因此使用它们不应该被拒绝。

答案 1 :(得分:6)

您无法合法地为UINavigationController的导航栏的属性设置动画 但是,您可以显示带有隐藏导航栏的导航控制器(根据您的喜好将其隐藏或仅隐藏在特定的视图控制器上),并将其替换为UINavigationBar的“特殊”实例; - )

我附上了一个示例项目(我使用Xcode模板更快地创建它):FakeNavBar

查看viewDidLoad的{​​{1}}方法:

DetailViewController

以下是最终产品on YouTube的视频。

答案 2 :(得分:2)

解决这个问题(我不确切地知道你计划如何设置动画到下一个视图或以什么方式合并淡入淡出)是将当前视图渲染为uiimage,制作全屏UIImageView使用此图像(基本上用它的图片替换现有的UIView)在图像视图后面的新视图中切换,然后淡出图像视图。

您还可以裁剪出图像的UInavigationBar部分,并在转换后淡出。这样,您可以将任何图像效果应用于'UINavgationBar',而不会被苹果拒绝。

答案 3 :(得分:1)

我知道没有Apple认可的方法来做到这一点。我怀疑你会因修改navigationBar的alpha值而被拒绝,但是和你一样,我不确定。

您当然可以实施自己的导航控制器/导航栏,您可以使用它来执行任何操作。当我需要做这样的事情时,这就是我在我的应用程序中所做的。苹果对此完全没问题。奖励积分:如果您使用自定义控件,Apple可以根据需要更改其控件,而不会破坏您的布局。这是我们应用程序某些领域的一个问题,在不同版本的iOS(7)中,该应用程序看起来完全不同。

无论如何,这是我的2美分......

答案 4 :(得分:0)

如果你继续阅读,这是你引用之后的下一段:

  

在iOS v5.0及更高版本中,您可以自定义栏的外观   使用“自定义栏外观”中列出的方法。您可以   使用外观自定义所有导航栏的外观   代理([UINavigationBar外观]),或只是一个单独的栏。

点击链接(自定义栏外观)将显示以下信息:

  

自定义栏外观
    tintColor 属性
   - backgroundImageForBarMetrics:
   - setBackgroundImage:forBarMetrics:
   - titleVerticalPositionAdjustmentForBarMetrics:
   - setTitleVerticalPositionAdjustment:forBarMetrics:
   titleTextAttributes property

因此,在iOS v5.0及更高版本中,这是您可以(合法)更改的列表。您可以使用tintColor或背景图像的alpha来玩一些游戏,以使其看起来像淡出(然后隐藏它)但我怀疑它看起来会很正确。可能值得一试。

答案 5 :(得分:0)

您可能无法轻松淡化导航栏,但可以轻松淡化导航栏的图片。因此,您可以做的一件事是创建导航栏的图像,用图像替换导航栏,然后使用alpha设置为0来设置图像视图的动画。或者您可以执行相反的操作:将图像视图放在顶部导航栏,淡入导航条后面的任何图像。