下面这幅图很好得将整个界面展示了出来,我们就从这幅图开始说起。
首先简单介绍一下UIWindow。
UIWindow是继承于UIView的,而在界面的呈现中,UIWindow相当于画框,而UIView相当于画布。一个画框上可以有多块画布,当然,画布里面也能有多块画布。
因此,UIWindow就是这样一个框架的存在。UIWindow还有一个需要注意的地方是,它有三种层级,Normal、StatusBar、Alert。
举个例子,如上图所示,Assembled views里面有两个UIWindow,一个是StatusBar(状态栏),其余剩下的部分为另一个UIWindow,前者的层级就是StatusBar,后者的层级是Normal。所以我们经常看到StatusBar一直都在最前面,就是这个原因。
当然,还有另一种情况,就是UIAlertView以及UIActionSheet,这两个View的层级是Alert,它们一出现就覆盖了另外两个层级的View。至于为什么这两个控件没有继承UIWindow,我也不是很清楚了。
还有一个关于UIWindow的概念是keyWindow,所谓的keyWindow简单得说就是能响应比如键盘弹出这类事件的window,就是当前window。
好了,了解了画框之后,我们就需要在上面填充一些东西。接下来我们就希望填充UINavigationController,因为这是一个container view controller,它可以嵌入其他ViewController的内容,这样就很方便我们进行管理一些界面的跳转。
这里顺带提一下UIViewController。为什么我们不直接将一些控件直接写在UIView、UIWindow这样的画布画框上呢。这是因为我们除了在View层将这些内容显示出来,我们还需要在他们之间进行一些逻辑交互,比如上面说到的界面之间的跳转。UIViewController就是做这类事情。这大概就是视图控制器和视图的区别吧。
从上图中我们了解到,UINavigationController包括一个必备的Navigation View以及一个可选的Tab bar view,以及主体部分Custom view hierarchy。在每次通过push或者pop进行压栈出栈时,Navigation View以及Tab bar view的内容发生改变,但本身view并没有改变,而Custom view hierarchy本身是发生了改变(一般是由一个UIViewController变成另一个UIViewController)。
下面是AppDelegate里面的一段代码。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// 根据屏幕大小初始化UIWindow
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// 自定义视图控制器
MainPageViewController *mainPageVC = [[MainPageViewController alloc] init];
// 初始化UINavigationController
UINavigationController *navigationController = [[UINavigationController alloc] init];
// 将自定义视图控制器push到导航堆栈顶部
[navigationController pushViewController:mainPageVC animated:YES];
// 将导航控制器添加到window的根视图控制器
self.window.rootViewController = navigationController;
// 让window变成keyWindow,并且显示
[self.window makeKeyAndVisible];
return YES;
}
接下来说下UINavigationBar,你可以自定义它的appearance-related properties,但不能修改frame,bounds, alpha。
修改导航栏以及状态栏的背景图片代码:
// 更改背景图片
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"test.png" forBarMetrics:UIBarMetricsDefault];
// 更改背景颜色
self.navigationController.navigationBar.barTintColor = [UIColor redColor];
// navigation bar 半透明效果
self.navigationController.navigationBar.translucent = YES;
[self.navigationController.navigationBar setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], NSForegroundColorAttributeName,[UIFont systemFontOfSize:[UIFont systemFontOfSize:14], NSFontAttributeName, nil]];
UIBarButtonItem *leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"title" style:UIBarButtonItemStylePlain target:self action:nil];
[leftBarButtonItem setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], NSForegroundColorAttributeName, [UIFont systemFontOfSize:14], NSFontAttributeName, nil] forState:UIControlStateNormal];
self.navigationItem.leftBarButtonItem = leftBarButtonItem;
文章只是谈一些自己的理解,不保证正确性,理性使用。