• iOS开发--ChildViewController实现订单页的切换


      先不说废话, 上效果图, 代码量也不大, 也不上传github骗星星了, 你们复制粘贴下代码, 就可以轻而易举的弄出一个小demo.

      

      这个代码的实现并不复杂, 甚至于说非常简单, 就是逻辑有点小绕, 下面将用代码详细讲解下.

      childViewController方便在一个vc上面呈现出这种多种vc的效果, 相信好处百度上面说的多了去了, 这里只说实现.

      首先, 需要新建一个父vc和五个子vc, 这里就不多说了, 先给大家看看进入父vc后的上面的btn控件封装, 以及方法回调.

      IndentButtonView.h中代码

    1 #import "RootClassView.h"
    2 
    3 typedef void(^buttonBlock)(NSInteger);
    4 
    5 @interface IndentButtonView : RootClassView
    6 
    7 @property(nonatomic, copy)buttonBlock block;
    8 
    9 @end

      这里声明了一个具有整形参数的block闭包属性, 用于捕获button的tag值来作为参数回调.

      IndentButtonView.m中代码, 有我自己定义的宏和基类, 你们按照你们自己的习惯来写就好.

     1 #import "IndentButtonView.h"
     2 #import "ALLHeaderFile.pch"
     3 @implementation IndentButtonView
     4 
     5 - (instancetype)initWithFrame:(CGRect)frame{
     6     self = [super initWithFrame:frame];
     7     if (self) {
     8         [self createButton];
     9     }
    10     return self;
    11 }
    12 
    13 - (void)createButton{
    14     NSArray *nameArray = @[@"全部", @"待付款", @"待收货", @"待评价", @"退换货"];
    15     for (NSInteger i = 0; i < 5; i++) {
    16         UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    17         button.frame = CGRectMake(150 / 2 * i, 0, 150 / 2, self.H);
    18         [button setTitle:nameArray[i] forState:UIControlStateNormal];
    19         button.tag = 2006 + i;
    20         [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
    21         button.backgroundColor = [UIColor grayColor];
    22         button.titleLabel.textColor = [UIColor redColor];
    23         button.titleLabel.font = [UIFont systemFontOfSize:15];
    24         [self addSubview:button];
    25     }
    26 }
    27 
    28 - (void)buttonAction:(UIButton *)button{
    29     NSLog(@"第%ld个按钮被点击了", button.tag -2006);
    30     _block(button.tag - 2006);
    31 }
    32 @end

      当点击button的时候, 触发闭包传值回调. 通过button的tag值判断, 在闭包实现的地方也会有不同的结果. 这样一个button按钮条的封装就完成了.

      然后是外部的一个自定义cell, 我选择了用四个imageView作为订单四个状态的按钮. 这个自定义cell同样声明了一个闭包属性, 作为以后的回调, 传递的也是imageView的tag值作为参数.

      .h

    #import "RootClassTableViewCell.h"
    #import "RootClassImageView.h"
    typedef void(^indentBlock)(NSInteger);
    @interface IndentTableViewCell : RootClassTableViewCell
    @property(nonatomic, copy)indentBlock block;
    @end

      .m中代码

      

     1 #import "IndentTableViewCell.h"
     2 #import "XCLHeader.h"
     3 #import "RootClassLabel.h"
     4 @implementation IndentTableViewCell
     5 
     6 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
     7 {
     8     self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
     9     if (self) {
    10         [self createCell];
    11     }
    12     return self;
    13 }
    14 
    15 - (void)createCell
    16 {
    17     //订单Label
    18     RootClassLabel *indentLabel = [[RootClassLabel alloc]initWithFrame:CGRectMake(48, 18, 30, 15)];
    19     indentLabel.text = @"订单";
    20     indentLabel.font = [UIFont systemFontOfSize:15];
    21     [self.contentView addSubview:indentLabel];
    22     
    23     //查看全部订单
    24     RootClassLabel *checkIndentLabel = [[RootClassLabel alloc]initWithFrame:CGRectMake(SCREEN_WIDTH - (168 + 10 + 14 + 40) / 2, 38 / 2, 168 / 2, 28 / 2)];
    25     checkIndentLabel.text = @"查看全部订单";
    26     checkIndentLabel.font = [UIFont systemFontOfSize:14];
    27     [self.contentView addSubview:checkIndentLabel];
    28     
    29     RootClassImageView *imageView = [[RootClassImageView alloc]initWithFrame:CGRectMake(checkIndentLabel.X + checkIndentLabel.W + 5, checkIndentLabel.Y, 7, 14)];
    30     [self.contentView addSubview:imageView];
    31     
    32     /**循环实例化imageView对象
    33      *
    34      *待付款
    35      *
    36      *待收货
    37      *
    38      *待评价
    39      *
    40      *退换货
    41      *
    42      */
    43     
    44     for (NSInteger i = 0; i < 4; i++) {
    45         RootClassImageView *imageView = [[RootClassImageView alloc]initWithFrame:CGRectMake(41 + 167 / 2 * i, 117 / 2, 85 / 2, 85 / 2)];
    46         //imageView增加tag值
    47         imageView.tag = 2002 + i;
    48         
    49         //打开imageView交互
    50         imageView.userInteractionEnabled = YES;
    51         
    52         //为imageView添加轻拍手势
    53         UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
    54         [imageView addGestureRecognizer:tap];
    55         imageView.t;
    56         [self.contentView addSubview:imageView];
    57     }
    58 }
    59 
    60 
    61 - (void)tapAction:(UITapGestureRecognizer *)tap
    62 {
    63     _block(tap.view.tag - 2002);
    64 }
    65 
    66 - (void)layoutSubviews
    67 {
    68     [super layoutSubviews];
    69 }

      自定义cell在重用池协议中代码, 对闭包进行了实现, 同时传递值给要跳转的vc.

     1         //订单
     2         static NSString *indentifier = @"indent";
     3         IndentTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:indentifier];
     4         if (!cell) {
     5             cell = [[IndentTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:indentifier];
     6             cell.selectionStyle = 0;
     7         }
     8         cell.block = ^(NSInteger index){
     9             //index就是通过block传递过来imageView的tag值.
    10             MyIndentViewController *myIndentViewController = [MyIndentViewController new];
    11             //当点击imageView后, 将图片的tag值传递给vc, vc通过这个值来布局, 以实现点击不同的imageView, 使页面中呈现不同的子视图.
    12             myIndentViewController.index = index + 1;
    13             [self.navigationController pushViewController: myIndentViewController animated:1];
    14         };
    15         return cell;

      可能上面传tag值让大家很迷茫, 现在把最重要的实现部分的VC代码拿出来, 大家就好懂了.

      .h

      

    1 #import "ViewController.h"
    2 
    3 @interface MyIndentViewController : ViewController
    4 
    5 @property(nonatomic, assign)NSInteger index;
    6 
    7 @end

      .m

      1 //我的订单页
      2 
      3 #import "MyIndentViewController.h"
      4 #import "ALLHeaderFile.pch"
      5 @interface MyIndentViewController ()
      6 @property(nonatomic, strong)IndentButtonView *buttonView;
      7 //子视图
      8 @property(nonatomic, strong)AllIndentViewController *allIndentViewController;
      9 @property(nonatomic, strong)ObligationViewController *obligationViewController;
     10 @property(nonatomic, strong)WaitingReceiveViewController *waitingReceiveViewController;
     11 @property(nonatomic, strong)WaitingEvaluateViewController *waitingEvaluateViewController;
     12 @property(nonatomic, strong)ExchangeViewController *exchangeViewController;
     13 
     14 //当前视图
     15 @property(nonatomic, strong)RootClassViewController *currentViewController;
     16 
     17 //视图控制器数组
     18 @property(nonatomic, strong)NSMutableArray *viewControllerArray;
     19 
     20 
     21 @end
     22 
     23 @implementation MyIndentViewController
     24 
     25 
     26 - (void)loadView {
     27     [super loadView];
     28     //实例化buttonView
     29     _buttonView = [[IndentButtonView alloc]initWithFrame:CGRectMake(0, 69, SCREEN_WIDTH, 30)];
     30     [self.view addSubview:_buttonView];
     31     
     32     //添加视图方法
     33     [self addViewController];
     34     
     35 }
     36 
     37 
     38 - (void)viewDidLoad {
     39     [super viewDidLoad];
     40     // Do any additional setup after loading the view.
     41     
     42     //实现buttonView的block
     43     __weak typeof (self) WeakSelf = self;
     44     _buttonView.block = ^(NSInteger sign){
     45         [WeakSelf changeChildViewController:sign];
     46     };
     47 }
     48 
     49 - (void)changeChildViewController:(NSInteger)sign {
     50     //通过block传递过来的tag值判断切换视图
     51     //如果点击的button在当前页, 则废弃点击操作
     52     if ((_currentViewController == _allIndentViewController && sign == 0) ||
     53         (_currentViewController == _obligationViewController && sign == 1) ||
     54         (_currentViewController == _waitingReceiveViewController && sign == 2) ||
     55         (_currentViewController == _waitingEvaluateViewController && sign == 3) ||
     56         (_currentViewController == _exchangeViewController && sign == 4)
     57         ) {
     58         return;
     59     }
     60     else{
     61         [self replaceOldViewCroller:_currentViewController newViewController:_viewControllerArray[sign]];
     62     }
     63 }
     64 
     65 - (void)addViewController {
     66     //视图控制器数组
     67     _viewControllerArray = [NSMutableArray array];
     68     
     69     //设置子视图的尺寸
     70     CGRect rect = CGRectMake(0, 109, SCREEN_HEIGHT, SCREEN_HEIGHT - 109);
     71     
     72     //实例化子视图的vc
     73     _allIndentViewController = [AllIndentViewController new];
     74     _obligationViewController = [ObligationViewController new];
     75     _waitingReceiveViewController = [WaitingReceiveViewController new];
     76     _waitingEvaluateViewController = [WaitingEvaluateViewController new];
     77     _exchangeViewController = [ExchangeViewController new];
     78     
     79     //将子视图的vc添加到一个可变数组中, 方便处理
     80     [_viewControllerArray addObject:_allIndentViewController];
     81     [_viewControllerArray addObject:_obligationViewController];
     82     [_viewControllerArray addObject:_waitingReceiveViewController];
     83     [_viewControllerArray addObject:_waitingEvaluateViewController];
     84     [_viewControllerArray addObject:_exchangeViewController];
     85     
     86     //偷懒
     87     for (NSInteger i = 0; i < 5; i++) {
     88         [_viewControllerArray[i] view].frame = rect;
     89     }
     90     
     91     //这块是实现能够在外面点击不同的imageView进入不同页面的关键, 通过属性传值确定视图的内部布局
     92     [self.view addSubview:[_viewControllerArray[_index] view]];
     93     
     94     //将当前子视图设置为传值确定的子视图
     95     _currentViewController = _viewControllerArray[_index];
     96     
     97     //将子视图添加到父视图上
     98     [self addChildViewController:_viewControllerArray[_index]];
     99 
    100     
    101 }
    102 
    103 #pragma mark 切换子视图方法
    104 
    105 - (void)replaceOldViewCroller:(RootClassViewController *)oldViewController newViewController:(RootClassViewController *)newViewController{
    106     
    107     //将新的子视图先添加到父视图上
    108     [self addChildViewController:newViewController];
    109     
    110     //这个方法是负责对子视图进行切换的, 有几个参数, 前两个参数是切换前子视图和切换后子视图, 这个方法有个条件, 就是一定要两个视图都是当前父视图的子视图才可以切换, 所以在上面才会先添加子视图, 后面的参数都应该很熟悉了, duration延时, options选项, 可以将动画的枚举类型给他, animations更不用说了, 动画效果, 闭包的bool参数finish代表的是切换是否成功
    111     [self transitionFromViewController:oldViewController toViewController:newViewController duration:.3 options:UIViewAnimationOptionTransitionCrossDissolve  animations:nil completion:^(BOOL finished) {
    112         if (finished) {
    113             //切换后将老视图移除, 新的视图设置为当前视图
    114             [oldViewController removeFromParentViewController];
    115             _currentViewController = newViewController;
    116             
    117         }else{
    118             
    119             _currentViewController = oldViewController;
    120             
    121         }
    122     }];
    123 }
    124 
    125 
    126 - (void)didReceiveMemoryWarning {
    127     [super didReceiveMemoryWarning];
    128     // Dispose of any resources that can be recreated.
    129 }
    130 
    131 /*
    132 #pragma mark - Navigation
    133 
    134 // In a storyboard-based application, you will often want to do a little preparation before navigation
    135 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    136     // Get the new view controller using [segue destinationViewController].
    137     // Pass the selected object to the new view controller.
    138 }
    139 */
    140 
    141 @end

      通过这么简单的几步, 就实现了如上界面.

  • 相关阅读:
    【C/C++开发】c++ 工具库 (zz)
    【机器学习】半监督学习
    【Python开发】Pycharm下的Anaconda配置
    【C/C++开发】emplace_back() 和 push_back 的区别
    【C/C++开发】容器set和multiset,C++11对vector成员函数的扩展(cbegin()、cend()、crbegin()、crend()、emplace()、data())
    【C/C++开发】C++11 并发指南三(std::mutex 详解)
    【C/C++开发】C++11 并发指南二(std::thread 详解)
    【C/C++开发】C++11 并发指南一(C++11 多线程初探)
    【C/C++开发】STL内嵌数据类型: value_type
    个股实时监控之综述
  • 原文地址:https://www.cnblogs.com/JianweiWang/p/5305737.html
Copyright © 2020-2023  润新知