前面分析了应用启动时引导动画的展示过程,动画结束后根据会跳转到登录或者注册界面(LoginViewController/RegisterViewController,另外我发现在连续登陆失败3次之后会出现验证码的输入框,关于登录过程后续再进行分析),当用户登录完成之后会进入RootTabViewController视图,该控制器里面依次加载了五个RootViewController(项目、任务、冒泡、消息和Me,其中的Me指的是用户)。RootTabViewController继承自第三方库RDVTabBarController,这个库的用法类似于UITabBarController,可以通过底部的标签项来切换上面说到的五个RootViewController。
目录
按以下几部分展开:
介绍RootTabViewController
首先看到重写了- (id)initWithNibName: bundle: 方法(但是没有添加内容,只是调用了父类的该方法)。然后可以看到- (void)viewDidLoad调用了- (void)setupViewControllers方法,这个是我们关注的重点。
setupViewControllers方法添加了5个五个RootViewController,并且定制了屏幕底部的标签栏(设置标签项在不同状态下的图标和背景图片)。
- (void)setupViewControllers {
// 加载Project_RootViewController
Project_RootViewController *project = [[Project_RootViewController alloc] init];
... ...
/* 以Project_RootViewController为根视图控制器, 初始化一个导航控制器 */
UINavigationController *nav_project = [[BaseNavigationController alloc] initWithRootViewController:project];
// 加载MyTask_RootViewController 和 Tweet_RootViewController
MyTask_RootViewController *mytask = [[MyTask_RootViewController alloc] init];
UINavigationController *nav_mytask = [[BaseNavigationController alloc] initWithRootViewController:mytask];
RKSwipeBetweenViewControllers *nav_tweet = [RKSwipeBetweenViewControllers newSwipeBetweenViewControllers];
[nav_tweet.viewControllerArray addObjectsFromArray:@[[Tweet_RootViewController newTweetVCWithType:Tweet_RootViewControllerTypeAll],
[Tweet_RootViewController newTweetVCWithType:Tweet_RootViewControllerTypeFriend],
[Tweet_RootViewController newTweetVCWithType:Tweet_RootViewControllerTypeHot]]];
nav_tweet.buttonText = @[@"冒泡广场", @"朋友圈", @"热门冒泡"];
// 加载Message_RootViewController
Message_RootViewController *message = [[Message_RootViewController alloc] init];
... ...
UINavigationController *nav_message = [[BaseNavigationController alloc] initWithRootViewController:message];
// 加载Message_RootViewController
Me_RootViewController *me = [[Me_RootViewController alloc] init];
me.isRoot = YES;
UINavigationController *nav_me = [[BaseNavigationController alloc] initWithRootViewController:me];
/* 将需要被管理的多个UIViewController组合成NSArray对象, 将这个NSArray对象设置成 RDVTabBarController的viewController属性, 这样就可以通过RDVTabBarController来切换显示多个UIViewController */
[self setViewControllers:@[nav_project, nav_mytask, nav_tweet, nav_message, nav_me]];
[self customizeTabBarForController];
self.delegate = self;
}
另外,可以注意到该方法(setupViewControllers)中用到了ReactiveCocoa 框架(基于响应式编程思想),关于这个框架的使用介绍,我找了几篇写的比较详细的文章:《ReactiveCocoa入门教程》 和 《ReactiveCocoa框架菜鸟入门》 ,可以参考一下。
/* RACObserve(TARGET, KEYPATH) 观察TARGET的KEYPATH属性,相当于KVO,产生一个RACSignal */
/* 使用combineLatest:reduce:方法 产生聚合信号(此处只有一个信号), 当该聚合信号产生一个新值时,reduce: block 会执行, block的返回值会赋值给project对象的badgeValue属性 */
RAC(project, rdv_tabBarItem.badgeValue) = [RACSignal combineLatest:@[RACObserve([UnReadManager shareManager], project_update_count)]
reduce:^id(NSNumber *project_update_count){
return project_update_count.integerValue > 0? kBadgeTipStr : @"";
}];
关于定制屏幕底部标签栏的方法的使用可以参考RDVTabBarController库的github说明,在本应用中的使用情况分析如下:
- (void)customizeTabBarForController {
//定制标签条(设置标签项在不同状态下的背景图片和图标)
UIImage *backgroundImage = [UIImage imageNamed:@"tabbar_background"];
NSArray *tabBarItemImages = @[@"project", @"task", @"tweet", @"privatemessage", @"me"];
NSArray *tabBarItemTitles = @[@"项目", @"任务", @"冒泡", @"消息", @"我"];
NSInteger index = 0;
for (RDVTabBarItem *item in [[self tabBar] items]) {
item.titlePositionAdjustment = UIOffsetMake(0, 3);
/* 设置标签项在选中和未选中状态下分别对应的背景图片 */
[item setBackgroundSelectedImage:backgroundImage withUnselectedImage:backgroundImage];
/* 设置标签项在选中和未选中状态下分别对应的图标 */
/* 以index=1为例, 查找名为 project_selected 的图片(其中的 "%@" 表示NSArray返回指定index的对象) */
/* 图片 project_selected 位于 "image/tabbar/" 目录下 */
UIImage *selectedimage = [UIImage imageNamed:[NSString stringWithFormat:@"%@_selected",
[tabBarItemImages objectAtIndex:index]]];
UIImage *unselectedimage = [UIImage imageNamed:[NSString stringWithFormat:@"%@_normal",
[tabBarItemImages objectAtIndex:index]]];
[item setFinishedSelectedImage:selectedimage withFinishedUnselectedImage:unselectedimage];
[item setTitle:[tabBarItemTitles objectAtIndex:index]];
index++;
}
}
RootTabViewController的根视图为Project_RootViewController,因此默认显示的是项目视图,可以通过底部的5个标签栏来进行切换。
对于顶部的搜索栏、”+”号按钮,则是在Project_RootViewController中定义的,关于项目根视图控制器的理解后面在进行分析。