先不說廢話, 上效果圖, 代碼量也不大, 也不上傳github騙星星了, 大家複製粘貼下代碼, 就能夠垂手可得的弄出一個小demo.git
這個代碼的實現並不複雜, 甚至於說很是簡單, 就是邏輯有點小繞, 下面將用代碼詳細講解下.github
childViewController方便在一個vc上面呈現出這種多種vc的效果, 相信好處百度上面說的多了去了, 這裏只說實現.數組
首先, 須要新建一個父vc和五個子vc, 這裏就很少說了, 先給你們看看進入父vc後的上面的btn控件封裝, 以及方法回調.閉包
IndentButtonView.h中代碼app
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值來做爲參數回調.ide
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值做爲參數.atom
.hlua
#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
經過這麼簡單的幾步, 就實現瞭如上界面.