UITabBarController和UINavigationController的整合使用
2016-01-27 15:38
1126 查看
好多项目都同时用到了UITabBarController和UINavigationController,XCode可以直接创建这两个控制器中的其中一个,但是要一起用的话就得稍微麻烦点。
从这张图可以看到:最右边的Assembled views是呈现给用户的界面,它左边的Window是最底层的窗口,重点来了,再往左,是Tab bar view,Tab bar view的上方是Navigation view,最后是用户定制的视图。
看完这个,代码就应该很好写了,我们需要把Navigation view加到 Tab bar view的内容上去,Tab bar view再加到Window上去。就是Window套UITabBarController,UITabBarController套UINavigationController, UINavigationController套UIViewController。
好了,接下来,我们开始实战。
ViewController.h、ViewController.m和Main.storyboard。
点击Next,继承于UITabBarController,不用勾选Also Create XIB file,如下图:
如下图:
FirstViewController:
SecondViewController:
创建好后,现在的文件目录结构是这样的
直接上代码:
直接看代码注释就可以大致了解流程:UIViewController加到UINavigationController上,UINavigationController加入UITabBarController,跟上面的层级关系图相符。
我们现在可以运行一下,会提示如下错误:
‘NSInvalidArgumentException’, reason: ‘Could not find a storyboard named ‘Main’ in bundle NSBundle
看这个提示,原来是我们步骤2中删除了Main.storyboard,但是程序设置的Main Interface默认是Main,这肯定会报错了。我们需要修改一下项目的配置,就暂且改成LaunchScreen吧,如下图:
我们再次运行一下,应该是没问题的,效果已经出来了,如下图:
我们把每页的title加一下,方便看效果:
FirstViewController.m
SecondViewController.m
再次运行,点击相应的标签图片,就可以看到效果了:
文件新建好之后,我们给这个页面加上标题:
DetailsViewController.m
我们接下来在FirstViewController.xib里加一个按钮,然后连线到FirstViewController.m文件里实现点击事件,如下图:
FirstViewController.m里的点击事件代码:
通过上面的代码,点击Go就可以跳转到DetailsViewController页面。
注意第四行,如果我们需要在进入Details页面之后隐藏底部的标签栏,可以在这里设置hidesBottomBarWhenPushed为YES。注意,在DetailsViewController.m文件中的viewDidLoad方法中调用是没效果的,在viewWillAppear里也不行,只有在init方法中调用才可以,如以下代码:
再次运行,点击Go按钮,顺利跳转到了Details页面:
到此,就已经算是实现了TabBar和Navigation的整合使用。
MainViewController.m文件中的loadViewControllers方法,在新建firstNC实例之后,加入:
加入上述代码之后,再次运行,可以看到导航栏和状态栏的文字颜色已经更改
进入details页面
还可以自定义每个标签默认和选中的图片,拷入素材图片之后,
在MainViewControllers中,重新定义第一个标签栏Item:
最终效果,如下图:
最后,附上代码下载地址:点击下载
层级关系
首先得搞清这两个控制器之间的层级关系,我们直接看官网给的图,如下所示:从这张图可以看到:最右边的Assembled views是呈现给用户的界面,它左边的Window是最底层的窗口,重点来了,再往左,是Tab bar view,Tab bar view的上方是Navigation view,最后是用户定制的视图。
看完这个,代码就应该很好写了,我们需要把Navigation view加到 Tab bar view的内容上去,Tab bar view再加到Window上去。就是Window套UITabBarController,UITabBarController套UINavigationController, UINavigationController套UIViewController。
好了,接下来,我们开始实战。
具体流程
1、新建Single View Application项目
为了更好的理解,我们直接新建Single View Application2、删除ViewController.h等3个文件
删除如下图所示的3个文件:ViewController.h、ViewController.m和Main.storyboard。
3、新建MainViewController
根据上面的层级关系图,我们需要把UITabBarController加到Window上去,所以在这里,我们直接新建MainViewController,让它继承UITabBarController,如下图所示:点击Next,继承于UITabBarController,不用勾选Also Create XIB file,如下图:
4、修改AppDelegate.m文件
我们为了让MainViewController加到Window上去,修改AppDelegate.m文件,直接上代码,如下所示:#import "AppDelegate.h" #import "MainViewController.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. MainViewController *mainVC = [[MainViewController alloc] init]; self.window.rootViewController = mainVC; return YES; }
5、新建两个标签页
新建FirstViewController和SecondViewController,继承于UIViewController,勾选Also create XIB file如下图:
FirstViewController:
SecondViewController:
创建好后,现在的文件目录结构是这样的
6、修改MainViewController.m
现在,我们需要把刚才创建的页面(First/Second ViewController)加入到导航控制器,再把导航控制器加到标签控制器上去。直接上代码:
#import "MainViewController.h" #import "FirstViewController.h" #import "SecondViewController.h" @interface MainViewController () @end @implementation MainViewController - (void)viewDidLoad { [super viewDidLoad]; // 执行加载控制器 [self loadViewControllers]; } - (void)loadViewControllers { // 1.新建第一页视图控制器实例 FirstViewController *firstVC = [[FirstViewController alloc] init]; // 2.新建第一页导航控制器实例,把firstVC加入进去 UINavigationController *firstNC = [[UINavigationController alloc] initWithRootViewController:firstVC]; // 3.新建第一页的标签栏图标 UITabBarItem *firstTabBarItem =[[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemBookmarks tag:0]; // 4.图标加入到第一页的导航控制器上 firstNC.tabBarItem = firstTabBarItem; // 第二页 SecondViewController *secondVC = [[SecondViewController alloc] init]; UINavigationController *secondNC = [[UINavigationController alloc] initWithRootViewController:secondVC]; UITabBarItem *secondTabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemContacts tag:1]; secondNC.tabBarItem = secondTabBarItem; // 5.新建一个导航控制器实例的数组 NSArray *controllersArray = @[firstNC, secondNC]; // 6.把导航控制器的数组加入到标签控制器 [self setViewControllers:controllersArray animated:YES]; }
直接看代码注释就可以大致了解流程:UIViewController加到UINavigationController上,UINavigationController加入UITabBarController,跟上面的层级关系图相符。
我们现在可以运行一下,会提示如下错误:
‘NSInvalidArgumentException’, reason: ‘Could not find a storyboard named ‘Main’ in bundle NSBundle
看这个提示,原来是我们步骤2中删除了Main.storyboard,但是程序设置的Main Interface默认是Main,这肯定会报错了。我们需要修改一下项目的配置,就暂且改成LaunchScreen吧,如下图:
我们再次运行一下,应该是没问题的,效果已经出来了,如下图:
我们把每页的title加一下,方便看效果:
FirstViewController.m
- (void)viewDidLoad { [super viewDidLoad]; // 设置title self.title = @"main"; }
SecondViewController.m
- (void)viewDidLoad { [super viewDidLoad]; // 设置title self.title = @"second"; }
再次运行,点击相应的标签图片,就可以看到效果了:
7、新建DetailsViewController
为了体现UINavigaitonController,我们需要再新建一个页面,然后在FirstViewController里增加一个按钮,点击按钮跳转到此页面,如下图:文件新建好之后,我们给这个页面加上标题:
DetailsViewController.m
- (void)viewDidLoad { [super viewDidLoad]; // 设置title self.title = @"details"; }
我们接下来在FirstViewController.xib里加一个按钮,然后连线到FirstViewController.m文件里实现点击事件,如下图:
FirstViewController.m里的点击事件代码:
- (IBAction)btnGoOnClick:(id)sender { DetailsViewController *detailsVC = [[DetailsViewController alloc] init]; // 隐藏标签栏 detailsVC.hidesBottomBarWhenPushed = YES; [self.navigationController pushViewController:detailsVC animated:YES]; }
通过上面的代码,点击Go就可以跳转到DetailsViewController页面。
注意第四行,如果我们需要在进入Details页面之后隐藏底部的标签栏,可以在这里设置hidesBottomBarWhenPushed为YES。注意,在DetailsViewController.m文件中的viewDidLoad方法中调用是没效果的,在viewWillAppear里也不行,只有在init方法中调用才可以,如以下代码:
- (instancetype)init { self.hidesBottomBarWhenPushed = YES; return [super init]; }
再次运行,点击Go按钮,顺利跳转到了Details页面:
到此,就已经算是实现了TabBar和Navigation的整合使用。
美化
顶部导航栏
我们可以美化一下顶部导航栏,比如更改背景、文字颜色,还有状态栏文字颜色等。MainViewController.m文件中的loadViewControllers方法,在新建firstNC实例之后,加入:
// 设置导航栏背景图片(需要素材) [firstNC.navigationBar setBackgroundImage:[UIImage imageNamed:@"bg"] forBarMetrics:UIBarMetricsDefault]; // 设置导航栏样式 [firstNC.navigationBar setBarStyle:UIBarStyleBlackTranslucent]; // 设置返回按钮文字和图标颜色 [firstNC.navigationBar setTintColor:[UIColor whiteColor]];
加入上述代码之后,再次运行,可以看到导航栏和状态栏的文字颜色已经更改
进入details页面
底部标签栏
当然,底部的标签栏也可以更改背景,在MainViewController.m的viewDidLoad方法中:- (void)viewDidLoad { [super viewDidLoad]; // 执行加载控制器 [self loadViewControllers]; //设置底部标签栏背景 [self.tabBar setBackgroundImage:[UIImage imageNamed:@"bg"]]; }
还可以自定义每个标签默认和选中的图片,拷入素材图片之后,
在MainViewControllers中,重新定义第一个标签栏Item:
// 自定义显示的图片 UIImage *homeNormal = [UIImage imageNamed:@"home_normal"]; UITabBarItem *firstTabBarItem = [[UITabBarItem alloc] initWithTitle:@"Main" image:homeNormal tag:0];
最终效果,如下图:
最后,附上代码下载地址:点击下载
相关文章推荐
- Speeding up Gradle builds
- 交互设计的用户行为模式十二项 【转载】
- UITableViewCell中的bug
- Please specify exact device preset UUID
- build and install everything into local directory
- 给GPUImage录制的视频添加水印
- Customizing Your Build With Gradle
- ViewPager强制刷新UI
- UISearchDisplayController 底部留白
- require文件失败的解决
- 动态获取UITextView 高度
- Java - String, StringBuffer and StringBuilder
- 两个UIViewController之间的翻转可以用动画效果翻转(上下,左右)--跨界面之间的视图切换
- HDU-4908-BestCoder Sequence【思维题】
- RESTEasy数据自动装配之@QueryParam
- ClassNotFound: edu.emory.mathcs.backport.java.util.concurrent.BlockingQueue
- UIScrollView 实践经验
- 解决VirtualBox分辨率太小及VBoxGuestAdditions_4.3.12.iso下载地址
- druid数据源例子
- Value Dispose() cannot be called while doing CreateHandle().