揣摩一下UITabbarViewController 内部机制

最近想要自定义一个tabbarController,本篇文章是为了解下原生的工作原理,参考来源为Developer Documtation和控制台调试。所以下面的思路含有推测部分,只能表示笔者的思路。如有错误,请指正。如能告知在哪了解原生控件工作原理,万分感激!!!

1. 使用

  • 指定管理的子控制器viewControllers,同时可以通过selectedViewControllerselectedIndex指定默认选中的控制器
  • 对于tabbar上的标签控制则通过子控制器的tabbarItem实现。tabBarController上的tabBar属性(只读)不能直接修改。
  • 通过UITabBarControllerDelegate协议控制或添加交互行为。该协议可选。

注意:tabbar最多能显示5个item,超过会将第5个item变为More。点击More再选择其他。

2. 思路

tabbarController继承于UIViewController,子控制器视图和tabbar都是添加到该UIViewControllerview上。切换时将原来的子控制器视图移除,将新的视图添加。

对于More项,猜测:检测到控制器数大于5时,新建一个数组存储前4项控制器和moreNaviController多出的控制器则赋值给moreNaviControllerviewControllers

创建moreNaviController同时会创建一个UIMoreListController用于列出多出的控制器。但是控制台调试时,点击More时,moreNaviControllerviewControllers只包含列表控制器。当选择多出的控制器时,viewControllers也只包含了列表控制器和选中的控制器。

也即是在多出的控制器间切换时,更新的是viewControllers属性,而不是push pop。我的猜想:由于导航控制器时以栈的形式管理的,如果一次性将控制器加到viewControllers。当根控制器UIMoreListController依次push了5,6,7,此时要从7回到5,会有多余的入栈出栈行为。

而通过直接更新viewControllers,也就是直接替换了导航栈,能可直接刷新视图到viewControllers的最后一个控制器的视图。

所以moreNaviControllerviewControllers是 ?动态? 调整的。

3. 属性

属性 作用
tabBar 只读属性,仅为用于-[UIActionSheet showFromTabBar:]方法
viewControllers 子控制器
customizableViewControllers 当出现More时,可以对各控制器顺序重新布置,该属性指定哪些控制器能被重新布置,其他的则不能
moreNavigationController More标签,只读属性。通过该属性可以拿到多出的子控制器
selectedViewController 当前选中的控制器,可以修改替换成其他的,包括More
selectedIndex 选中的控制器的索引,从左至右从0开始,值和viewControllers的索引相同,修改该属性也可以切换。但是不能选中More

4. 协议UITabBarControllerDelegate

  • 指定选中的控制器
  • 选中后执行方法
// 是否切换到用户选中的viewController
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController;
// 切换后
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController;
  • 自定义控制器顺序前(后)要做的事
// 自定排序窗口显示前
- (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers;
// 排序窗口退出前
- (void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed;
// 结束排序后(tvOS不可用)
- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed;
  • tabbar横竖屏支持
- (UIInterfaceOrientationMask)tabBarControllerSupportedInterfaceOrientations:(UITabBarController *)tabBarController;
- (UIInterfaceOrientation)tabBarControllerPreferredInterfaceOrientationForPresentation:(UITabBarController *)tabBarController;
  • 动画
- (nullable id )tabBarController:(UITabBarController *)tabBarController
                      interactionControllerForAnimationController: (id )animationController;
// contentController的切换动画
- (nullable id )tabBarController:(UITabBarController *)tabBarController
            animationControllerForTransitionFromViewController:(UIViewController *)fromVC
                                              toViewController:(UIViewController *)toVC  NS_AVAILABLE_IOS(7_0);

你可能感兴趣的:(揣摩一下UITabbarViewController 内部机制)