首页 > 代码库 > ios UINavigationController 导航栏

ios UINavigationController 导航栏

1.关于导航栏左右两边的按钮

1.隐藏导航栏上的返回字体
//Swift
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), forBarMetrics: .Default)
//OC
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];

//设置导航栏右边有2个按钮
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:view];
self.navigationItem.rightBarButtonItem = item;

系统默认的rightBarButtonItem边距
self.navigationItem.leftBarButtonItem.imageInsets = UIEdgeInsetsMake(0,-20,0,0);
self.navigationItem.rightBarButtonItem.imageInsets = UIEdgeInsetsMake(0,-10,0,10);

//使左边导航栏按钮位置更加左边一点
{
    UIView *left = [[UIView alloc] init];
    left.frame = CGRectMake(0, 0, 0, 1);
    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:left];
    
    //使导航栏按钮位置更加左边或者右边
    UIBarButtonItem *nagetiveSpacer = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    nagetiveSpacer.width = -40;//这个值可以根据自己需要自己调整
    
    self.navigationItem.leftBarButtonItems = @[nagetiveSpacer,item];
}

UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:back];
item.width = -20;

2.修改标题

//标题颜色
self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor someColor]}

//设置了导航条背景颜色,会导致按钮标题颜色改变,通过以下方法修改
导航栏子控件颜色
self.navigationController.navigationBar.tintColor = [UIColor someColor];

修改导航条背景颜色
self.navigationController.navigationBar.barTintColor = [UIColor colorWithHexString:@"#2295f2"];

  //设置导航控制器标题的颜色和字体大小等

  NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:

                              [UIColor whiteColor],NSForegroundColorAttributeName,

                              [UIFont systemFontOfSize:17],NSFontAttributeName,nil];

  [self.navigationController.navigationBar setTitleTextAttributes:attributes];

3.在滑动过程中隐藏navigationbar

(1) 像safari
self.navigationController.hidesBarsOnSwipe = YES;
(2)
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat offsetY = scrollView.contentOffset.y + __tableView.contentInset.top;
    CGFloat panTranslationY = [scrollView.panGestureRecognizer translationInView:self.tableView].y;
    if (offsetY > 64) {
        if (panTranslationY > 0)
        {
            //下滑趋势,显示
            [self.navigationController setNavigationBarHidden:NO animated:YES];
        } else {
            //上滑趋势,隐藏
            [self.navigationController setNavigationBarHidden:YES animated:YES];
        }
    } else {
        [self.navigationController setNavigationBarHidden:NO animated:YES];
    }
}
这里的offsetY > 64只是为了在视图滑过navigationBar的高度之后才开始处理,防止影响展示效果。panTranslationY是scrollView的pan手势的手指位置的y值,可能不是太好,因为panTranslationY这个值在较小幅度上下滑动时,可能都为正或都为负,这就使得这一方式不太灵敏.
(3).当我们的手离开屏幕时候隐藏
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
    if(velocity.y > 0)
    {
        [self.navigationController setNavigationBarHidden:YES animated:YES];
    } else {
        [self.navigationController setNavigationBarHidden:NO animated:YES];
    }
}
velocity.y这个量,在上滑和下滑时,变化极小(小数),但是因为方向不同,有正负之分,这就很好处理了。

4.设置导航栏透明度

//第一种navigationBar根据滑动距离的渐变色实现
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat offsetToShow = 200.0;//滑动多少就完全显示
    CGFloat alpha = 1 - (offsetToShow - scrollView.contentOffset.y) / offsetToShow;
    [[self.navigationController.navigationBar subviews] objectAtIndex:0].alpha = alpha;
}

//第二种
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat offsetToShow = 200.0;
    CGFloat alpha = 1 - (offsetToShow - scrollView.contentOffset.y) / offsetToShow;
    
    [self.navigationController.navigationBar setShadowImage:[UIImage new]];
    [self.navigationController.navigationBar setBackgroundImage:[self imageWithColor:[[UIColor orangeColor]colorWithAlphaComponent:alpha]] forBarMetrics:UIBarMetricsDefault];
}

//生成一张纯色的图片
- (UIImage *)imageWithColor:(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 *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return theImage;
}
设置导航栏透明
//方法一:设置透明度
[[[self.navigationController.navigationBar subviews]objectAtIndex:0] setAlpha:0.1];
//方法二:设置背景图片
/**
 * 设置导航栏,使其透明
 *
 */
- (void)setNavigationBarColor:(UIColor *)color targetController:(UIViewController *)targetViewController{
    //导航条的颜色 以及隐藏导航条的颜色targetViewController.navigationController.navigationBar.shadowImage = [[UIImage alloc]init];
    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 *theImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); [targetViewController.navigationController.navigationBar setBackgroundImage:theImage forBarMetrics:UIBarMetricsDefault];
}

//3
//设置一张空的图片
[self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc]init] forBarMetrics:UIBarMetricsDefault];
//清除边框,设置一张空的图片(隐藏底部阴影条,传递一个空图片的UIImage对象),底部的黑线
[self.navigationController.navigationBar setShadowImage:[[UIImage alloc]init]];
//是否透明
self.navigationController.navigationBar.translucent = YES;

5.滑动返回手势

//关闭navigationController的滑动返回手势
//第一种
self.navigationController.interactivePopGestureRecognizer.enabled = NO;

//第二种
id target = self.navigationController.interactivePopGestureRecognizer.delegate;
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:nil];
[self.view addGestureRecognizer:pan];

//解决导航控制器pop手势失效
self.interactivePopGestureRecognizer.delegate = self;

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    // 手势何时有效 : 当导航控制器的子控制器个数 > 1就有效
    return self.childViewControllers.count > 1;
}

6.导航栏的隐藏显示问题(正确的姿势)

1.// 设置导航控制器的代理为self
self.navigationController.delegate = self;

2.<UINavigationControllerDelegate>

3.// 将要显示控制器
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    // 判断要显示的控制器是否是自己
    BOOL isShowHomePage = [viewController isKindOfClass:[self class]];
    
    [self.navigationController setNavigationBarHidden:isShowHomePage animated:YES];
}

7.修改pop回来的页面

#warning  写在 C 的 viewDidLoad() 方法中
//A push 到 B, B push 到 C, C pop 到 D,D 再 pop到 A
// 建立可变拷贝对象,然后进行替换操作
NSMutableArray *navChildMArr = [self.navigationController.childViewControllers mutableCopy];
[navChildMArr replaceObjectAtIndex:1 withObject:D];

// 当然,最后再将替换后的数组赋值回去不要忘了
[self.navigationController setViewControllers:navChildMArr animated:YES];

 

修改pop回来的页面

ios UINavigationController 导航栏