iOS之导航栏详解

导航栏作为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;
            }
        }
    }  
}
iOS之导航栏详解_第1张图片
2.1.gif

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;
}
iOS之导航栏详解_第2张图片
2.2.gif

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];
        }
    }
}
iOS之导航栏详解_第3张图片
3.1.gif

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];
}
iOS之导航栏详解_第4张图片
3.2.gif

  • 根据2.1,2.2 的比对,还是改变图片实现比较合理一点,如果控制图片的是否隐藏,会改变navBar的frame,然后对整体有一个向下20的偏移.

4.导航栏隐藏问题

进入新的界面时隐藏状态栏,view顶头,在退出VC时记得把隐藏状态改成NO

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:NO];
    self.navigationController.navigationBarHidden = YES;
}
iOS之导航栏详解_第5张图片
4.1.gif

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;
}
iOS之导航栏详解_第6张图片
5.gif

有些人可能会遇到导航栏下面有一条黑线的问题

// 添加上这一句,可以去掉导航条下边的shadowImage,就可以正常显示了  
 self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init];  
 self.navigationController.navigationBar.translucent = NO; 

问题类似


github链接

附加一个博客:
iOS 7 改变 app 的外观(NavigationBar,TabBar,StatusBar)

你可能感兴趣的:(iOS之导航栏详解)