导航栏作为iOS开发的一大空控件来说,是非常的重要,可以实现各种效果,隐藏,透明,的导航栏动画等等,这次就写一点自己的经验和总结.
1.导航栏的基本属性设置
导航栏的主要的子控件如下,其中都包含了所有的属性和方法:
- UINavigationItem
- UINavigationBar
- UIBarButtonItem
剩下的就是自定义左右barButtonItem,这个不就不多说了.
附上一个不错的博客:http://www.jianshu.com/p/f797793d683f
2.透明导航栏
1.思路是遍历NavigationBar的子视图,找到bar的背景图片,控制它的hidden
附上代码:
- (void)viewWillDisappear:(BOOL)animated
{
[self NavigationBarClear:self.navigationController.navigationBar hidden:NO];
self.navigationController.navigationBar.backgroundColor = [UIColor whiteColor];
}
- (void)viewWillAppear:(BOOL)animated
{
[self NavigationBarClear:self.navigationController.navigationBar hidden:YES];
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
}
#pragma mark ----
#pragma mark privateMethods
-(void)NavigationBarClear:(UINavigationBar *)navigationBar hidden:(BOOL) hidden
{
if ([navigationBar respondsToSelector:@selector( setBackgroundImage:forBarMetrics:)]){
NSArray *list = navigationBar.subviews;
for (id obj in list) {
if ([obj isKindOfClass:[UIImageView class]]) {
UIImageView *imageView = (UIImageView *)obj;
imageView.hidden = hidden;
}
}
}
}
2.是更换背景图片
- (void)viewWillDisappear:(BOOL)animated
{
[self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:nil];
}
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController.navigationBar setBackgroundImage:[self imageWithBgColor:[UIColor colorWithRed:1 green:1 blue:1 alpha:0]] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:[self imageWithBgColor:[UIColor colorWithRed:1 green:1 blue:1 alpha:0]]];
}
#pragma mark ----
#pragma mark privateMethods
-(UIImage *)imageWithBgColor:(UIColor *)color {
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
3.导航栏根据滚动是否透明
1.基于2.1的基础上实现,主要是根据tableView的偏移量来对navTgationBar的背景色进行设置,其中改了nav的frame,有一点小问题
#pragma mark ----
#pragma mark scrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
UIColor *color=[UIColor redColor];
CGFloat offset=scrollView.contentOffset.y;
self.navigationController.navigationBar.frame = CGRectMake(0, 0, self.view.frame.size.width, 64);
if (offset< 0) {
self.navigationController.navigationBar.backgroundColor = [color colorWithAlphaComponent:1];
}else{
CGFloat alpha = offset / 200;
if (alpha < 0.5) {
self.navigationController.navigationBar.backgroundColor = [color colorWithAlphaComponent:0];
}
}
}
2.是基于2.2的基础上实现的,根据tableView的偏移量,去更改nav的背景图片
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self.navigationController.navigationBar setBackgroundImage:[self imageWithBgColor:[UIColor colorWithRed:1 green:0 blue:0 alpha:self.tableView.contentOffset.y / 100]] forBarMetrics:UIBarMetricsDefault];
}
- 根据2.1,2.2 的比对,还是改变图片实现比较合理一点,如果控制图片的是否隐藏,会改变navBar的frame,然后对整体有一个向下20的偏移.
4.导航栏隐藏问题
进入新的界面时隐藏状态栏,view顶头,在退出VC时记得把隐藏状态改成NO
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:NO];
self.navigationController.navigationBarHidden = YES;
}
5.类似的效果
根据scrollView的滚动方向在设置nav是否hidden,适当做一个动画可以让体验更好一些.
#pragma mark ----
#pragma mark scrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (willEndContentOffsetX > startContentOffsetX) {
[UIView animateWithDuration:0.5 animations:^{
//这里可以有一些其他的操作
} completion:^(BOOL finished) {
self.navigationController.navigationBarHidden = YES;
}];
}else{
[UIView animateWithDuration:0.5 animations:^{
//这里可以有一些其他的操作
} completion:^(BOOL finished) {
self.navigationController.navigationBarHidden = NO;
}];
}
}
#pragma mark scrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ //拖动前的起始坐标
startContentOffsetX = scrollView.contentOffset.y;
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{ //将要停止前的坐标
willEndContentOffsetX = scrollView.contentOffset.y;
}
有些人可能会遇到导航栏下面有一条黑线的问题
// 添加上这一句,可以去掉导航条下边的shadowImage,就可以正常显示了
self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init];
self.navigationController.navigationBar.translucent = NO;
问题类似
github链接
附加一个博客:
iOS 7 改变 app 的外观(NavigationBar,TabBar,StatusBar)