ChildViewController的应用
viewControlle中可以添加多个subView,在需要的时候显示出来;另一种方法是通过向parentViewController中可以添加多个childCiewController;来控制页面中的subView,降低代码耦合度;通过切换子视图控制器,可以显示不同的view;,替代之前的addSubView的管理。
本节通过类似百度新闻模块切换的界面来演示ChileViewController的应用:
文档结构:
代码演示:
#import "MainViewController.h" #import "FirstViewController.h" #import "SecondViewController.h" #import "ThirdViewController.h" @interface MainViewController () @property (nonatomic, strong) FirstViewController *firstVC; @property (nonatomic, strong) SecondViewController *secondVC; @property (nonatomic, strong) ThirdViewController *thirdVC; @property (nonatomic, strong) UIViewController *currentVC; @property (nonatomic, strong) UIScrollView *headScrollView; @property (nonatomic, strong) NSMutableArray *itemArray; @property (nonatomic, strong) UIView *contentView; @end @implementation MainViewController - (void)loadView{ [super loadView]; [self initialization]; } - (void)viewDidLoad { [super viewDidLoad]; [self loadBaseUI]; } - (void)initialization{ _itemArray = [NSMutableArray arrayWithObjects:@"头条",@"今日",@"焦点", nil]; } - (void)loadBaseUI{ self.title = @"首页"; _headScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44)]; _headScrollView.backgroundColor = [UIColor colorWithWhite:0.902 alpha:1.000]; for (int i = 0; i<_itemArray.count; i++) { UIButton *itemButton = [[UIButton alloc]initWithFrame:CGRectMake(i*([UIScreen mainScreen].bounds.size.width/_itemArray.count), 0, [UIScreen mainScreen].bounds.size.width/_itemArray.count, 44)]; itemButton.tag = 100+i; itemButton.backgroundColor = [UIColor clearColor]; NSDictionary *dic = @{NSForegroundColorAttributeName:[UIColor purpleColor],NSFontAttributeName:[UIFont systemFontOfSize:14.0f]}; [itemButton setAttributedTitle:[[NSAttributedString alloc]initWithString:_itemArray[i] attributes:dic] forState:UIControlStateNormal]; [itemButton addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside]; [_headScrollView addSubview:itemButton]; } [_headScrollView setContentSize:CGSizeMake([UIScreen mainScreen].bounds.size.width, 44)]; _headScrollView.showsHorizontalScrollIndicator = NO; _headScrollView.showsVerticalScrollIndicator = NO; [self.view addSubview:_headScrollView]; _contentView = [[UIView alloc]initWithFrame:CGRectMake(0, 44, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 44 - 64)]; _contentView.backgroundColor = [UIColor clearColor]; [self.view addSubview:_contentView]; [self addSubControllers]; } #pragma mark - privatemethods - (void)addSubControllers{ _firstVC = [[FirstViewController alloc]initWithNibName:@"FirstViewController" bundle:nil]; [self addChildViewController:_firstVC]; _secondVC = [[SecondViewController alloc]initWithNibName:@"SecondViewController" bundle:nil]; [self addChildViewController:_secondVC]; _thirdVC = [[ThirdViewController alloc]initWithNibName:@"ThirdViewController" bundle:nil]; [self addChildViewController:_thirdVC]; //调整子视图控制器的Frame已适应容器View [self fitFrameForChildViewController:_firstVC]; //设置默认显示在容器View的内容 [self.contentView addSubview:_firstVC.view]; NSLog(@"%@",NSStringFromCGRect(self.contentView.frame)); NSLog(@"%@",NSStringFromCGRect(_firstVC.view.frame)); _currentVC = _firstVC; } - (void)buttonClick:(UIButton *)sender{ if ((sender.tag == 100 && _currentVC == _firstVC) || (sender.tag == 101 && _currentVC == _secondVC) || (sender.tag == 102 && _currentVC == _thirdVC)) { return; } switch (sender.tag) { case 100:{ [self fitFrameForChildViewController:_firstVC]; [self transitionFromOldViewController:_currentVC toNewViewController:_firstVC]; } break; case 101:{ [self fitFrameForChildViewController:_secondVC]; [self transitionFromOldViewController:_currentVC toNewViewController:_secondVC]; } break; case 102:{ [self fitFrameForChildViewController:_thirdVC]; [self transitionFromOldViewController:_currentVC toNewViewController:_thirdVC]; } break; } } - (void)fitFrameForChildViewController:(UIViewController *)chileViewController{ CGRect frame = self.contentView.frame; frame.origin.y = 0; chileViewController.view.frame = frame; } //转换子视图控制器 - (void)transitionFromOldViewController:(UIViewController *)oldViewControllertoNewViewController:(UIViewController *)newViewController{ [self transitionFromViewController:oldViewController toViewController:newViewController duration:0.3 options:UIViewAnimationOptionTransitionCrossDissolve animations:nil completion:^(BOOL finished) { if (finished) { [newViewController didMoveToParentViewController:self]; _currentVC = newViewController; }else{ _currentVC = oldViewController; } }]; } //移除所有子视图控制器 - (void)removeAllChildViewControllers{ for (UIViewController *vc in self.childViewControllers) { [vc willMoveToParentViewController:nil]; [vc removeFromParentViewController]; } } /** * 方法说明: * 1、addChildViewController:向父VC中添加子VC,添加之后自动调用willMoveToParentViewController:父VC * 2、removeFromParentViewController:将子VC从父VC中移除,移除之后自动调用 didMoveToParentViewController:nil * 3、willMoveToParentViewController: 当向父VC添加子VC之后,该方法会自动调用。若要从父VC移除子VC,需要在移除之前调用该方法,传入参数nil。 * 4、didMoveToParentViewController: 当向父VC添加子VC之后,该方法不会被自动调用,需要显示调用告诉编译器已经完成添加(事实上不调用该方法也不会有问题,不太明白); 从父VC移除子VC之后,该方法会自动调用,传入的参数为nil,所以不需要显示调用。 */ /** * 注意点: 要想切换子视图控制器a/b,a/b必须均已添加到父视图控制器中,不然会报错 */ @end
最终效果:(实现了3个视图之间的切换)
时间: 2024-11-10 15:01:43