前言

一直以来都让我很头痛的一个问题:系统自带的导航条,在标题文字很长时,进入到下一个界面,而下一个界面的标题也很长时,就会出现标题不居中显示。

曾经,我尝试过很多种办法,但是都没有从根上解决问题。下面笔者分别说说用过哪些方案。

方案一(不可行)

这个方案是不使用系统自带默认的backButtonItem,而是使用leftBarButtonItem

这样做的好处是:解决了本界面标题过长,而上一个界面的标题也很长时,本界面的标题不居中显示的问题。

这样做的坏处是:系统自带的右滑返回手势就没有了。

方案二(不可行)

这里我们自定义一个继承于UINavigationController的类,然后所有使用导航类的地方都使用我们所定义的导航控制器类。在这个类中,我们通过配置全局的导航条相关全局属性

 - (void)config {
NSString *backImageName = @"default_back"; if (kIsIOS7OrLater) {
UIImage *image = [UIImage imageNamed:backImageName];
CGFloat w = image.size.width;
if (kScreenWidth <= ) {
w = ;
}
self.navigationBar.backIndicatorImage = image;
UIImage *backButtonImage = [image resizableImageWithCapInsets:UIEdgeInsetsMake(, w, , -w)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage
forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
// 将返回按钮的文字position设置不在屏幕上显示
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(NSIntegerMin, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];
self.interactivePopGestureRecognizer.enabled = YES;
} else {
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
UIBarButtonItem *item = [[UIBarButtonItem alloc] init];
UIImage *image = [UIImage imageNamed:backImageName];
[item setBackButtonBackgroundImage:[image resizableImageWithCapInsets:UIEdgeInsetsMake(, image.size.width, , )] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[item setBackgroundImage:image forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[item setBackButtonTitlePositionAdjustment:UIOffsetMake(NSIntegerMin, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];
self.navigationItem.backBarButtonItem = item;
#endif
} return;
}

因此这里,我们需要使用自定义的返回箭头,而且不显示返回按钮的文字。因此,我们需要设置如下:

[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(NSIntegerMin, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];

但是,仅仅部分标题是正常显示,还是有一些地方有不居中的。因此,我们还需要再添加一些代码解决。

下面,我们使用了全局设置UIBarButtonItem的字体大小为1

NSDictionary *attributes = @{NSFontAttributeName : [UIFont systemFontOfSize:]};
[[UIBarButtonItem appearance] setTitleTextAttributes:attributes
forState:UIControlStateNormal];

这样确实解决了我们的问题。标题没有出现不居中显示的了,但是又引发了新的问题。因为我们是全局将UIBarButtonItem的字体大小修改为1,那么所有使用了这个控件的地方,都会不显示了。除非我们每个使用的地方再重新设置其字体大小。

因此,此方案也不可行。

方案三(可行,但不太好)

应用中始终隐藏系统自带的导航,然后自定义一个UIView作为导航,这样就解决居中显示的问题,但是没有了返回手势,因此需要借助第三方库追加右滑返回手势功能,但是体验不如原生的好。

方案四(当前最终方案)

自定义一个继承于UINavigationController的类,然后所有使用导航类的地方都使用我们所定义的导航控制器类。在这个类中,我们通过配置全局的导航条相关全局属性。

 - (void)config {
NSString *backImageName = @"default_back"; if (kIsIOS7OrLater) {
UIImage *image = [UIImage imageNamed:backImageName];
CGFloat w = image.size.width;
if (kScreenWidth <= ) {
w = ;
}
self.navigationBar.backIndicatorImage = image;
UIImage *backButtonImage = [image resizableImageWithCapInsets:UIEdgeInsetsMake(, w, , -w)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage
forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
// 将返回按钮的文字position设置不在屏幕上显示
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(NSIntegerMin, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];
self.interactivePopGestureRecognizer.enabled = YES;
} else {
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
UIBarButtonItem *item = [[UIBarButtonItem alloc] init];
UIImage *image = [UIImage imageNamed:backImageName];
[item setBackButtonBackgroundImage:[image resizableImageWithCapInsets:UIEdgeInsetsMake(, image.size.width, , )] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[item setBackgroundImage:image forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[item setBackButtonTitlePositionAdjustment:UIOffsetMake(NSIntegerMin, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];
self.navigationItem.backBarButtonItem = item;
#endif
} return;
}

然后,我们在每个控制器的viewDidLoad方法中,调用这么个方法:

- (void)resetBackButtonItem {
NSArray *viewControllerArray = [self.navigationController viewControllers]; long previousViewControllerIndex = [viewControllerArray indexOfObject:self] - ;
UIViewController *previous; if (previousViewControllerIndex >= ) {
previous = [viewControllerArray objectAtIndex:previousViewControllerIndex];
previous.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]
initWithTitle:@""
style:UIBarButtonItemStylePlain
target:self
action:nil];
}
}

这个方法是我们用于判断是否有上一个界面,如果有,则将上一个界面的返回按钮的标题设置为空,那么在本界面的返回按钮就不会有标题,如此一来,就解决了上个界面的标题过长,而本界面标题也很长时,导致本界面的标题不居中显示的问题

建议

我们可以将这resetBackButtonItem方法放到基类控制器中,然后在基类控制器中的viewDidLoad方法中调用,就不需要各个类都调用了。当然,如果现在类似笔者当前的情景,就需要手动各个界面都调用了。当前笔者的情景是,项目是由很多个团队敏捷迭代开发的,如果全局统一改,很有可能会影响到他人的版本,因此不得不只在需要处理的控制器调用。

转载地址:http://blog.csdn.net/woaifen3344/article/details/50035609

 

  

 

iOS导航标题不居中问题(转载)的更多相关文章

  1. react-navigation 做导航栏,发现 Android 上的标题不居中

    在做 React Native 应用的时候,我们常常使用 react-navigation 做导航栏,发现 Android 上的标题不居中,IOS 上没问题. 1 如果只有标题,那就在 headerT ...

  2. 关于ios导航控制器的知识总结

    关于ios导航控制器的知识总结 添加了导航控制器后: 1.一个导航控制器会有一个顶部导航栏navigationbar和一个底部工具栏toolbar,它们是导航控制器navC的属性.且导航栏默认是不隐藏 ...

  3. iOS导航栏主题

    主要是取得导航栏的appearance对象,操作它就设置导航栏的主题 UINavigationBar *navBar = [UINavigationBar appearance]; 常用主题设置 导航 ...

  4. 横向滑动页面,导航条滑动居中的 js 实现思路

    最近在做新闻咨询页的项目,各个新闻频道通过横向滑动切换,顶部的导航active栏需要跟着切换到对应频道,并且active到达中部时,要一直处在中间. 类似效果就是uc浏览器<UC头条>的导 ...

  5. uniapp动态改变底部tabBar和导航标题navigationBarTitleText

    在开发中,我们会遇到需求国际化,那么底部tabBar和导航标题navigationBarTitleText就要动态切换: 1.改变底部tabBar: uni.setTabBarItem({ index ...

  6. iOS导航栏标题颜色

    按钮的颜色 [self.navigationBar setTintColor:[UIColor whiteColor]]; 标题颜色.字体 [self.navigationBar setTitleTe ...

  7. iOS导航栏背景,标题和返回按钮文字颜色

    在iOS7下,默认导航栏背景,颜色是这样的,接下来我们就进行自定义,如果你仅仅是更改一下背景和颜色,代码会很简单,不需要很复杂的自定义View来替代leftBarItem 更改导航栏的背景和文字Col ...

  8. 关于iOS导航控制器隐藏和显示会出现返回键失效,导航栏标题动画异常

    最近做的demo  bug出现了,我觉得这个bug出现得很经典所以贴出来给大家看看, bug演示就是:点击返回键失效出现如下gif图演示的内容 为啥会出现如此奇葩的bug,系统的返回键居然失效了,尴尬 ...

  9. react-navigation android 导航标题居中

    先贴下代码供参考: 安卓默认导航的titile 是在左侧的,为了和iOS保持一致,需要添加 alignSelf:'center',这个 属性 但是会遇到title有点偏右的情况 添加headerRig ...

随机推荐

  1. 自定义HttpFilter模块完善

    自定义HttpFilter模块完善   背景 在12月由于要针对项目做用户操作日志,但不想在每个方法里去增加代码,写入用户日志.因为这样具体的方法违背职责单一的原则,若后期日志内容格式发生变更,或其他 ...

  2. Vijos: P1046观光旅游

    背景 湖南师大附中成为百年名校之后,每年要接待大批的游客前来参观.学校认为大力发展旅游业,可以带来一笔可观的收入. 描述 学校里面有N个景点.两个景点之间可能直接有道路相连,用Dist[I,J]表示它 ...

  3. 【学习笔记】锋利的jQuery(三)事件和动画

    一.jQuery事件 1,加载事件 $(document).ready(function(){...}) //等同于$(function(){..}) $(window).load(function( ...

  4. [Usaco2008 Feb]Eating Together麻烦的聚餐[最长不下降子序列]

    Description 为了避免餐厅过分拥挤,FJ要求奶牛们分3批就餐.每天晚饭前,奶牛们都会在餐厅前排队入内,按FJ的设想所有第3批就餐的奶牛排在队尾,队伍的前端由设定为第1批就餐的奶牛占据,中间的 ...

  5. C#操作Kentico cms

    C#操作Kentico cms 中的 content(winform环境) 前段时间做了个winform程序,去管理kentico网站的content,包括content节点的增删改查,以及相应节点内 ...

  6. MVC3+EF5.0 code first+Flexigrid+ajax请求+jquery dialog 增删改查

    MVC3+EF5.0 code first+Flexigrid+ajax请求+jquery dialog 增删改查 本文的目的:   1.MVC3项目简单配置EF code first生成并初始化数据 ...

  7. C#代码和javascript函数相互调用

    C#代码与javaScript函数的相互调用 问:1.如何在JavaScript访问C#函数?2.如何在JavaScript访问C#变量?3.如何在C#中访问JavaScript的已有变量?4.如何在 ...

  8. Cocoa框架

    Cocoa提供了用于存放数字和字符串的通用数据类型的实际的类.非正式地可以将这些称为值类或基本值类. Cocoa框架本身封装了三个独立的框架:Foundation基本框架.AppKit框架和核心数据框 ...

  9. 基于libgdx游戏引擎开发的飞天猫

    闲来没事学学游戏,这是鄙人第一个小游戏——飞天猫 1,基于Android开发的小游戏,至少Android2.2以上的系统. 2,界面简洁,美观,游戏易操作,上手快. 3,可以左右摇摆手机来改变飞天猫的 ...

  10. Nodejs应用安全备忘录

    本人新博客www.wjs.photo,基于360的firekylin,感兴趣的可以看看哈 本文翻译自 www.risingstack.com ,并非逐字逐句的翻译,有错误的地方请指出,谢谢啦 应用程序 ...