iOS Developer@IT·互联网程序员

iOS Navigation导航栏

2017-05-18  本文已影响0人  xyzcwb

在iOS开发过程中,导航栏是最为经常用到的控件,处理不好总会出现一些瑕疵或者bug,写这篇文章旨在为自己记录平时所用有关Navigation一些操作或者说是小技巧。
下文涉及到的push逻辑都是从A页面push到B页面,我会直接以A、B介绍

一、关于返回Item

默认从A—>B(push),B中返回按钮的title显示的是A的标题,当A的标题过长,会显示返回(back)。A标题长同时B标题也长,就会出现B标题被挤到右边了,这就尴尬了。如下图


B标题未正常显示

网上有说在A的viewWillDisappear将A的标题设置成空的,在viewDidAppear方法中再将标题设置原来的,但是这个在手势侧滑过程中显示会有问题,这里就不做演示了。
这里提供一个解决方案:让A控制器继承自BaseViewController(自己创建的控制器),在BaseViewController做以下操作:

- (void)viewDidLoad {
    [super viewDidLoad];
    UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@"返回"
                                                                 style:UIBarButtonItemStyleDone
                                                                target:self
                                                                action:nil];
    self.navigationItem.backBarButtonItem = backItem;
}
正常显示

有时我们并不需要显示title,在上图中的“返回”设置成 nil 就可以解决问题。当然我们刚才并没有改变返回的图片都是用系统默认的,如果只是单纯的显示自定义的返回图标(需求就是这么样,有什么办法),那么问题来了,怎么设置比较合理。以
下给出几种方案:

1、设置navigationItem的leftBarButtonItem(不推荐)
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"navigation_back"]
                                                             style:UIBarButtonItemStylePlain
                                                            target:self
                                                            action:@selector(p_actionBack)];
self.navigationItem.leftBarButtonItem = backItem;
自定义返回按钮

只是添加leftBarButtonItem侧滑手势被禁止了,图标离左侧有一定距离,经过如下修改:

- (void)p_addBackItem {
    //间隙
    UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:self action:nil];
    //spaceItem宽度为负值,相当于左移
    spaceItem.width = -8;
    UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"navigation_back"]
                                                                 style:UIBarButtonItemStylePlain
                                                                target:self
                                                                action:@selector(p_actionBack)];
    self.navigationItem.leftBarButtonItems = @[spaceItem, backItem];
    //设置代理,添加leftBarButtonItem系统的侧滑手势会被禁
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
       self.navigationController.interactivePopGestureRecognizer.delegate = self;
    }
}
 - (void)p_actionBack {
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    return YES;
}
自定义
2、将title移出视图外,从而达到隐藏的效果(推荐,作用范围全局)

注意:这个需要在AppDelegate设置才有效

- (void)initBars {
    UIImage *backImage = [UIImage imageNamed:@"navigation_back"];
    UINavigationBar *navigationbar = [UINavigationBar appearance];
    [navigationbar setBackIndicatorImage:backImage];
    [navigationbar setBackIndicatorTransitionMaskImage:backImage];
    [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60)
                                                         forBarMetrics:UIBarMetricsDefault];
}
设置偏移量,替换系统返回按钮
上一页标题过长

对比可以发现,第一张图是标题比较短的时候显示正常,第二张图是标题比较长的时候标题被往右挤了。


视图下查看 这个方法只是将返回Item的title移出,宽度并没有改变,所以在使用这个方法时一定要注意,我一般是配合一开始提到的搭配使用。如果有更好的解决方法可以留言告知,不胜感激。

二、Navigation显示或隐藏

项目中一般有一两个页面比较特殊,需要隐藏导航栏或者导航栏需要根据滑动渐变,如登录页面需要隐藏导航栏。隐藏简单,拿起键盘就是干。

1、隐藏导航栏

使用[self.navigationController setNavigationBarHidden:NO animated:YES] 侧滑手势会被禁,所以需要加代理开启手势

- (void)viewDidLoad {
    [super viewDidLoad];
    //设置代理
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.delegate = self;
    }
}
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    //会导致侧滑手势被禁
    [self.navigationController setNavigationBarHidden:YES animated:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    //如果该控制器没有上级控制器,建议将使用[self.navigationController setNavigationBarHidden:NO animated:animated] 效果会更好点
    [self.navigationController setNavigationBarHidden:NO animated:NO];
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    return YES;
}
2、导航栏渐变

介绍两个方法:

//隐藏导航栏,但不隐藏上面的Item
[self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init]
                                              forBarMetrics:UIBarMetricsDefault];
//隐藏导航栏底部那条线
[self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];

这个不做演示,推荐一个三方 LTNavigationBar

三、自定义TitleView

直接上代码

UIView *titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 40)];
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
switchView.center = titleView.center;
[titleView addSubview:switchView];
self.navigationItem.titleView = titleView;
自定义TitleView
上一篇下一篇

猜你喜欢

热点阅读