效果如下:
ViewController.h
1 #import <UIKit/UIKit.h> 2 #import "HeaderViewDelegate.h" 3 #import "HeaderView.h" 4 5 @interface ViewController : UITableViewController<HeaderViewDelegate> 6 @property (strong, nonatomic) NSMutableArray *mArrHeaderView; 7 @property (assign, nonatomic) NSInteger currentSection; 8 @property (assign, nonatomic) NSInteger currentRow; 9 10 @end
ViewController.m
1 #import "ViewController.h" 2 3 @interface ViewController () 4 - (void)layoutUI; 5 @end 6 7 @implementation ViewController 8 #define kSectionCount 6 9 #define kRowCount 8 10 #define kWidthForHeaderView self.view.frame.size.width 11 #define kHeightForHeaderView 45 12 #define kHeightForFooterView 1 13 14 - (void)viewDidLoad { 15 [super viewDidLoad]; 16 17 [self layoutUI]; 18 } 19 20 - (void)didReceiveMemoryWarning { 21 [super didReceiveMemoryWarning]; 22 // Dispose of any resources that can be recreated. 23 } 24 25 - (void)layoutUI { 26 _currentSection = -1; 27 _currentRow = -1; 28 _mArrHeaderView = [[NSMutableArray alloc] initWithCapacity:kSectionCount]; 29 for (NSInteger i=0; i<kSectionCount; i++) { 30 HeaderView *headerView = [[HeaderView alloc] initWithFrame:CGRectMake(0, 0, kWidthForHeaderView, kHeightForHeaderView)]; 31 headerView.delegate = self; 32 [headerView.btnBack setTitle:[NSString stringWithFormat:@"第%ld组", (long)i] forState:UIControlStateNormal]; 33 headerView.section = i; 34 [_mArrHeaderView addObject:headerView]; 35 } 36 self.tableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 15.0); //设置单元格(上左下右)内边距 37 38 self.navigationItem.title = @"为每行单元格设置展开子项"; 39 } 40 41 #pragma mark - TableView 42 //- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 43 // return @"列表"; 44 //} 45 46 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 47 return _mArrHeaderView[section]; 48 } 49 50 - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { 51 UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kWidthForHeaderView, kHeightForFooterView)]; 52 view.backgroundColor = [UIColor grayColor]; 53 return view; 54 } 55 56 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 57 return kHeightForHeaderView; 58 } 59 60 - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 61 return kHeightForFooterView; 62 } 63 64 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 65 HeaderView *headerView = _mArrHeaderView[indexPath.section]; 66 return headerView.isOpen ? 35.0 : 0; 67 } 68 69 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 70 return kSectionCount; 71 } 72 73 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 74 HeaderView *headerView = _mArrHeaderView[section]; 75 return headerView.isOpen ? kRowCount : 0; 76 } 77 78 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 79 static NSString *cellIdentifier = @"cellIdentifier"; 80 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 81 if (!cell) { 82 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; 83 } 84 cell.textLabel.text = [NSString stringWithFormat:@"%ld-%ld",(long)indexPath.section,(long)indexPath.row]; 85 return cell; 86 } 87 88 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 89 _currentSection = indexPath.section; 90 _currentRow = indexPath.row; 91 [tableView reloadData]; 92 } 93 94 #pragma mark - HeaderViewDelegate 95 - (void)selectedWith:(HeaderView *)view { 96 UIImage *img = nil; 97 if (view.section == _currentSection) { 98 //点击的HeaderView如果是当前已选中的HeaderView时,就进行本身收缩和展开切换 99 view.isOpen = !view.isOpen; 100 img = [UIImage imageNamed:(view.isOpen ? @"LineIsOpen" : @"LineNormal")]; 101 [view.btnBack setBackgroundImage:img forState:UIControlStateNormal]; 102 } else { 103 //点击的HeaderView如果不是当前已选中的HeaderView时,就进行先收缩全部的HeaderView,再展开它 104 for (HeaderView *headerView in _mArrHeaderView) { 105 headerView.isOpen = NO; 106 img = [UIImage imageNamed:@"LineNormal"]; 107 [headerView.btnBack setBackgroundImage:img forState:UIControlStateNormal]; 108 109 } 110 view.isOpen = YES; 111 img = [UIImage imageNamed:@"LineIsOpen"]; 112 [view.btnBack setBackgroundImage:img forState:UIControlStateNormal]; 113 } 114 [self.tableView reloadData]; 115 116 _currentSection = view.section; 117 } 118 119 @end
HeaderViewDelegate.h
1 @class HeaderView; 2 3 @protocol HeaderViewDelegate <NSObject> 4 - (void)selectedWith:(HeaderView *)view; 5 6 @end
HeaderView.h
1 #import <UIKit/UIKit.h> 2 #import "HeaderViewDelegate.h" 3 4 @interface HeaderView : UIView 5 @property (weak, nonatomic) id<HeaderViewDelegate> delegate; 6 @property (strong, nonatomic) UIButton *btnBack; 7 @property (assign, nonatomic) NSInteger section; 8 @property (assign, nonatomic) BOOL isOpen; 9 10 @end
HeaderView.m
1 #import "HeaderView.h" 2 3 @implementation HeaderView 4 5 - (id)initWithFrame:(CGRect)frame { 6 if (self = [super initWithFrame:frame]) { 7 _isOpen = NO; 8 UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 9 btn.frame = frame; 10 [btn setBackgroundImage:[UIImage imageNamed:@"LineNormal"] 11 forState:UIControlStateNormal]; 12 [btn setBackgroundImage:[UIImage imageNamed:@"LineHighlighted"] 13 forState:UIControlStateHighlighted]; 14 [btn addTarget:self 15 action:@selector(execSelected) 16 forControlEvents:UIControlEventTouchUpInside]; 17 [self addSubview:btn]; 18 _btnBack = btn; 19 } 20 return self; 21 } 22 23 - (void)execSelected { 24 if (_delegate && [_delegate respondsToSelector:@selector(selectedWith:)]) { 25 [_delegate selectedWith:self]; 26 } 27 } 28 29 @end
AppDelegate.h
1 #import <UIKit/UIKit.h> 2 3 @interface AppDelegate : UIResponder <UIApplicationDelegate> 4 @property (strong, nonatomic) UIWindow *window; 5 @property (strong, nonatomic) UINavigationController *navigationController; 6 7 @end
AppDelegate.m
1 #import "AppDelegate.h" 2 #import "ViewController.h" 3 4 @interface AppDelegate () 5 @end 6 7 @implementation AppDelegate 8 9 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 10 _window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 11 ViewController *viewController = [[ViewController alloc] init]; 12 _navigationController = [[UINavigationController alloc] initWithRootViewController:viewController]; 13 _window.rootViewController = _navigationController; 14 //[_window addSubview:_navigationController.view]; //当_window.rootViewController关联时,这一句可有可无 15 [_window makeKeyAndVisible]; 16 return YES; 17 } 18 19 - (void)applicationWillResignActive:(UIApplication *)application { 20 } 21 22 - (void)applicationDidEnterBackground:(UIApplication *)application { 23 } 24 25 - (void)applicationWillEnterForeground:(UIApplication *)application { 26 } 27 28 - (void)applicationDidBecomeActive:(UIApplication *)application { 29 } 30 31 - (void)applicationWillTerminate:(UIApplication *)application { 32 } 33 34 @end