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