定制UINavigationBar

简介: 在开发中经常需要定制某些界面,navigationController的navigationBar就是一个很典型的例子,比如要修改背景图、后退按钮等等。

在开发中经常需要定制某些界面,navigationController的navigationBar就是一个很典型的例子,比如要修改背景图、后退按钮等等。

背景图的修改很简单,但是需要了解iOS的框架,假设我给自己定制的UINavigationController增加一个接口用于修改背景图:

@property (nonatomic, retain) UIImage *backgroundImage;
那么该消息的实现如下:

-(void)setBackgroundImage:(UIImage *)backgroundImage{
    if ([self.navigationBar respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]) {
        [self.navigationBar setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault];
        return;
    }
    self.navigationBar.layer.contents = (id)backgroundImage.CGImage;
}

iOS 5增加了大量API,可以基本满足我们的定制需求,所以如果是iOS 5,我们直接调5的API就行了,而最后一行代码是针对5以下的,也就是说这一行代码就可以修改了,写起来容易但是要知道为什么。众所周知一个视图如何显示是取决于它的drawRect方法,因为调这个方法之前iOS也不知道如何显示它,但其实drawRect方法的目的也是画图(显示内容),而且我们如果以其他的方式给出了内容(图)的话,drawRect方法就不会被调用了。

注:实际上UIView是CALayer的delegate,如果CALayer没有内容的话,会回调给UIView的displayLayer:或者drawLayer:inContext:方法,UIView在其中调用drawRect,draw完后的图会缓存起来,除非使用setNeedsDisplay或是一些必要情况,否则都是使用缓存的图。

虽然往navigationBar里面插入一个imageView也能达到这种目的,但是要麻烦得多,因为你要自己管理navigationBar的视图层级,原因在于iOS 4和iOS 5的版本不同,往navigationBar插入视图的位置是相反的,不处理的话会导致部份子视图被遮住。

-----------------------------------------猥琐的分界线-----------------------------------------

如果只想更改后退按钮的标准属性,比如title、target、action,那么就:

    UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] init];
    backButtonItem.title = @"已改的";
    backButtonItem.target = self;
    backButtonItem.action = @selector(back);
    self.navigationItem.backBarButtonItem = backButtonItem;
    [backButtonItem release];
只要注意一点,这个设置是 针对于子导航层级的,也就是你push到下个视图控制器的时候才会看到。

如果是想更改字体、颜色、背景之类的,就要用到UIButton了:

    UIButton *back = [UIButton buttonWithType:UIButtonTypeCustom];
    [back setTitle:@"已改" forState:UIControlStateNormal];
    [back setFrame:CGRectMake(0, 0, 100, 32)];
    [back setBackgroundColor:[UIColor redColor]];
    UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:back];
    self.navigationItem.leftBarButtonItem = backButtonItem;
    [backButtonItem release];
完全当成一个button来用,注意和上面的不同:赋给了 leftBarButtonItem

如果你不知道何时添加这个自己的后退按钮?很简单,判断navigationBar.backItem有没有就行了,跟着系统走是不会错的,不过可能要再判断一下当前显示的viewController有没有用到leftBarButtonItem,不要覆盖掉逻辑就行了。


-----------------------------------------如有问题,请指出-----------------------------------------


目录
相关文章
|
6月前
|
存储 运维 BI
万字长文带你深入广告场景Paimon+Flink全链路探索与实践
本文将结合实时、离线数据研发痛点和当下Paimon的特性,以实例呈现低门槛、低成本、分钟级延迟的流批一体化方案,点击文章阅读详细内容~
|
Java TensorFlow 算法框架/工具
【tensorflow】TF1.x保存.pb模型 解决模型越训练越大问题
在上一篇博客【tensorflow】TF1.x保存与读取.pb模型写法介绍介绍的保存.pb模型方法中,保存的是模型训练过程中所有的参数,而且训练越久,最终保存的模型就越大。我的模型只有几千参数,可是最终保存的文件有1GB。。。。
170 0
|
XML 数据格式
加载 XML 字符串
这段代码演示了在不同浏览器中加载和解析XML字符串的方法:非IE浏览器使用DOMParser的parseFromString方法,而IE则使用ActiveXObject的loadXML方法。
|
JSON 前端开发 Java
Swagger介绍及使用
Swagger介绍及使用
204 2
|
监控 JavaScript 数据可视化
一个Vue3搭建的低代码数据可视化开发平台
一个Vue3搭建的低代码数据可视化开发平台
760 0
|
Dubbo Java 应用服务中间件
【从零开始学微服务】07.微服务常用的开发框架
大家好,欢迎来到万猫学社,跟我一起学,你也能成为微服务专家。
204 1
|
Python
Python 继承和子类示例:从 Person 到 Student 的演示
继承允许我们定义一个类,该类继承另一个类的所有方法和属性。父类是被继承的类,也叫做基类。子类是从另一个类继承的类,也叫做派生类。
165 0
|
人工智能 安全 自动驾驶
GPT-4是8x2200亿参数的混合模型?这个小道消息今天传疯了
GPT-4是8x2200亿参数的混合模型?这个小道消息今天传疯了
237 0
|
Shell Linux 开发者
Shell公共函数库|学习笔记
快速学习Shell公共函数库
166 0
Shell公共函数库|学习笔记