美文网首页
动态导航颜色

动态导航颜色

作者: liu_bo | 来源:发表于2015-08-05 15:36 被阅读148次

思路

在UISrollView的delegate方法 

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

中根据当前的contentOffset更新navigationBar的backgroundColor即可,so easy~

开动

那么我们来看看apple为我们提供了哪些API来设置navigationBar的颜色。

首先想到的是最常用的[UINavigationBar appearance],我们一般会在AppDelegate中使用它对navigationBar进行统一的设置。但是如果试一下,会发现在scrollViewDidScrollView中调用它并不能动态地改变navigationBar的颜色,原因可以看一下Apple的doc:

Use the UIAppearance protocol to get the appearance proxy for a class. You can customize the appearance of instances of a class by sending appearance modification messages to the class’s appearance proxy.

但是:

iOS applies appearance changes when a view enters a window, it doesn’t change the appearance of a view that’s already in a window. To change the appearance of a view that’s currently in a window, remove the view from the view hierarchy and then put it back.

所以换一条路,直接修改UINavigationBar的backgroudColor:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

{

UIColor *color = [UIColor blueColor];

CGFloat offsetY = scrollView.contentOffset.y;

if (offsetY > 0) {

CGFloat alpha = 1 - ((64 - offsetY) / 64);

self.navigationController.navigationBar.backgroundColor = [color colorWithAlphaComponent:alpha];

} else {

self.navigationController.navigationBar.backgroundColor = [color colorWithAlphaComponent:0];

}

}

结果却是。。。 仔细观察,会发现navigationBar的高度是44,它的上方是statusBar,而且,navigationBar的上面还有一个未知的View。。。到底Apple是怎么实现UINavigationBar的呢,让我们一探究竟!

在xcode的顶部菜单栏找到Debug > View Debugging > Capture View Hierarchy:

原来UINavigationBar上有一个_UIBackDropView,正是它决定了navigationBar的背景色。

既然没有public的API,我们只能hack了!

我们的思路很简单,参照Apple的实现,在navigationBar的view hierarchy中插入一个view,通过它来控制在navigationBar的backgroundColor。

考虑到继承UINavigationBar使用起来会非常不便,我们决定用Category来实现,首先定义我们的category:

@interface UINavigationBar (BackgroundColor)

- (void)lt_setBackgroundColor:(UIColor *)backgroundColor;

@end

实现:我们使用associatedObject将overlayView动态地绑定到UINavigationBar的instance上,当调用lt_setBackgroundColor的时候,我们只要更新这个overlayView就行啦~

@implementation UINavigationBar (BackgroundColor)

static char overlayKey;

- (UIView *)overlay

{

return objc_getAssociatedObject(self, &overlayKey);

}

- (void)setOverlay:(UIView *)overlay

{

objc_setAssociatedObject(self, &overlayKey, overlay, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (void)lt_setBackgroundColor:(UIColor *)backgroundColor

{

if (!self.overlay) {

[self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];

// insert an overlay into the view hierarchy

self.overlay = [[UIView alloc] initWithFrame:CGRectMake(0, -20, [UIScreen mainScreen].bounds.size.width, self.bounds.size.height + 20)];

self.overlay.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;

[self insertSubview:self.overlay atIndex:0];

}

self.overlay.backgroundColor = backgroundColor;

}

@end

最后在scrollViewDidScroll中,我们就可以动态地修改UINavigationBar的backgroundColor了:

[self.navigationController.navigationBar lt_setBackgroundColor:[color colorWithAlphaComponent:alpha]];

UINavigationBar是一个比较特殊的view,它被系统高度集成,有时候定制起来并不那么方便。其实这个demo完全可以用另外一种方法实现,就是不用UINavigationBar,自己画一套UI。

很多时候我们都会发现系统原生控件出现一些预料之外的行为,那么打开view debugging,找出原因,然后解决它!

相关文章

  • 动态导航颜色

    思路 在UISrollView的delegate方法 - (void)scrollViewDidScroll:(U...

  • 4月:阅读WRNavigationBar源码

    iOS动态改变导航栏透明度和颜色(WRNavigationBar) github: https://github....

  • 动态改变导航栏的颜色

    仿美团的商品页签下的商品详情界面 一开始是这样 向上拉到一定的程度后,变为下面这样 一、写一个UIImage的扩展...

  • 修改导航栏属性

    1、修改导航栏字体颜色 2、修改导航栏背景颜色颜色

  • iOS动态切换导航栏字体颜色

    前言:新版本项目UI界面上做了很大的改动,要求状态栏字体颜色也要跟着界面做出动态的改变。在我对设计的理解中,状态栏...

  • UINavigationBar Tips

    设置所有导航栏的属性: 更改导航栏的背景颜色: 更改导航栏的文字颜色: 更改导航栏的标题字体及颜色: iOS字体查...

  • iOS 导航栏颜色字体设置

    导航栏标题字体大小和颜色 导航栏背景颜色

  • 导航栏UINavigationController

    2,设置导航栏的背景颜色 3,设置导航栏按钮字体颜色 4,设置标题样式与颜色(通过导航栏字典的方式) 5,设置返回...

  • iOS UINavigationController导航栏 设置

    只有电池栏颜色变化 而且 没有导航栏那条横线 导航栏字体大小和颜色 设置状态栏和导航栏是一致的颜色 设置透明的导航栏

  • Swift_ios_开发之UINavigationControl

    1.导航栏是否隐藏 2.导航栏的最底部颜色设置 3.导航栏的表层颜色,即首先看到的颜色 4.导航栏中间标题titl...

网友评论

      本文标题:动态导航颜色

      本文链接:https://www.haomeiwen.com/subject/rgavqttx.html