IOS初级:导航控制器

时间:2021-11-30 20:40:33


1、AppDelegate.m老生常谈了,创建window,创建根视图rootViewController


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    RootViewController *rootVC = [[RootViewController alloc] init];
    //权限最高的给根视图控制器
    self.window.rootViewController = rootVC;
    
    return YES;
}

2、在根视图中弄一个三级导航样式出来


RootViewController.h

@interface RootViewController : UITabBarController//我们的根视图RootViewController继承自UITabBarController
@property (nonatomic, strong) UIView *tabBarView;//声明自定义的tabBar,包括下面的方法show写在这里是为了方便其他viewContoller控制
- (void)showTabBar:(BOOL)show;//控制是否显示tabBar,tabBar其实就是屏幕下方的那个标签导航
@end

RootViewController.m

#define kScreenWidth [UIScreen mainScreen].bounds.size.width     //宏定义屏幕宽度
#define kScreenHeight [UIScreen mainScreen].bounds.size.height   //宏定义屏幕高度
CGFloat const tabViewHeight = 49; 
CGFloat const btnWidth = 64;
CGFloat const btnHeight = 45;
@interface RootViewController ()
@property (nonatomic, strong) UIImageView *selectView; //在tabBar上的选中效果
@end

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tabBar.hidden = YES;//隐藏系统默认的样式
    [self initViewController];
    [self initTabBarView];
    
}
//初始化视图控制器,这里就是把根控制器要控制的视图统统加进来
- (void)initViewController{
    //初始化视图控制器
    ProfielViewController *profielVC = [[ProfielViewController alloc] init];
    MessageViewController *messageVC = [[MessageViewController alloc] init];
    ColaViewController *colaVC = [[ColaViewController alloc] init];
    UserViewController *userVC = [[UserViewController alloc] init];
    MoreViewController *moreVC = [[MoreViewController alloc] init];
    NSArray *vcArray = @[profielVC,messageVC,colaVC,userVC,moreVC];
    NSMutableArray *tabArray = [NSMutableArray arrayWithCapacity:vcArray.count];//初始化可变数组,虽然指定了长度,但他仍然是可变的
    //初始化导航控制器
    for (int i = 0; i < vcArray.count; i++) {
        UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:vcArray[i]];//创建若干个导航控制器,导航控制器里是刚创建的的profielVC等视图
        [tabArray addObject:navCtrl];//加入到数组中
    }
    //将导航控制器给标签控制器
    self.viewControllers = tabArray;//将根控制器的所控制的视图加进来
}
//自定义底部的标签工具栏
- (void)initTabBarView{
    //初始化标签工具栏视图
    _tabBarView = [[UIView alloc] initWithFrame:CGRectMake(0, kScreenHeight - tabViewHeight, kScreenWidth, tabViewHeight)];//下划线的功能是让编译器自动生成getter方法,并指定frame
    _tabBarView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"mask_navbar"]];
    [self.view addSubview:_tabBarView];//显示tabBarView
    //新语法创建数组,拿到图片
    NSArray *imgArray = @[@"home_tab_icon_1",@"home_tab_icon_2",@"home_tab_icon_3",@"home_tab_icon_4",@"home_tab_icon_5"];
    for (int i = 0; i < imgArray.count; i++) {
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        [btn setBackgroundImage:[UIImage imageNamed:imgArray[i]] forState:UIControlStateNormal];
        btn.frame = CGRectMake(btnWidth * i, (tabViewHeight - btnHeight)/2, btnWidth, btnHeight);
        btn.tag = 100 + i;//下面的TouchUpInside事件需要btn指定要切换到哪个视图,这里的tag作为传值的作用。100以下的tag值IOS占用了,所以要设置100以上的值
        [btn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];//点击底部标签,改变标签上按钮的样式,这里有些不明白为什么它会自动能找到对应的视图。
        [self.tabBarView addSubview:btn];
    }
    //初始化选中图片视图
    _selectView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, btnWidth, btnHeight)];
    _selectView.image = [UIImage imageNamed:@"home_bottom_tab_arrow"];
    [_tabBarView addSubview:_selectView];
}
#pragma mark - UIButtonAction
- (void)btnAction:(UIButton *)button{
    //根据tag值判断当前索引
    self.selectedIndex = button.tag - 100;
    [UIView animateWithDuration:0.2 animations:^{
        _selectView.center = button.center;//选中视图中,tabBar的箭头滑动效果
    } completion:nil];
}
//是否显示工具栏
- (void)showTabBar:(BOOL)show{
    CGRect frame = self.tabBarView.frame;
    if (show) {
        frame.origin.x = 0;
    }else{
        frame.origin.x = - kScreenWidth;
    }
    //重新赋值frame
    [UIView animateWithDuration:0.2 animations:^{
        self.tabBarView.frame = frame;
    } completion:nil];
}

3、我们个性化一下顶部的导航栏

CGFloat const writeButtonWidth = 33;
CGFloat const writeButtonHeight = 32;
@interface ProfielViewController ()

@end

@implementation ProfielViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.title = @"首页";
    self.view.backgroundColor = [UIColor yellowColor];
    [self initNavButton];
    [self initPushButton];
}
//自定义顶部导航栏按钮
- (void)initNavButton{
    UIButton *writeBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    writeBtn.frame = CGRectMake(0, 0, writeButtonWidth, writeButtonHeight);
    [writeBtn setBackgroundImage:[UIImage imageNamed:@"write"] forState:UIControlStateNormal];
    [writeBtn addTarget:self action:@selector(presentAction) forControlEvents:UIControlEventTouchUpInside];//弹出一个model类型的view
    //添加自定义按钮
    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:writeBtn];//UIBarButtonItem不能随意摆放在屏幕上,它不是继承自UIView。它可以放在导航栏,标签栏或工具栏管理
    self.navigationItem.rightBarButtonItem = item;//放到导航栏上
}
//初始化push按钮
- (void)initPushButton{
    UIButton *pushButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    pushButton.frame = CGRectMake(100, 100, 200, 40);
    //[pushButton setImage:<#(UIImage *)#> forState:<#(UIControlState)#>]
    //标题和图片不能同时设置
    [pushButton setTitle:@"Push" forState:UIControlStateNormal];
    [pushButton addTarget:self action:@selector(pushAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:pushButton];
}
- (void)pushAction{
    PushViewController *pushVC = [[PushViewController alloc] init];
    [self.navigationController pushViewController:pushVC animated:YES];
    RootViewController *rootVC = (RootViewController *)self.tabBarController;
    [rootVC showTabBar:NO];//不显示底部标签导航栏
    //[self.navigationController showViewController:<#(UIViewController *)#> sender:<#(id)#>]
}
- (void)presentAction{
    ModalViewController *modalVC = [[ModalViewController alloc] init];
    //模态视图
    [self presentViewController:modalVC animated:YES completion:nil];
}
//视图将要出现的时候调用
//这里用于push的view返回,要重新显示底部标签导航栏
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    RootViewController *rootVC = (RootViewController *)self.tabBarController;
    [rootVC showTabBar:YES];
}