从透明导航栏到半透明的过渡

28
在苹果最近发布的远程应用程序中,我注意到导航栏行为方式是独特的,我无法复制它。在弹出“现在播放”视图控制器时,导航栏保持透明状态,而库视图控制器的导航栏也保持半透明状态(截图1)。 我试图弄清楚他们是使用两个导航控制器还是仅使用一个。我个人认为他们只使用了一个,有两个理由:(1)启用了交互式弹出手势;(2)在库视图控制器中按下“现在播放”按钮时,在现在播放屏幕完成“推送视图控制器”动画之前,导航栏变为透明状态(屏幕截图2)。这是我推送我的视图控制器时遇到的情况(将导航栏设置为透明)。所以我的问题是:苹果如何呈现两个视图控制器的导航栏,就像它们是单独的一样(与截图1相同),即使是栏按钮、导航标题等...在切换时也是100%不透明(通常当按下/弹出按钮和标题时,上一个视图控制器的按钮和标题会淡化,因为新控制器被推入)。我尝试在viewDidAppearviewWillAppear中调整栏色调颜色,但无法复制相同的行为,并且无法防止栏按钮褪色。

这里讲得很清楚了。仔细阅读。 - Abhinav
@Abhinav 谢谢,但我不认为那解决了我的问题。我不想在顶部设置插图。就像远程应用程序一样,我希望表格可以在导航栏下滚动,但同时我也想复制截图1,在转换期间保留所有按钮、导航栏色调和标题。 - sooper
@sooper 请测试我的答案。 - Léo Natan
@LeoNatan 感谢您,我只需要一些空闲时间来测试它。但是如果在赏金截止日期之前我无法尝试它,我将在此之前接受答案。干杯 - sooper
2个回答

37

我刚刚下载了该应用程序以确保。使用了两个不同的导航栏。您可以通过使用交互式弹出手势来看到这一点。请注意,底部视图控制器上的导航栏会滑入和滑出。在普通的推送和弹出转换中,导航项只是在现有的栏上淡入淡出,而栏是固定的。这就是在现在播放视图控制器被推送之前发生的事情。

如果您快速查看现在播放视图控制器动画,您会看到底部导航栏消失。

从我的UIKit行为经验和我在应用程序中看到的情况来看,这是我认为发生的事情:

album_vc=底部列表视图控制器 nowplaying_vc=顶部视图控制器

  • nowplaying_vcviewWillAppear:中:

    • 使用[self.navigationController setNavigationBarHidden:YES animated:YES];将导航栏设置为隐藏状态。由于这是在动画块中,因此这将使导航栏在推送动画期间滑出。
    • 设置[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;。我很确定,因为请注意状态栏样式的转换没有任何动画。它只变成白色。
  • nowplaying_vcviewWillDisappear:中:

    • 使用[self.navigationController setNavigationBarHidden:NO animated:YES];将导航栏设置为显示状态。由于这是在动画块中,因此这将使导航栏在弹出动画期间滑入。
    • 设置[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;。同样,请注意,在交互式弹出手势期间,状态栏仅更改而没有动画。

要实现nowplaying_vc导航栏的透明外观,可以使用一个空图像([UIImage alloc])并使用setBackgroundImage:forBarPosition:barMetrics:

由于该应用程序不进行旋转,我们无法确定nowplaying_vc上的导航栏是另一个导航控制器的一部分还是顶部位置为UIBarPositionTopAttached的导航栏。 我们甚至不知道那里是否有导航栏,只有一个后退倒三角形图片视图(后退栏按钮由图像视图和按钮组成)。

我认为在viewWillAppear:viewWillDisappear:中更改状态栏样式是由于交互式弹出手势的不自然感觉。 我建议使用动画过渡,甚至更好地使用基于新视图控制器的状态栏样式,系统会自行动画过渡。


适用于现代API的更新:

您应该使用animateAlongsideTransition:completion:animateAlongsideTransitionInView:animation:completion: API,而不是依赖于viewWillAppear:viewWillDisappear:的隐式动画。


我相信这是正确的方法,但目前唯一的问题是当导航栏隐藏时,交互式弹出手势被禁用了。因此,我无法像远程应用程序那样在 nowplaying_vc 中使用弹出手势。 - sooper
1
@sooper 你在viewWillAppear:(或disappear)中将它设置为隐藏了吗?使用[self.navigationController setNavigationBarHidden:YES animated:YES];将其隐藏。 - Léo Natan
animated设置为YES就可以了!我在viewWillAppear:中设置了隐藏,并在viewWillDisappear:中取消隐藏,两者都是有动画效果的。不过很奇怪,为什么设置animated会产生这种行为呢? - sooper
我的猜测是,苹果内部有两种实现方法来隐藏状态栏,一种是动画的,另一种则不是,并且它们在动画期间重置值。我见过更奇怪的错误/行为。随着时间的推移,你会学习到UIKit的怪癖。 - Léo Natan
@sooper已更新答案,提供了正确的隐藏栏方法。 - Léo Natan
显示剩余4条评论

3

与其隐藏和显示导航栏,你可以更新导航栏的alpha值。在转换期间,它会平稳地动画效果过渡。对于具有透明导航栏的视图控制器,不要修改导航栏,而是在第二个控制器的视图中手动创建一个导航栏(或仅是后退按钮和标题等)。然后,我们将在从第一个视图控制器到第二个视图控制器的转换中隐藏导航栏。

在你的第一个控制器的 viewWillDisappear 和第二个控制器的 viewWillAppear: 中,使用 self.navigationController.navigationBar.alpha = 0; 将导航栏的alpha值设置为零。由于这是在动画块中,这将使导航栏在推送动画期间消失。

在第一个控制器的 viewWillAppear 和第二个控制器的 viewWillDisappear 中将alpha值重新设置为一。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接