美文网首页iOS开发
iOS之导航栏详解

iOS之导航栏详解

作者: 武小寺 | 来源:发表于2016-03-21 15:45 被阅读3603次

导航栏作为iOS开发的一大空控件来说,是非常的重要,可以实现各种效果,隐藏,透明,简书的导航栏动画等等,这次就写一点自己的经验和总结.

1.导航栏的基本属性设置

导航栏的主要的子控件如下,其中都包含了所有的属性和方法:

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.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;
}
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];
        }
    }
}
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];
}
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;
}
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;
}
5.gif

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

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

问题类似


github链接

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

相关文章

网友评论

  • 超_iOS:导航栏在pop过程中会有个变透明(不正常)的过程.请问有什么思路么
    dongwenbo:@不知有汉_超 需要重写过度动画
    超_iOS:@武小寺 就和你文中的3相似,从一个不透明的POP到透明的过程中
    武小寺:@李二超 导航栏变透明? 还是系统自带的那个效果?
  • 长空北:透明导航栏二,用手势返回时,有bug,会把前一页的导航栏给显示出来,
    如果把TableView移动到下面,让NavigationBar显示成红色,然后用手势向→拉一很小段距离,然后放开,等于取消返回操作,这个时候NavigationBar显示就变成了白色,上面的状态栏也变成了透明的

本文标题:iOS之导航栏详解

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