iOS 【UIKit-导航控制器 UINavigationController】

来源:互联网 发布:天猫网络异常 编辑:程序博客网 时间:2024/04/28 21:56
一、基本介绍
两个比较特殊的控制器,专门用来管理控制器用的。他们是UINavigationController和UITabBarController。

导航控制器也是一个控制器,它也有自己的View(两个,分别是导航条栈顶控制器的view)。

导航控制器的标志导航条导航条的Y值是从20开始的,高度为44,它显示到导航控制器的view上面。

导航条的内部有一个子控件,它的Y值是从0开始的,这其实并不矛盾。它其实是导航条的一个子控件,它本身已经超过了导航条的高度。这说明了一点:子控件的尺寸超过了父控件的尺寸也是可以显示的


二、导航控制器的使用
① 创建
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    
    // 1、创建一个WZYOneViewController作为导航控制器的根控制器
    WZYOneViewController *oneVc = [[WZYOneViewController alloc] init];
    
    // 2、创建一个导航控制器(导航控制器必须要有一个根控制器,导航控制器的根控制器同时也是导航控制器的子控制器!!!)
//    UINavigationController *nav = [[UINavigationController alloc] init];
    // 3、将oneVc添加(push)到nav上,成为了nav的根控制器(通过push操作,导航控制器会把子控制器的view添加到自己专门存放子控制器的view上面)
//    [nav pushViewController:oneVc animated:YES];
    
    // 2,3步可以这样合并来写initWithRootViewController方法的内部会调用push方法,将当前的控制器添加为导航控制器的子控制器,并且他会将该控制器的view添加到导航控制器专门存放子控制器的view上面。
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:oneVc];
    
    // 4、设置窗口的根控制器为nav(把导航控制器设置为窗口的根控制器时,它会将导航控制器的view添加到窗口的view上面。所以程序运行时,我们看到的是一个导航控制器的view)
    self.window.rootViewController = nav;
    
    [self.window makeKeyAndVisible];
    
    return YES;
}

② 使用
- (IBAction)showChildsVC:(id)sender {
    // 所有添加到导航控制器的子控制器都存放在一个中,也就是数组之中(导航控制器的childViewControllers数组
    NSLog(@"childViewControllers-----%ld", self.navigationController.childViewControllers.count);
}

- (IBAction)pushThreeVC:(id)sender {
    // 用push将当前控制器添加到导航控制器中,实现跳转(该控制器threeVc被压到了栈顶,随之导航控制器的view就显示的是刚压入栈中的这个控制器的view。导航控制器会相应的把原来存放展示的子控制器的view移除。这里注意只是将上一个展示的控制器的view移除,但上一个展示的控制器并没有移除
    WZYThreeViewController *threeVc = [[WZYThreeViewController alloc] init];
    [self.navigationController pushViewController:threeVc animated:YES];
}

- (IBAction)popOneVC:(id)sender {
    // 可通过下标取出导航控制器的子控制器
    UIViewController *vc = self.navigationController.childViewControllers[0];
    [self.navigationController popToViewController:vc animated:YES];
}

- (IBAction)popTwoVC:(id)sender {
    // 返回上一级控制器(将当前控制器从导航控制器的子控制器中移除,也就是在栈中移除,当然导航控制器的view也会移除之前显示的子控制器的view。这种情况下移除的控制器会销毁,然后接着会把上一个添加到栈中的控制器view展示到导航控制器的view上显示
    [self.navigationController popViewControllerAnimated:YES];
}
★:这里的“导航控制器的view”指的就是“导航控制器中专门存放自控制器的view”,简写一下,理解就好

- (IBAction)popRootVC:(id)sender {
    // 返回根控制器(将除了导航控制器的根控制器以外的控制器全部移除,也就是第一个添加的控制器不被移除
    [self.navigationController popToRootViewControllerAnimated:YES];
}

使用方法总结:
使用push方法可以将某个控制器压入到栈中,使用pop方法可以移除控制器。


三、设置导航条的内容——栈顶控制器(NavigationItem)决定
导航控制器必须要有根控制器,目的设置导航条的内容。
- (instancetype)initWithTitle:(NSString *)title;
- (nullable instancetype)initWithCoder:(NSCoder *)coder;

@property(nullable, nonatomic,copy)   NSString        *title;            
@property(nullable, nonatomic,strong) UIView          *titleView;        

@property(nullable,nonatomic,copy)   NSString *prompt; // 多出来的一部分


@property(nullable,nonatomic,strong) UIBarButtonItem *backBarButtonItem;

@property(nonatomic,assign) BOOL hidesBackButton;
- (void)setHidesBackButton:(BOOL)hidesBackButton animated:(BOOL)animated;

@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem *> *leftBarButtonItems;
@property(nullable,nonatomic,copy) NSArray<UIBarButtonItem *> *rightBarButtonItems ;
- (void)setLeftBarButtonItems:(nullable NSArray<UIBarButtonItem *> *)items animated:
- (void)setRightBarButtonItems:(nullable NSArray<UIBarButtonItem *> *)items animated:

@property(nonatomic) BOOL leftItemsSupplementBackButton;

@property(nullable, nonatomic,strong) UIBarButtonItem *leftBarButtonItem;
@property(nullable, nonatomic,strong) UIBarButtonItem *rightBarButtonItem;
- (void)setLeftBarButtonItem:(nullable UIBarButtonItem *)item animated:(BOOL)animated;
- (void)setRightBarButtonItem:(nullable UIBarButtonItem *)item animated:(BOOL)animated;

几点注意:
①  UIBarButtonItemStyle iOS 7 之后设置什么都没有用了,它是一个枚举值,以后可以直接设置为0
typedef NS_ENUM(NSInteger, UIBarButtonItemStyle) {
    UIBarButtonItemStylePlain,
    UIBarButtonItemStyleBordered NS_ENUM_DEPRECATED_IOS(2_0, 8_0, "Use UIBarButtonItemStylePlain when minimum deployment target is iOS7 or later"),
    UIBarButtonItemStyleDone,
};

backBarButtonItem 和 leftBarButtonItem 的区别
backBarButtonItem和leftBarButtonItem描述的都是调航条左边的item,但不同的是设置在不同的控制器中起作用。如果作用同是点击返回至上一个控制器,那么leftBarButtonItem是设置在push的下一个控制器,在下个控制器点击时返回当前控制器。而backBarButtonItem是设置在当前控制器页面,在下个控制器点击时返回当前控制器。

例如:子控制器A push 子控制器B,在A中设置backBarButtonItem就等同于设置B的leftBarbuttonItem。都会达到B pop A的效果。

注意:如果两个同时设置。那么在当前控制器中设置的backBarButtonItem会被下个控制器中设置的leftBarButtonItem覆盖掉。


在设置item的时候,一定要设置尺寸!!!不管是自定义的尺寸还是自适应的尺寸。
1 0
原创粉丝点击