UINavigationController与UITabBarController

来源:互联网 发布:js中跳转页面 编辑:程序博客网 时间:2024/05/18 21:41

UINavigationController:

什么?这玩意竟然继承自UIViewController?看上去不要太像唉!

废话少说,让我们看看这玩意是什么组成的吧!----------


不追求细节的前提下:

从官方文档我们可以得到,整个NavigationController分成了三个部分:

1:最上面的UINavigationBar。

导航栏:UINavigationBar继承自UIView

2:中间的NavigationView。

这里倒是和ViewController一样,也是一个View。

使用navigation.view可以访问

UILayoutContainerView,在这个容器中添加的内容会盖在导航上面(toolbar上面),状态栏下面。原点与状态栏原点一致。

3:下边的NavigationToolBar。

UIToolBar同样继承自UIView。

============

初始化:

initWithRootViewController

还记得前面讲过的UIViewController中怎么实现childViewController之间的切换的么?也需要先将某一个子ViewController 的View添加到某个可以显示的容器中,然后才能利用这个View实现子类Controller中View内容的切换。

这里的根ViewController也与之类似。根视图控制器会作为默认显示的ViewController,而不同ViewController之间的切换似乎也和前面提到过的只是对View进行变换吻合,因为在切换中,你的导航和ToolBar似乎并没有随着View的移动而移动。


成员数组:

@property(nonatomic,copy)NSArray *viewControllers;// The current view controller stack.

其实,NavigationController以Stack的形式来管理这个数组,并且NavigationControoler的View与这个栈的栈顶元素相关联,也就是说,只要改变了这个数组的内容,NavigationController的View就会改变。

甚至可以使用SetViewControlelrs方法一次性设置整个流程,并将流程确定在栈顶ViewController的状态。


关于代理,虽然很少用到:

UINavigationControllerDelegate

UINavigationController也是提供了代理的,用于监听当前NavigationConroller显示的是哪个ViewController。

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;


关于UINavigationItem:

@property(nonatomic,readonly,retain)UINavigationItem *navigationItem;// Created on-demand so that a view controller may customize its navigation appearance.



UITabBarController:

根据UINavigationController 的经验,这个东东应该也是继承自UIviewController的。(从名字就可以看出来好么,大神)


国际惯例:看看它的结构。

貌似比UINavigationController简单一丢丢。

分为两部分:

1:上面的是所谓的Custom content。

亮瞎狗眼的细节你注意到了没?这个content里面竟然包含状态栏,而你去看看上面的UINavigationController,它是不包含状态栏的,事实上,TabBarController所处的层次结构肯定不可能高与状态栏,因为任何UIView都不可能盖在状态栏之上。但是,TabBarcontroller的层次结构还是非常高了,所以,一般都是用TabBarController来管理不同的NavigationController,而使用NavigationController来管理不同的ViewControlelr,再用ViewController来管理UIview,形成这样的一个层级结构。

使用tab.view可以访问

UILayoutContainerView层,如果添加一个uiview到这个层中,那么这个uiview在所有的子ViewController中均可见(并且还能盖在tabBar上面),并且Frame的起点是与状态栏一致的起点。


如果需要恶补更多关于UIview层次的知识,访问:

http://blog.csdn.net/hamasn/article/details/8216584

2:下面的TabBar。

有三个方法与之有关:

@property(nonatomic,assign)UIViewController *selectedViewController;// This may return the "More" navigation controller if it exists.

返回“More”这个NavigationConntroller。

@property(nonatomic)NSUInteger selectedIndex;

当前选择的是ViewController的下标。

@property(nonatomic,readonly)UINavigationController *moreNavigationController;// Returns the "More" navigation controller, creating it if it does not already exist.

返回“More”这个NavigationConntroller,如果不存在就会创建并返回一个。


关于代理:

UITabBarControllerDelegate

方法均是在视图切换时刻触发的事件监听,不赘述。

---------------------------------------------------------------------------------------

ViewController在其他UI视图中的拓展:

由于IOS的特有语法,一个类是可以分成很多部分定义在不同的类中的。我们上面提到的两个Controller中就存在对UIviewController的拓展定义:

