系统自带的NavigationBar局限性比较大,往往开发中我们需要制作比较精美的导航栏。常见的导航栏都是由三部分组成的。 如下图所示, 左边的按钮视图, 中间的视图,右侧的按钮视图。本篇文章我们就来模拟Path这个软件的NavigationBar。
AppDelegate.h
#import <UIKit/UIKit.h>
#import "MyViewController.h"
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UINavigationController *navController;
@property (strong, nonatomic) UIViewController *viewController;
@end
AppDelegate.m
#import "AppDelegate.h"
@implementation AppDelegate
@synthesize window = _window;
@synthesize navController;
@synthesize viewController;
- (void)dealloc
{
[_window release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.window.backgroundColor = [UIColor whiteColor];
self.viewController = [[[MyViewController alloc]init]autorelease];
self.navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
[self.window addSubview:navController.view];
[self.window makeKeyAndVisible];
return YES;
}
@end
MyViewController.m
#import "MyViewController.h"
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//设置导航栏背景图片
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"nav-bar.png"] forBarMetrics:UIBarMetricsDefault];
//导航栏正中央图片
UIImage * titleImage = [UIImage imageNamed:@"nav-logo.png"];
UIImageView * titleview = [[UIImageView alloc]initWithImage:titleImage];
//加在导航栏中
self.navigationItem.titleView =titleview;
//绘制导航栏右侧的图片按钮
UIImage *rightButtonImage = [UIImage imageNamed:@"nav-bar-button.png"];
UIImage *rightbuttonNormal = [rightButtonImage
stretchableImageWithLeftCapWidth:10 topCapHeight:10];
//设置按钮类型为自定义
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
//设置按钮的显示区域
[rightButton setFrame: CGRectMake(0, 0, 50, 40)];
//设置按钮的背景显示图
[rightButton setBackgroundImage:rightbuttonNormal forState:UIControlStateNormal];
//设置按钮的前景显示图
[rightButton setImage:[UIImage imageNamed:@"nav-friends-icon.png"] forState:UIControlStateNormal];
[rightButton setImage:[UIImage imageNamed:@"nav-friends-icon.png"] forState:UIControlStateHighlighted];
//监听点击事件
[rightButton addTarget:self action:@selector(RightDown) forControlEvents:UIControlEventTouchDown];
//加载导航栏中
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:rightButton];
//含义和上面类似就不详解了
//绘制导航栏左侧的图片按钮
UIImage *leftButtonImage = [UIImage imageNamed:@"nav-bar-button.png"];
UIImage *leftbuttonNormal = [leftButtonImage
stretchableImageWithLeftCapWidth:10 topCapHeight:10];
UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
[leftButton setFrame: CGRectMake(0, 0, 50, 40)];
[leftButton setBackgroundImage:leftbuttonNormal forState:UIControlStateNormal];
[leftButton setImage:[UIImage imageNamed:@"nav-menu-icon.png"] forState:UIControlStateNormal];
[leftButton setImage:[UIImage imageNamed:@"nav-menu-icon.png"] forState:UIControlStateHighlighted];
[leftButton addTarget:self action:@selector(leftDown) forControlEvents:UIControlEventTouchDown];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:leftButton];
}
-(void) leftDown
{
NSLog(@"按下左边按钮");
}
-(void) RightDown
{
NSLog(@"按下右边按钮");
}
@end
最后我仔细说几个重要的方法。
self.navigationItem.titleView //导航栏中间显示内容
self.navigationItem.leftBarButtonItem //导航栏左侧显示内容
self.navigationItem.rightBarButtonItem //导航栏右侧显示内容
这个是IOS5独有的方法,可以直接设置导航栏背景图片。
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"nav-bar.png"] forBarMetrics:UIBarMetricsDefault];
最后再说一下拉伸图片的方法 默认在UIImageView中设置Rect属性后中间的图片将会被拉伸,矩形图片被拉伸还好,可是圆角图片被拉伸就会非常不好看。如下图所示,按钮的圆角被拉伸了好多,非常难看。
如下图所示,它就是项目中我们使用到的导航栏按钮的背景图,做过Android的朋友应该会想到9path吧。蛤蛤。其实它们的原理都是一样的,无论是怎么样的圆角图片我们只需要让程序去拉伸图片中央最重要的矩形,而四周的圆角部分不会被拉伸。这样圆角图片无论怎么拉伸都不会出现变形的情况。
![]()
在代码中我们通过这样的方法来重新得到UIImage对象,参数1表示从左边开始数多少个像素的图片区域不会拉伸,参数2表示从上面开始数多少个像素的图片区域不会被拉伸。
UIImage *rightbuttonNormal = [rightButtonImage stretchableImageWithLeftCapWidth:10topCapHeight:10];
细心的朋友可能会想 切图的话 左边 上面参数都给出了为什么没有右边下边呢?其实上面的这个方法会镜像的对应在右侧与下侧,它们都是等比对应的。
最后的这个简单DEMO的源代码,希望大家喜欢,雨松MOMO祝大家学习愉快。
源码下载地址:http://vdisk.weibo.com/s/acehY
8月13号补充
导航栏中其实还有个比较重要的按钮,就是返回按钮。比如A界面-》B界面,此时B界面左上角应当有一个返回A界面的按钮,然而默认的按钮比较单调,那么我们学习如何自定义这个返回按钮。
如果A界面-》B界面,请把添加返回按钮的代码添加在A界面的ViewController中,因为只有这样当A界面切换至B界面时,B界面就可以看到左上角返回的按钮了。
UIImage *leftButtonImage = [UIImage imageNamed:@"nav-bar-back-button.png"];
UIImage *leftbuttonNormal = [leftButtonImage
stretchableImageWithLeftCapWidth:15 topCapHeight:15];
UIBarButtonItem *item = [[[UIBarButtonItem alloc]init] autorelease];
[item setBackButtonBackgroundImage:leftbuttonNormal forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[item setTitle:@"雨松MOMO"];
self.navigationItem.backBarButtonItem = item;
效果如下所示
- 本文固定链接: https://www.xuanyusong.com/archives/1514
- 转载请注明: 雨松MOMO于 雨松MOMO程序研究院 发表




感谢分享 收获很大呀
建议换掉stretchableImageWithLeftCapWidth 改用 resizableImageWithCapInsets
吼吼,带领一排人,超过雨松MOMO…..哈哈,加油MOMO!!!一直坚持下去!
感谢小马。。加油
博主你写的文章不错,有机会多交流,我也有一个博客,http://lxzngpzh.com/