在作ViewControlller的navigationItem时,咱们常常须要使用自定义的图片来替换系统默认的按钮样式,这点在对普通导航项,好比leftBarButtonItem或rightBarButtonItem来讲仍是比较简单的,经过UIBarButtonItem的setImage设置作好的图片按钮,而后再经过api
[item setBackgroundImage:[UIImage new] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
去掉默认的背景image就能够了。可是若是是想自定义特殊的backBarButtonItem就比较麻烦了,直接使用和普通item同样的方法,会发现根本没有效果,这是由于就算同为UIBarButtonItem,back方式的处理也是和通常的不同的,api里专门提供了一套setBackButtonXXX的api,如setBackButtonBackgroundImage来提供给UIBarButtonItem用做back button时的参数设置,虽然也有setBackButtonBackgroundImage能够用,可是替换完会发现图片被以局部拉伸平铺的方式适应了按钮的大小,这样若是你的图片按钮能够这么作,好比和默认效果累死,只是换个颜色,换个边框,或者甚至是也支持这种局部拉伸平铺的作法,就还好说,调整一下拉伸范围参数就能够了,可是若是是固定图形,不像自适应拉伸的话就比较麻烦了,本人试了几种操做组合,发现不是须要去掉button title就是背景重叠,各类效果不对。这时看到有人说自定义backBarButtonItem确实比较麻烦,建议能够以hide的方式隐藏默认返回按钮,同时配合leftBarButtonItem样式和自定义响应函数中调用navigation的pop来实现相似效果,这种方法虽然确实可行,可是总感受有默认的行为(并且当前页的back实际是显示在导航切换到的下一页上的,直接替换还要考虑这点!)不用而本身模拟替代这样不是很妥,因而又查找了一些资料,终于找到了能够在不缩放图片,不去掉title的前提下,替换backBarButton图片的方法:app
UIImage* image = [UIImage imageNamed:@"back_button.png"]; [item setBackButtonBackgroundImage:[image resizableImageWithCapInsets:UIEdgeInsetsMake(0, image.size.width, 0, 0)] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; [item setBackButtonTitlePositionAdjustment:UIOffsetMake(-400.f, 0) forBarMetrics:UIBarMetricsDefault]; self.navigationItem.backBarButtonItem = item;
原理很简单,第一行加载图片,第二行以加载图片的宽度结合resizableImageWithCapInsets生成一个缩放时不会拉伸的新图片做为BackButtonBackgroundImage,再在第三行设置title的位置偏移到一个不可见的位置,达到隐藏的目的。另外,若是须要所有统一替换,也能够在app的didFinishLaunching里通[UIBarButtonItem appearance]所有统一替换!ide