其中:UINavigationController中对ViewController的拓展是

@interface UIViewController (UINavigationControllerItem)

@property(nonatomic,readonly,retain)UINavigationItem *navigationItem;// Created on-demand so that a view controller may customize its navigation appearance.


正是因为这样,我们在ViewController中才能通过self.navigationItem修改所属的UINavigationController的属性


@property(nonatomic)BOOL hidesBottomBarWhenPushed;// If YES, then when this view controller is pushed into a controller hierarchy with a bottom bar (like a tab bar), the bottom bar will slide out. Default is NO.


当这个ViewController被显示的时刻,将下面的TabBar隐藏,至于为什么要将与TabBarController有关的拓展写在这里面,我只想说,你他么有病么!


@property(nonatomic,readonly,retain)UINavigationController *navigationController;// If this view controller has been pushed onto a navigation controller, return it.


返回所属的UINavigationController对象。


@end


@interface UIViewController (UINavigationControllerContextualToolbarItems)

@property (nonatomic,retain) NSArray *toolbarItemsNS_AVAILABLE_IOS(3_0);

- (void)setToolbarItems:(NSArray *)toolbarItems animated:(BOOL)animatedNS_AVAILABLE_IOS(3_0);

通过这个方法自定义ToolBar

@end



UITabBarController中也有拓展:


@interface UIViewController (UITabBarControllerItem)

@property(nonatomic,retain)UITabBarItem *tabBarItem;// Automatically created lazily with the view controller's title if it's not set explicitly.

同理,通过这个对象,对所属的UITabBarController进行管理。例如,修改这个viewController在父tabBarController中显示的文字和图片。可以通过自定一个UITabBarItem对象然后赋值给它,来自定义显示自身在tabBarController中的显示。


@property(nonatomic,readonly,retain)UITabBarController *tabBarController;// If the view controller has a tab bar controller as its ancestor, return it. Returns nil otherwise.

为什么在ViewController中使用self.tabBarController得不到所属的tabBarController对象,因为这里说是只有当前ViewController继承自TabBarController,才能返回一个UITabBarController对象。setFinishedSelectedImage:withFinishedUnselectedImage:这个方法可以设置选中和非选中状态下的图片。构造方法中就可以设置文字。

@end


=====高级篇======

UINavigationController样式自定义:

1:UINavigationBar样式定制:

关于UINavigationBar其上面的所有内容都是通过navigationItem来管理的。(也就是在ViewController中通过self.navigationItem来管理)

但是如果要设置UInavigationBar本身的属性,就只能通过self.navigationController.navigationBar来设置,如导航栏的背景图片,背景颜色和设置为半透明等。

除了第一个ViewController以外,在其它被push的ViewController的NavigationBar左侧都会存在一个返回按钮。这个按钮可以通过

self.navigationItem.hidesBackButton=YES;隐藏。


UIbarButtonItem的定制:

提供了自定义的方法:

[UIBarButtonItem alloc]initWithCustomView:(UIView *)


而导航栏中间titleView也是可以定制的,只需要自定义一个UIView再赋值给它就行。


注意:下面的都是涉及到导航栏本身的属性操作,所以都是通过self.navigationController来管理

 [self.navigationControllersetNavigationBarHidden:YES]; 

隐藏导航栏

[self.navigationController.navigationBarsetBarStyle:UIBarStyleBlackTranslucent];

设置导航栏半透明。


2:UIToolBar定制:

与导航一致,对于ToolBar本身,也是通过self.navigationController来管理。

而其上面的内容,则通过self.toolbarItems来进行自定义。

不赘述。


UITabBarController自定义:

只需要定制UITabBar:

而分栏控制器特有一种button类型UITabBarItem,UIBarButtonItem是导航控制器的特有类型。


UITabBarItem定制:

UITabBarItem不能够像上面的导航控制器的UIBarButtonItem一样使用自定义的UIView来定义它。只能够使用系统的类型或者

使用字符串加图片(图片有特殊要求)来初始化它。


角标显示:

在viewController中使用self.tabBarItem.badgeValue=@"99";


原创粉丝点击