开头
自定义根控制器
- xcode生成的项目默认是加载
storyboard的,而我现在一般喜欢纯代码开发,所以要进行项目的初始设置
- 删掉
SceneDelegate.h/.m
AppDelegate.h 中添加@property (nonatomic, strong) UIWindow *window;
Info.plist删掉有Scene设置,删掉有Main的值
- 删掉
Main.storyboard
AppDelegate.m实现下面这个函数,可以理解为App的入口,app的一些初始化设置,都可以写在这个函数里
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]
//设置根控制器
ViewController *vc = [ViewController new]
self.window.rootViewController = vc
[self.window makeKeyAndVisible]
return YES
}
UINavigationController
实际用处
基础用法
UINavigationController实际上就是个盒子,设置了根控制器后,从这个根控制器跳转的都会从里到外,放在这个盒子里。
- 设置app的根控制器,并将
ViewController放入NavigationController中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]
ViewController *vc = [ViewController new]
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc]
self.window.rootViewController = nav
[self.window makeKeyAndVisible]
return YES
}
ViewController跳转到testViewController,testViewController也放在这个盒子里
- (void)btnClick {
testViewController *vc = [testViewController new]
[self.navigationController pushViewController:vc animated:YES]
}
//弹回上一个界面,如果是第一页无效
[self.navigationController popViewControllerAnimated:YES]
//弹到指定的界面,这个界面必须要在这个盒子中,而不能新建
ViewController *vc = self.navigationController.viewControllers[0]
[self.navigationController popToViewController:vc animated:YES]
UINavigationBar
UINavigationBar是添加UINavigationController后,状态栏显示的导航栏
- 主要由三部分组成,
leftBarButton、rightBarButton、title。在实际开发中最常用的地方,也是设置左上角与右上角的按钮,和中间的标题
基本按钮添加
self.navigationItem.title = @"首页";
UIBarButtonItem *right = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:@selector(cameraClick)];
UIBarButtonItem *left = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:@selector(playClick)];
self.navigationItem.rightBarButtonItem = right;
self.navigationItem.leftBarButtonItem = left;
UIBarButtonItem *helpItem = [[UIBarButtonItem alloc]initWithTitle:@"常见问题" style:UIBarButtonItemStylePlain target:self action:@selector(helpItemClick)];
self.navigationItem.rightBarButtonItem = helpItem;
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"NavBack"] style:UIBarButtonItemStylePlain target:self action:@selector(backClick)];
self.navigationItem.leftBarButtonItem = item;
如果左右同时添加一个UIBarButtonItem,则只显示右边
- 用
self.navigationItem.rightBarButtonItem = helpItem这类方式添加,只会显示最左或者最右的按钮
添加多个按钮
UIBarButtonItem *helpItem = [[UIBarButtonItem alloc]initWithTitle:@"常见问题" style:UIBarButtonItemStylePlain target:self action:@selector(helpItemClick)];
UIBarButtonItem *left1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addClick)];
UIBarButtonItem *left2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:@selector(playClick)];
UIBarButtonItem *left3 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash target:self action:@selector(trashClick)];
self.navigationItem.leftBarButtonItems = @[left1, left2, left3, helpItem];
自定义Button添加
- 自定义控件作为
UIBarButtonItem,这里针对的情况是,按钮图片大小很大,而且需要另外修改约束,特别注意UIImage的渲染模式的设置
UIImage *image = [UIImage imageNamed:@"dv_icon1"]
//原图渲染
image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
[btn setImage:image forState:UIControlStateNormal]
//修改约束
CGFloat width = 44 * image.size.width / image.size.height
[btn.widthAnchor constraintEqualToConstant:width].active = YES
[btn.heightAnchor constraintEqualToConstant:44].active = YES
[btn addTarget:self action:@selector(cameraClick) forControlEvents:UIControlEventTouchUpInside]
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:btn]
self.navigationItem.leftBarButtonItem = item
修改外观
UINavigationBar默认的渲染颜色是蓝色
AppDelegate中设置
[[UINavigationBar appearance] setTintColor:[UIColor yellowColor]];
[[UINavigationBar appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor], NSFontAttributeName : [UIFont systemFontOfSize:30]}];
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"NavBar64"] forBarMetrics:UIBarMetricsDefault];
- 自定义
UINavigationController 设置
[self.navigationBar setBackgroundImage:[UIImage imageNamed:@"NavBar64"] forBarMetrics:UIBarMetricsDefault];
[self.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor], NSFontAttributeName : [UIFont systemFontOfSize:30]}];
[self.navigationBar setTintColor:[UIColor blackColor]];
内部跳转
- 内部跳转指的是,经过
UINavigationController跳转后的界面,都会被保存在viewControllers的数组中
- 其中销毁过程,也是按照上面所讲从下往上放的顺序,从上往下销毁,如果中间有某个界面被销毁后,这个界面上的所有界面也会被销毁,销毁顺序为从下往上,例如,界面顺序从下往上依次为
红绿蓝,一旦从蓝直接跳到红,会先销毁绿,在销毁蓝
//拿到导航控制器栈中的所有控制器
NSArray *vcs = self.navigationController.viewControllers
UIViewController *vc = vcs[1]
[self.navigationController popToViewController:vc animated:YES]
设置状态栏的样式
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}
- (BOOL)prefersStatusBarHidden {
return YES;
}