├── gif2.gif
├── .DS_Store
├── XDMultTableView
├── .DS_Store
├── XDMultTableView
│ ├── .DS_Store
│ ├── XDMultTableView
│ │ ├── down_blue@2x.png
│ │ ├── XDMultTableView.h
│ │ └── XDMultTableView.m
│ ├── ViewController.h
│ ├── AppDelegate.h
│ ├── main.m
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Info.plist
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── AppDelegate.m
│ └── ViewController.m
└── XDMultTableView.xcodeproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── caixindong.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ ├── xcuserdata
│ └── caixindong.xcuserdatad
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── XDMultTableView.xcscheme
│ └── project.pbxproj
└── README.md
/gif2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/caixindong/XDMultTableView/HEAD/gif2.gif
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/caixindong/XDMultTableView/HEAD/.DS_Store
--------------------------------------------------------------------------------
/XDMultTableView/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/caixindong/XDMultTableView/HEAD/XDMultTableView/.DS_Store
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/caixindong/XDMultTableView/HEAD/XDMultTableView/XDMultTableView/.DS_Store
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView/XDMultTableView/down_blue@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/caixindong/XDMultTableView/HEAD/XDMultTableView/XDMultTableView/XDMultTableView/down_blue@2x.png
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView.xcodeproj/project.xcworkspace/xcuserdata/caixindong.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/caixindong/XDMultTableView/HEAD/XDMultTableView/XDMultTableView.xcodeproj/project.xcworkspace/xcuserdata/caixindong.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // XDMultTableView
4 | //
5 | // Created by 蔡欣东 on 2016/7/16.
6 | // Copyright © 2016年 蔡欣东. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // XDMultTableView
4 | //
5 | // Created by 蔡欣东 on 2016/7/16.
6 | // Copyright © 2016年 蔡欣东. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // XDMultTableView
4 | //
5 | // Created by 蔡欣东 on 2016/7/16.
6 | // Copyright © 2016年 蔡欣东. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView.xcodeproj/xcuserdata/caixindong.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | XDMultTableView.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 4EA4A1F61D39D95A00AC649C
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // XDMultTableView
4 | //
5 | // Created by 蔡欣东 on 2016/7/16.
6 | // Copyright © 2016年 蔡欣东. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # XDMultTableView
2 | 多级展开列表
3 | #effect diagram
4 | 
5 |
6 | #How To Use
7 |
8 | ##Init XDMultTableView
9 | ```ObjC
10 | #import "XDMultTableView.h"
11 | ...
12 | @property(nonatomic, readwrite, strong)XDMultTableView *tableView;
13 |
14 | _tableView = [[XDMultTableView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height-64)];
15 | _tableView.openSectionArray = [NSArray arrayWithObjects:@1,@2, nil];
16 | _tableView.delegate = self;
17 | _tableView.datasource = self;
18 | _tableView.backgroundColor = [UIColor whiteColor];
19 | [self.view addSubview:_tableView];
20 |
21 | ```
22 |
23 | ##Datasource Impletement
24 |
25 | ```ObjC
26 |
27 | - (NSInteger)mTableView:(XDMultTableView *)mTableView numberOfRowsInSection:(NSInteger)section{
28 | return 5;
29 | }
30 |
31 | - (XDMultTableViewCell *)mTableView:(XDMultTableView *)mTableView
32 | cellForRowAtIndexPath:(NSIndexPath *)indexPath{
33 | static NSString *cellIdentifier = @"cell";
34 | UITableViewCell *cell = [mTableView dequeueReusableCellWithIdentifier:cellIdentifier];
35 | if (cell == nil)
36 | {
37 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
38 | }
39 | UIView *view = [[UIView alloc] initWithFrame:cell.bounds] ;
40 | view.layer.backgroundColor = [UIColor whiteColor].CGColor;
41 | view.layer.masksToBounds = YES;
42 | view.layer.borderWidth = 0.3;
43 | view.layer.borderColor = [UIColor lightGrayColor].CGColor;
44 |
45 | cell.backgroundView = view;
46 | cell.selectionStyle = UITableViewCellSelectionStyleNone;
47 |
48 | return cell;
49 | }
50 |
51 | - (NSInteger)numberOfSectionsInTableView:(XDMultTableView *)mTableView{
52 | return 6;
53 | }
54 |
55 | -(NSString *)mTableView:(XDMultTableView *)mTableView titleForHeaderInSection:(NSInteger)section{
56 | return @"我是头部";
57 | }
58 |
59 | ```
60 |
61 | ##Delegate Impletement
62 |
63 | ```ObjC
64 |
65 | - (CGFloat)mTableView:(XDMultTableView *)mTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
66 | return 50;
67 | }
68 |
69 | - (CGFloat)mTableView:(XDMultTableView *)mTableView heightForHeaderInSection:(NSInteger)section{
70 | return 40;
71 | }
72 |
73 |
74 | - (void)mTableView:(XDMultTableView *)mTableView willOpenHeaderAtSection:(NSInteger)section{
75 | NSLog(@"即将展开");
76 | }
77 |
78 |
79 | - (void)mTableView:(XDMultTableView *)mTableView willCloseHeaderAtSection:(NSInteger)section{
80 | NSLog(@"即将关闭");
81 | }
82 |
83 | - (void)mTableView:(XDMultTableView *)mTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
84 | NSLog(@"点击cell");
85 | }
86 |
87 | ```
88 |
89 | ##Easy Extension
90 |
91 | ```
92 | /**
93 | * ...易拓展出你想要的tableview的功能,写法可以参照上面的定义
94 | */
95 | ```
96 |
97 |
98 |
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // XDMultTableView
4 | //
5 | // Created by 蔡欣东 on 2016/7/16.
6 | // Copyright © 2016年 蔡欣东. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "XDMultTableView.h"
11 |
12 | @interface ViewController ()
13 |
14 | @property(nonatomic, readwrite, strong)XDMultTableView *tableView;
15 |
16 | @end
17 |
18 | @implementation ViewController
19 |
20 | - (void)viewDidLoad {
21 | [super viewDidLoad];
22 |
23 | self.automaticallyAdjustsScrollViewInsets = NO;
24 |
25 | self.navigationItem.title = @"我是多级列表";
26 |
27 | _tableView = [[XDMultTableView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height-64)];
28 | _tableView.openSectionArray = [NSArray arrayWithObjects:@1,@2, nil];
29 | _tableView.delegate = self;
30 | _tableView.datasource = self;
31 | _tableView.backgroundColor = [UIColor whiteColor];
32 | _tableView.autoAdjustOpenAndClose = NO;
33 | [self.view addSubview:_tableView];
34 | }
35 |
36 | #pragma mark - datasource
37 | - (NSInteger)mTableView:(XDMultTableView *)mTableView numberOfRowsInSection:(NSInteger)section{
38 | return 5;
39 | }
40 |
41 | - (XDMultTableViewCell *)mTableView:(XDMultTableView *)mTableView
42 | cellForRowAtIndexPath:(NSIndexPath *)indexPath{
43 | static NSString *cellIdentifier = @"cell";
44 | UITableViewCell *cell = [mTableView dequeueReusableCellWithIdentifier:cellIdentifier];
45 | if (cell == nil)
46 | {
47 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
48 | }
49 | UIView *view = [[UIView alloc] initWithFrame:cell.bounds] ;
50 | view.layer.backgroundColor = [UIColor whiteColor].CGColor;
51 | view.layer.masksToBounds = YES;
52 | view.layer.borderWidth = 0.3;
53 | view.layer.borderColor = [UIColor lightGrayColor].CGColor;
54 |
55 | cell.backgroundView = view;
56 | cell.selectionStyle = UITableViewCellSelectionStyleNone;
57 |
58 | return cell;
59 | }
60 |
61 | - (NSInteger)numberOfSectionsInTableView:(XDMultTableView *)mTableView{
62 | return 6;
63 | }
64 |
65 | -(NSString *)mTableView:(XDMultTableView *)mTableView titleForHeaderInSection:(NSInteger)section{
66 | return @"我是头部";
67 | }
68 |
69 | #pragma mark - delegate
70 | - (CGFloat)mTableView:(XDMultTableView *)mTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
71 | return 50;
72 | }
73 |
74 | - (CGFloat)mTableView:(XDMultTableView *)mTableView heightForHeaderInSection:(NSInteger)section{
75 | return 40;
76 | }
77 |
78 |
79 | - (void)mTableView:(XDMultTableView *)mTableView willOpenHeaderAtSection:(NSInteger)section{
80 | NSLog(@"即将展开");
81 | }
82 |
83 |
84 | - (void)mTableView:(XDMultTableView *)mTableView willCloseHeaderAtSection:(NSInteger)section{
85 | NSLog(@"即将关闭");
86 | }
87 |
88 | - (void)mTableView:(XDMultTableView *)mTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
89 | NSLog(@"点击cell");
90 | }
91 |
92 | @end
93 |
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView.xcodeproj/xcuserdata/caixindong.xcuserdatad/xcschemes/XDMultTableView.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView/XDMultTableView/XDMultTableView.h:
--------------------------------------------------------------------------------
1 | //
2 | // XDMultTableView.h
3 | // XDMultTableView
4 | //
5 | // Created by 蔡欣东 on 2016/7/16.
6 | // Copyright © 2016年 蔡欣东. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol XDMultTableViewDelegate,XDMultTableViewDatasource;
12 |
13 | typedef UITableViewCell XDMultTableViewCell;
14 |
15 | typedef UITableViewRowAnimation XDMultTableViewRowAnimation;
16 |
17 | typedef NS_ENUM(NSInteger, XDMultTableViewCellEditingStyle) {
18 | XDMultTableViewCellEditingStyleNone,
19 | XDMultTableViewCellEditingStyleDelete,
20 | XDMultTableViewCellEditingStyleInsert
21 | };
22 |
23 | @interface XDMultTableView : UIView
24 |
25 |
26 | @property (nonatomic, strong, readonly) UITableView *tableView;
27 |
28 | @property (nonatomic, assign, readwrite) id datasource;
29 |
30 | @property (nonatomic, assign, readwrite) id delegate;
31 |
32 |
33 | /**
34 | 若为YES,则点开一行,其他行关闭,默认为YES
35 | */
36 | @property (nonatomic, assign, readwrite) BOOL autoAdjustOpenAndClose;
37 |
38 | /**
39 | 预先打开的行数组
40 | */
41 | @property (nonatomic, copy, readwrite) NSArray *openSectionArray;
42 |
43 | @property (nonatomic, strong, readwrite) UIView *tableViewHeader;
44 |
45 |
46 |
47 | /**
48 | * Cell重用机制(一)
49 | *
50 | * @param identifier Cell标识
51 | *
52 | * @return Cell
53 | */
54 | - (XDMultTableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;
55 |
56 | /**
57 | * Cell重用机制(二)
58 | *
59 | * @param identifier Cell标识
60 | * @param indexPath
61 | *
62 | * @return Cell
63 | */
64 | - (XDMultTableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier
65 | forIndexPath:(NSIndexPath *)indexPath;
66 | /**
67 | * 刷新数据源
68 | */
69 | - (void)reloadData;
70 |
71 | /**
72 | * 注册cell(一)
73 | *
74 | * @param nib
75 | * @param identifier
76 | */
77 | - (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier ;
78 |
79 | /**
80 | * 注册cell(二)
81 | *
82 | * @param cellClass
83 | * @param identifier
84 | */
85 | - (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier;
86 |
87 | /**
88 | * 删除cell
89 | *
90 | * @param indexPaths
91 | * @param animation
92 | */
93 | - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
94 |
95 | @end
96 |
97 | /**
98 | * 数据源
99 | */
100 | @protocol XDMultTableViewDatasource
101 |
102 | @required
103 |
104 | /**
105 | * 每个section的行数
106 | *
107 | * @param mTableView
108 | * @param section
109 | *
110 | * @return 每个section的行数
111 | */
112 | - (NSInteger)mTableView:(XDMultTableView *)mTableView numberOfRowsInSection:(NSInteger)section;
113 |
114 | /**
115 | * Cell显示
116 | *
117 | * @param mTableView
118 | * @param indexPath
119 | *
120 | * @return Cell
121 | */
122 | - (XDMultTableViewCell *)mTableView:(XDMultTableView *)mTableView
123 | cellForRowAtIndexPath:(NSIndexPath *)indexPath;
124 |
125 | @optional
126 |
127 | /**
128 | * section的数量
129 | *
130 | * @param mTableView
131 | *
132 | * @return section的数量
133 | */
134 | - (NSInteger)numberOfSectionsInTableView:(XDMultTableView *)mTableView; // Default is 1
135 |
136 | /**
137 | * 头部的title
138 | *
139 | * @param tableView mTableView
140 | * @param section section
141 | *
142 | * @return
143 | */
144 | -(NSString *)mTableView:(XDMultTableView *)mTableView titleForHeaderInSection:(NSInteger)section;
145 |
146 | //Edit
147 |
148 | /**
149 | * cell是否可以编辑
150 | *
151 | * @param mTableView
152 | * @param indexPath
153 | */
154 | - (BOOL)mTableView:(XDMultTableView *)mTableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
155 |
156 | /**
157 | * cell编辑后回调
158 | *
159 | * @param tableView
160 | * @param editingStyle
161 | * @param indexPath
162 | */
163 | - (void)mTableView:(XDMultTableView *)tableView commitEditingStyle:(XDMultTableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
164 |
165 | @end
166 |
167 | /**
168 | * 代理
169 | */
170 | @protocol XDMultTableViewDelegate
171 |
172 | @optional
173 | /**
174 | * 每个Cell的高度
175 | *
176 | * @param mTableView
177 | * @param indexPath
178 | *
179 | * @return 每个Cell的高度
180 | */
181 | - (CGFloat)mTableView:(XDMultTableView *)mTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
182 |
183 | /**
184 | * 每个section的高度
185 | *
186 | * @param mTableView
187 | * @param section
188 | *
189 | * @return 每个section的高度
190 | */
191 | - (CGFloat)mTableView:(XDMultTableView *)mTableView heightForHeaderInSection:(NSInteger)section;
192 |
193 | /**
194 | * section View
195 | *
196 | * @param mTableView
197 | * @param section
198 | *
199 | * @return section View
200 | */
201 | - (UIView *)mTableView:(XDMultTableView *)mTableView viewForHeaderInSection:(NSInteger)section;
202 |
203 | /**
204 | * 即将打开指定列表回调
205 | *
206 | * @param mTableView
207 | * @param section
208 | */
209 | - (void)mTableView:(XDMultTableView *)mTableView willOpenHeaderAtSection:(NSInteger)section;
210 |
211 | /**
212 | *
213 | * 即将关闭列表回调
214 | * @param mTableView
215 | * @param section
216 | */
217 | - (void)mTableView:(XDMultTableView *)mTableView willCloseHeaderAtSection:(NSInteger)section;
218 |
219 | /**
220 | * 点击Cell回调
221 | *
222 | * @param mTableView
223 | * @param indexPath
224 | */
225 | - (void)mTableView:(XDMultTableView *)mTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
226 |
227 | //Edit
228 |
229 | /**
230 | *
231 | * 设置cell的编辑类型
232 | * @param mTableView
233 | * @param indexPath
234 | *
235 | * @return
236 | */
237 | - (XDMultTableViewCellEditingStyle)mTableView:(XDMultTableView *)mTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
238 |
239 | /**
240 | * 设置cell编辑状态之删除的文本
241 | *
242 | * @param mTableView
243 | * @param indexPath
244 |
245 | * @return
246 | */
247 | - (NSString *)mTableView:(XDMultTableView *)mTableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath;
248 |
249 |
250 | /**
251 | * ...易拓展出你想要的tableview的功能,写法可以参照上面的定义
252 | */
253 |
254 | @end
255 |
256 |
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4EA4A1FC1D39D95A00AC649C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA4A1FB1D39D95A00AC649C /* main.m */; };
11 | 4EA4A1FF1D39D95A00AC649C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA4A1FE1D39D95A00AC649C /* AppDelegate.m */; };
12 | 4EA4A2021D39D95A00AC649C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA4A2011D39D95A00AC649C /* ViewController.m */; };
13 | 4EA4A2051D39D95A00AC649C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4EA4A2031D39D95A00AC649C /* Main.storyboard */; };
14 | 4EA4A2071D39D95A00AC649C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4EA4A2061D39D95A00AC649C /* Assets.xcassets */; };
15 | 4EA4A20A1D39D95A00AC649C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4EA4A2081D39D95A00AC649C /* LaunchScreen.storyboard */; };
16 | 4EA4A2141D39D9C500AC649C /* XDMultTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EA4A2131D39D9C500AC649C /* XDMultTableView.m */; };
17 | 4EA4A2161D39D9D700AC649C /* down_blue@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4EA4A2151D39D9D700AC649C /* down_blue@2x.png */; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXFileReference section */
21 | 4EA4A1F71D39D95A00AC649C /* XDMultTableView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XDMultTableView.app; sourceTree = BUILT_PRODUCTS_DIR; };
22 | 4EA4A1FB1D39D95A00AC649C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
23 | 4EA4A1FD1D39D95A00AC649C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
24 | 4EA4A1FE1D39D95A00AC649C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
25 | 4EA4A2001D39D95A00AC649C /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
26 | 4EA4A2011D39D95A00AC649C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
27 | 4EA4A2041D39D95A00AC649C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
28 | 4EA4A2061D39D95A00AC649C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
29 | 4EA4A2091D39D95A00AC649C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
30 | 4EA4A20B1D39D95A00AC649C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
31 | 4EA4A2121D39D9C500AC649C /* XDMultTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XDMultTableView.h; sourceTree = ""; };
32 | 4EA4A2131D39D9C500AC649C /* XDMultTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XDMultTableView.m; sourceTree = ""; };
33 | 4EA4A2151D39D9D700AC649C /* down_blue@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "down_blue@2x.png"; sourceTree = ""; };
34 | /* End PBXFileReference section */
35 |
36 | /* Begin PBXFrameworksBuildPhase section */
37 | 4EA4A1F41D39D95A00AC649C /* Frameworks */ = {
38 | isa = PBXFrameworksBuildPhase;
39 | buildActionMask = 2147483647;
40 | files = (
41 | );
42 | runOnlyForDeploymentPostprocessing = 0;
43 | };
44 | /* End PBXFrameworksBuildPhase section */
45 |
46 | /* Begin PBXGroup section */
47 | 4EA4A1EE1D39D95A00AC649C = {
48 | isa = PBXGroup;
49 | children = (
50 | 4EA4A1F91D39D95A00AC649C /* XDMultTableView */,
51 | 4EA4A1F81D39D95A00AC649C /* Products */,
52 | );
53 | sourceTree = "";
54 | };
55 | 4EA4A1F81D39D95A00AC649C /* Products */ = {
56 | isa = PBXGroup;
57 | children = (
58 | 4EA4A1F71D39D95A00AC649C /* XDMultTableView.app */,
59 | );
60 | name = Products;
61 | sourceTree = "";
62 | };
63 | 4EA4A1F91D39D95A00AC649C /* XDMultTableView */ = {
64 | isa = PBXGroup;
65 | children = (
66 | 4EA4A2111D39D9A800AC649C /* XDMultTableView */,
67 | 4EA4A1FD1D39D95A00AC649C /* AppDelegate.h */,
68 | 4EA4A1FE1D39D95A00AC649C /* AppDelegate.m */,
69 | 4EA4A2001D39D95A00AC649C /* ViewController.h */,
70 | 4EA4A2011D39D95A00AC649C /* ViewController.m */,
71 | 4EA4A2031D39D95A00AC649C /* Main.storyboard */,
72 | 4EA4A2061D39D95A00AC649C /* Assets.xcassets */,
73 | 4EA4A2081D39D95A00AC649C /* LaunchScreen.storyboard */,
74 | 4EA4A20B1D39D95A00AC649C /* Info.plist */,
75 | 4EA4A1FA1D39D95A00AC649C /* Supporting Files */,
76 | );
77 | path = XDMultTableView;
78 | sourceTree = "";
79 | };
80 | 4EA4A1FA1D39D95A00AC649C /* Supporting Files */ = {
81 | isa = PBXGroup;
82 | children = (
83 | 4EA4A1FB1D39D95A00AC649C /* main.m */,
84 | );
85 | name = "Supporting Files";
86 | sourceTree = "";
87 | };
88 | 4EA4A2111D39D9A800AC649C /* XDMultTableView */ = {
89 | isa = PBXGroup;
90 | children = (
91 | 4EA4A2151D39D9D700AC649C /* down_blue@2x.png */,
92 | 4EA4A2121D39D9C500AC649C /* XDMultTableView.h */,
93 | 4EA4A2131D39D9C500AC649C /* XDMultTableView.m */,
94 | );
95 | path = XDMultTableView;
96 | sourceTree = "";
97 | };
98 | /* End PBXGroup section */
99 |
100 | /* Begin PBXNativeTarget section */
101 | 4EA4A1F61D39D95A00AC649C /* XDMultTableView */ = {
102 | isa = PBXNativeTarget;
103 | buildConfigurationList = 4EA4A20E1D39D95A00AC649C /* Build configuration list for PBXNativeTarget "XDMultTableView" */;
104 | buildPhases = (
105 | 4EA4A1F31D39D95A00AC649C /* Sources */,
106 | 4EA4A1F41D39D95A00AC649C /* Frameworks */,
107 | 4EA4A1F51D39D95A00AC649C /* Resources */,
108 | );
109 | buildRules = (
110 | );
111 | dependencies = (
112 | );
113 | name = XDMultTableView;
114 | productName = XDMultTableView;
115 | productReference = 4EA4A1F71D39D95A00AC649C /* XDMultTableView.app */;
116 | productType = "com.apple.product-type.application";
117 | };
118 | /* End PBXNativeTarget section */
119 |
120 | /* Begin PBXProject section */
121 | 4EA4A1EF1D39D95A00AC649C /* Project object */ = {
122 | isa = PBXProject;
123 | attributes = {
124 | LastUpgradeCheck = 0730;
125 | ORGANIZATIONNAME = "蔡欣东";
126 | TargetAttributes = {
127 | 4EA4A1F61D39D95A00AC649C = {
128 | CreatedOnToolsVersion = 7.3.1;
129 | };
130 | };
131 | };
132 | buildConfigurationList = 4EA4A1F21D39D95A00AC649C /* Build configuration list for PBXProject "XDMultTableView" */;
133 | compatibilityVersion = "Xcode 3.2";
134 | developmentRegion = English;
135 | hasScannedForEncodings = 0;
136 | knownRegions = (
137 | en,
138 | Base,
139 | );
140 | mainGroup = 4EA4A1EE1D39D95A00AC649C;
141 | productRefGroup = 4EA4A1F81D39D95A00AC649C /* Products */;
142 | projectDirPath = "";
143 | projectRoot = "";
144 | targets = (
145 | 4EA4A1F61D39D95A00AC649C /* XDMultTableView */,
146 | );
147 | };
148 | /* End PBXProject section */
149 |
150 | /* Begin PBXResourcesBuildPhase section */
151 | 4EA4A1F51D39D95A00AC649C /* Resources */ = {
152 | isa = PBXResourcesBuildPhase;
153 | buildActionMask = 2147483647;
154 | files = (
155 | 4EA4A2161D39D9D700AC649C /* down_blue@2x.png in Resources */,
156 | 4EA4A20A1D39D95A00AC649C /* LaunchScreen.storyboard in Resources */,
157 | 4EA4A2071D39D95A00AC649C /* Assets.xcassets in Resources */,
158 | 4EA4A2051D39D95A00AC649C /* Main.storyboard in Resources */,
159 | );
160 | runOnlyForDeploymentPostprocessing = 0;
161 | };
162 | /* End PBXResourcesBuildPhase section */
163 |
164 | /* Begin PBXSourcesBuildPhase section */
165 | 4EA4A1F31D39D95A00AC649C /* Sources */ = {
166 | isa = PBXSourcesBuildPhase;
167 | buildActionMask = 2147483647;
168 | files = (
169 | 4EA4A2021D39D95A00AC649C /* ViewController.m in Sources */,
170 | 4EA4A2141D39D9C500AC649C /* XDMultTableView.m in Sources */,
171 | 4EA4A1FF1D39D95A00AC649C /* AppDelegate.m in Sources */,
172 | 4EA4A1FC1D39D95A00AC649C /* main.m in Sources */,
173 | );
174 | runOnlyForDeploymentPostprocessing = 0;
175 | };
176 | /* End PBXSourcesBuildPhase section */
177 |
178 | /* Begin PBXVariantGroup section */
179 | 4EA4A2031D39D95A00AC649C /* Main.storyboard */ = {
180 | isa = PBXVariantGroup;
181 | children = (
182 | 4EA4A2041D39D95A00AC649C /* Base */,
183 | );
184 | name = Main.storyboard;
185 | sourceTree = "";
186 | };
187 | 4EA4A2081D39D95A00AC649C /* LaunchScreen.storyboard */ = {
188 | isa = PBXVariantGroup;
189 | children = (
190 | 4EA4A2091D39D95A00AC649C /* Base */,
191 | );
192 | name = LaunchScreen.storyboard;
193 | sourceTree = "";
194 | };
195 | /* End PBXVariantGroup section */
196 |
197 | /* Begin XCBuildConfiguration section */
198 | 4EA4A20C1D39D95A00AC649C /* Debug */ = {
199 | isa = XCBuildConfiguration;
200 | buildSettings = {
201 | ALWAYS_SEARCH_USER_PATHS = NO;
202 | CLANG_ANALYZER_NONNULL = YES;
203 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
204 | CLANG_CXX_LIBRARY = "libc++";
205 | CLANG_ENABLE_MODULES = YES;
206 | CLANG_ENABLE_OBJC_ARC = YES;
207 | CLANG_WARN_BOOL_CONVERSION = YES;
208 | CLANG_WARN_CONSTANT_CONVERSION = YES;
209 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
210 | CLANG_WARN_EMPTY_BODY = YES;
211 | CLANG_WARN_ENUM_CONVERSION = YES;
212 | CLANG_WARN_INT_CONVERSION = YES;
213 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
214 | CLANG_WARN_UNREACHABLE_CODE = YES;
215 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
216 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
217 | COPY_PHASE_STRIP = NO;
218 | DEBUG_INFORMATION_FORMAT = dwarf;
219 | ENABLE_STRICT_OBJC_MSGSEND = YES;
220 | ENABLE_TESTABILITY = YES;
221 | GCC_C_LANGUAGE_STANDARD = gnu99;
222 | GCC_DYNAMIC_NO_PIC = NO;
223 | GCC_NO_COMMON_BLOCKS = YES;
224 | GCC_OPTIMIZATION_LEVEL = 0;
225 | GCC_PREPROCESSOR_DEFINITIONS = (
226 | "DEBUG=1",
227 | "$(inherited)",
228 | );
229 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
230 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
231 | GCC_WARN_UNDECLARED_SELECTOR = YES;
232 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
233 | GCC_WARN_UNUSED_FUNCTION = YES;
234 | GCC_WARN_UNUSED_VARIABLE = YES;
235 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
236 | MTL_ENABLE_DEBUG_INFO = YES;
237 | ONLY_ACTIVE_ARCH = YES;
238 | SDKROOT = iphoneos;
239 | };
240 | name = Debug;
241 | };
242 | 4EA4A20D1D39D95A00AC649C /* Release */ = {
243 | isa = XCBuildConfiguration;
244 | buildSettings = {
245 | ALWAYS_SEARCH_USER_PATHS = NO;
246 | CLANG_ANALYZER_NONNULL = YES;
247 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
248 | CLANG_CXX_LIBRARY = "libc++";
249 | CLANG_ENABLE_MODULES = YES;
250 | CLANG_ENABLE_OBJC_ARC = YES;
251 | CLANG_WARN_BOOL_CONVERSION = YES;
252 | CLANG_WARN_CONSTANT_CONVERSION = YES;
253 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
254 | CLANG_WARN_EMPTY_BODY = YES;
255 | CLANG_WARN_ENUM_CONVERSION = YES;
256 | CLANG_WARN_INT_CONVERSION = YES;
257 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
258 | CLANG_WARN_UNREACHABLE_CODE = YES;
259 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
260 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
261 | COPY_PHASE_STRIP = NO;
262 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
263 | ENABLE_NS_ASSERTIONS = NO;
264 | ENABLE_STRICT_OBJC_MSGSEND = YES;
265 | GCC_C_LANGUAGE_STANDARD = gnu99;
266 | GCC_NO_COMMON_BLOCKS = YES;
267 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
268 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
269 | GCC_WARN_UNDECLARED_SELECTOR = YES;
270 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
271 | GCC_WARN_UNUSED_FUNCTION = YES;
272 | GCC_WARN_UNUSED_VARIABLE = YES;
273 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
274 | MTL_ENABLE_DEBUG_INFO = NO;
275 | SDKROOT = iphoneos;
276 | VALIDATE_PRODUCT = YES;
277 | };
278 | name = Release;
279 | };
280 | 4EA4A20F1D39D95A00AC649C /* Debug */ = {
281 | isa = XCBuildConfiguration;
282 | buildSettings = {
283 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
284 | INFOPLIST_FILE = XDMultTableView/Info.plist;
285 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
286 | PRODUCT_BUNDLE_IDENTIFIER = com.xindong.XDMultTableView;
287 | PRODUCT_NAME = "$(TARGET_NAME)";
288 | };
289 | name = Debug;
290 | };
291 | 4EA4A2101D39D95A00AC649C /* Release */ = {
292 | isa = XCBuildConfiguration;
293 | buildSettings = {
294 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
295 | INFOPLIST_FILE = XDMultTableView/Info.plist;
296 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
297 | PRODUCT_BUNDLE_IDENTIFIER = com.xindong.XDMultTableView;
298 | PRODUCT_NAME = "$(TARGET_NAME)";
299 | };
300 | name = Release;
301 | };
302 | /* End XCBuildConfiguration section */
303 |
304 | /* Begin XCConfigurationList section */
305 | 4EA4A1F21D39D95A00AC649C /* Build configuration list for PBXProject "XDMultTableView" */ = {
306 | isa = XCConfigurationList;
307 | buildConfigurations = (
308 | 4EA4A20C1D39D95A00AC649C /* Debug */,
309 | 4EA4A20D1D39D95A00AC649C /* Release */,
310 | );
311 | defaultConfigurationIsVisible = 0;
312 | defaultConfigurationName = Release;
313 | };
314 | 4EA4A20E1D39D95A00AC649C /* Build configuration list for PBXNativeTarget "XDMultTableView" */ = {
315 | isa = XCConfigurationList;
316 | buildConfigurations = (
317 | 4EA4A20F1D39D95A00AC649C /* Debug */,
318 | 4EA4A2101D39D95A00AC649C /* Release */,
319 | );
320 | defaultConfigurationIsVisible = 0;
321 | };
322 | /* End XCConfigurationList section */
323 | };
324 | rootObject = 4EA4A1EF1D39D95A00AC649C /* Project object */;
325 | }
326 |
--------------------------------------------------------------------------------
/XDMultTableView/XDMultTableView/XDMultTableView/XDMultTableView.m:
--------------------------------------------------------------------------------
1 | //
2 | // XDMultTableView.m
3 | // XDMultTableView
4 | //
5 | // Created by 蔡欣东 on 2016/7/16.
6 | // Copyright © 2016年 蔡欣东. All rights reserved.
7 | //
8 |
9 | #import "XDMultTableView.h"
10 |
11 | static const CGFloat CELLHEIGHT = 44.0f;
12 |
13 | #define DEFAULTHEADVIEWCOLOR [UIColor colorWithRed:229/255.f green:229/255.f blue:229/255.f alpha:1]
14 |
15 | @interface XDMultTableView()
16 |
17 | @property (nonatomic, strong, readwrite) NSMutableArray *multopenSectionArray;
18 |
19 | @end
20 |
21 | @implementation XDMultTableView
22 |
23 | - (instancetype)initWithFrame:(CGRect)frame{
24 | if ([super initWithFrame:frame]) {
25 | _multopenSectionArray = [NSMutableArray arrayWithCapacity:10];
26 | _autoAdjustOpenAndClose = YES;
27 |
28 | _tableView = [[UITableView alloc] initWithFrame:self.bounds];
29 | _tableView.delegate = self;
30 | _tableView.dataSource = self;
31 | _tableView.backgroundColor = [UIColor clearColor];
32 | _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
33 |
34 | _tableView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
35 |
36 | [self addSubview:_tableView];
37 |
38 | }
39 | return self;
40 | }
41 |
42 | - (XDMultTableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier{
43 |
44 | return [self.tableView dequeueReusableCellWithIdentifier:identifier];
45 | }
46 |
47 | - (XDMultTableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath{
48 | return [self.tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
49 | }
50 |
51 | - (void)reloadData{
52 | [_tableView reloadData];
53 | }
54 |
55 | - (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier{
56 | [self.tableView registerNib:nib forCellReuseIdentifier:identifier];
57 | }
58 |
59 | - (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier{
60 | [self.tableView registerClass:cellClass forCellReuseIdentifier:identifier];
61 | }
62 |
63 | - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(XDMultTableViewRowAnimation)animation{
64 | [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:animation];
65 | }
66 |
67 | #pragma mark - UITableViewDataSource
68 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
69 | if (![_multopenSectionArray containsObject:[NSNumber numberWithInteger:section]]) {
70 | return 0;
71 | }
72 | return [self invoke_numberOfRowsInSection:section];
73 | }
74 |
75 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
76 | return [self invoke_cellForRowAtIndexPath:indexPath];
77 | }
78 |
79 |
80 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
81 | return [self invoke_numberOfSections];
82 | }
83 |
84 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
85 | return [self invode_canEditRowAtIndexPath:indexPath];
86 | }
87 |
88 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
89 | [self invode_commitEditingStyle:editingStyle forRowAtIndexPath:indexPath];
90 | }
91 |
92 | #pragma mark - UITableViewDelegate
93 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
94 | return [self invoke_heightForRowAtIndexPath:indexPath];
95 |
96 | }
97 |
98 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
99 | if (self.datasource && [self.datasource respondsToSelector:@selector(numberOfSectionsInTableView:)])
100 | {
101 | return [self invoke_heightForHeaderInSection:section];
102 |
103 | }else {
104 | return 0;
105 | }
106 | }
107 |
108 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
109 | UIView* view = [self invoke_viewForHeaderInSection:section];
110 | CGFloat height = [self invoke_heightForHeaderInSection:section];
111 | CGFloat width = self.tableView.bounds.size.width;
112 | CGRect frame = CGRectMake(0, 0, width, height);
113 | if (view) {
114 | view.frame = frame;
115 | }else{
116 | view = [[UIView alloc] init];
117 | view.backgroundColor = DEFAULTHEADVIEWCOLOR;
118 | view.layer.borderColor = [UIColor whiteColor].CGColor;
119 | view.layer.borderWidth = 0.5;
120 | NSString *title = [self invoke_titleForHeaderInSection:section];
121 | view.frame = frame;
122 | CGFloat labelW = 200;
123 | CGFloat labelH = 20;
124 | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, (height-labelH)/2, labelW, labelH)];
125 | label.text = title;
126 | [view addSubview:label];
127 | }
128 | view.tag = section;
129 | CGFloat imgH = height-20;
130 | CGFloat imgW = imgH;
131 | UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(width-imgW-10, (height-imgH)/2, imgW, imgH)];
132 | imageView.contentMode = UIViewContentModeScaleAspectFit;
133 | imageView.image = [UIImage imageNamed:@"down_blue"];
134 | NSNumber *sectionObj = [NSNumber numberWithInteger:section];
135 | if ([_multopenSectionArray containsObject:sectionObj]) {
136 | imageView.transform = CGAffineTransformMakeRotation(0);
137 | }else{
138 | imageView.transform = CGAffineTransformMakeRotation(-M_PI/2);
139 | }
140 | imageView.tag = 100;
141 | [view addSubview:imageView];
142 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapHeader:)];
143 | [view addGestureRecognizer:tap];
144 | return view;
145 | }
146 |
147 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
148 | [tableView deselectRowAtIndexPath:indexPath animated:YES];
149 | [self invoke_didSelectRowAtIndexPath:indexPath];
150 | }
151 |
152 | - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
153 | return [self invoke_editingStyleForRowAtIndexPath:indexPath];
154 | }
155 |
156 | - (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{
157 | return [self invoke_titleForDeleteConfirmationButtonForRowAtIndexPath:indexPath];
158 | }
159 |
160 | #pragma mark - add or delete NSIndexPaths
161 |
162 | - (NSMutableArray *)buildInsertRowWithSection:(NSInteger)section
163 | {
164 | NSInteger insert = [self invoke_numberOfRowsInSection:section];
165 |
166 | if (insert != 0)
167 | {
168 | [self invoke_willOpenHeaderAtSection:section];
169 | }
170 |
171 | NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
172 |
173 | for (int i = 0; i < insert; i++)
174 | {
175 | [indexPaths addObject: [NSIndexPath indexPathForRow:i inSection:section]];
176 | }
177 |
178 | return indexPaths;
179 | }
180 |
181 | - (NSMutableArray *)buildDeleteRowWithSection:(NSInteger)section
182 | {
183 | NSInteger delete = [self invoke_numberOfRowsInSection:section];;
184 | if (delete != 0)
185 | {
186 | [self invoke_willCloseHeaderAtSection:section];
187 | }
188 | NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
189 |
190 | for (int i = 0; i < delete; i++)
191 | {
192 | [indexPaths addObject: [NSIndexPath indexPathForRow:i inSection:section]];
193 | }
194 |
195 | return indexPaths;
196 | }
197 |
198 | #pragma mark - UITapGestureRecognizer response
199 | - (void)tapHeader:(UITapGestureRecognizer *) tap {
200 | NSInteger section = tap.view.tag;
201 | NSNumber *sectionObj = [NSNumber numberWithInteger:section];
202 | UIImageView *imageView = (UIImageView *)[tap.view viewWithTag:100];
203 | if ([_multopenSectionArray containsObject:sectionObj]) {
204 | NSArray *deleteArray = [self buildDeleteRowWithSection:section];
205 | [_multopenSectionArray removeObject:sectionObj];
206 | [_tableView deleteRowsAtIndexPaths:deleteArray withRowAnimation:UITableViewRowAnimationFade];
207 | [UIView animateWithDuration:0.3 animations:^{
208 | imageView.transform = CGAffineTransformMakeRotation(-M_PI/2);
209 | }];
210 | }else{
211 | if (_autoAdjustOpenAndClose) {
212 | [[_multopenSectionArray copy] enumerateObjectsUsingBlock:^(NSNumber *obj, NSUInteger idx, BOOL * _Nonnull stop) {
213 | NSLog(@"%ld",[obj integerValue]);
214 | NSArray *otherDeleteArray = [self buildDeleteRowWithSection:[obj integerValue]];
215 | [_multopenSectionArray removeObject:obj];
216 | [_tableView deleteRowsAtIndexPaths:otherDeleteArray withRowAnimation:UITableViewRowAnimationFade];
217 | UIView *otherView = [self.tableView viewWithTag:[obj integerValue]];
218 | UIImageView *imageView = (UIImageView *)[otherView viewWithTag:100];
219 | [UIView animateWithDuration:0.3 animations:^{
220 | imageView.transform = CGAffineTransformMakeRotation(-M_PI/2);
221 | }];
222 | }];
223 | }
224 |
225 | [_multopenSectionArray addObject:sectionObj];
226 | NSArray *insertArray = [self buildInsertRowWithSection:section];
227 | [_tableView insertRowsAtIndexPaths:insertArray withRowAnimation:UITableViewRowAnimationFade];
228 | [UIView animateWithDuration:0.3 animations:^{
229 | imageView.transform = CGAffineTransformMakeRotation(0);
230 | }];
231 | }
232 | }
233 |
234 | #pragma mark - invoke_datasource
235 | - (NSInteger)invoke_numberOfRowsInSection:(NSInteger)section{
236 | if (self.datasource&&[self.datasource respondsToSelector:@selector(mTableView:numberOfRowsInSection:)]){
237 | return [self.datasource mTableView:self numberOfRowsInSection:section];
238 | }
239 | return 0;
240 | }
241 |
242 | - (NSInteger)invoke_numberOfSections{
243 | if (self.datasource&&[self.datasource respondsToSelector:@selector(numberOfSectionsInTableView:)]) {
244 | return [self.datasource numberOfSectionsInTableView:self];
245 | }
246 | return 1;
247 | }
248 |
249 | - (UITableViewCell *)invoke_cellForRowAtIndexPath:(NSIndexPath *)indexPath{
250 | UITableViewCell *cell = nil;
251 | if (self.datasource&&[self.datasource respondsToSelector:@selector(mTableView:cellForRowAtIndexPath:)]) {
252 | cell = [self.datasource mTableView:self cellForRowAtIndexPath:indexPath];
253 | }
254 | return cell;
255 | }
256 |
257 | - (NSString *)invoke_titleForHeaderInSection:(NSInteger)section {
258 | if (self.datasource&&[self.datasource respondsToSelector:@selector(mTableView:titleForHeaderInSection:)]) {
259 | return [self.datasource mTableView:self titleForHeaderInSection:section];
260 | }
261 | return @"";
262 | }
263 |
264 | - (BOOL)invode_canEditRowAtIndexPath:(NSIndexPath *)indexPath {
265 | if(self.datasource&&[self.datasource respondsToSelector:@selector(mTableView:canEditRowAtIndexPath:)]){
266 | return [self.datasource mTableView:self canEditRowAtIndexPath:indexPath];
267 | }
268 | return false;
269 | }
270 |
271 | - (void)invode_commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
272 | if (self.datasource&&[self.datasource respondsToSelector:@selector(mTableView:commitEditingStyle:forRowAtIndexPath:)]) {
273 | XDMultTableViewCellEditingStyle style = (XDMultTableViewCellEditingStyle)editingStyle;
274 | [self.datasource mTableView:self commitEditingStyle:style forRowAtIndexPath:indexPath];
275 | }
276 | }
277 |
278 | #pragma mark - invoke_delegate
279 | - (CGFloat)invoke_heightForRowAtIndexPath:(NSIndexPath *)indexPath{
280 | CGFloat height = CELLHEIGHT;
281 | if (self.delegate&&[self.delegate respondsToSelector:@selector(mTableView:heightForRowAtIndexPath:)]) {
282 | height = [self.delegate mTableView:self heightForRowAtIndexPath:indexPath];
283 | }
284 | return height;
285 | }
286 |
287 | - (CGFloat)invoke_heightForHeaderInSection:(NSInteger)section{
288 | if (self.delegate&&[self.delegate respondsToSelector:@selector(mTableView:heightForHeaderInSection:)]) {
289 | return [self.delegate mTableView:self heightForHeaderInSection:section];
290 | }
291 | return 0;
292 | }
293 |
294 | - (UIView*)invoke_viewForHeaderInSection:(NSInteger)section;{
295 | if (self.delegate&&[self.delegate respondsToSelector:@selector(mTableView:viewForHeaderInSection:)]) {
296 | return [self.delegate mTableView:self viewForHeaderInSection:section];
297 | }
298 | return nil;
299 | }
300 |
301 | - (void)invoke_didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
302 | if (self.delegate&&[self.delegate respondsToSelector:@selector(mTableView:didSelectRowAtIndexPath:)]) {
303 | [self.delegate mTableView:self didSelectRowAtIndexPath:indexPath];
304 | }
305 | }
306 |
307 | - (void)invoke_willOpenHeaderAtSection:(NSInteger)section {
308 | if (self.delegate&&[self.delegate respondsToSelector:@selector(mTableView:willOpenHeaderAtSection:)]) {
309 | [self.delegate mTableView:self willOpenHeaderAtSection:section];
310 | }
311 | }
312 |
313 | - (void)invoke_willCloseHeaderAtSection:(NSInteger)section {
314 | if (self.delegate&&[self.delegate respondsToSelector:@selector(mTableView:willCloseHeaderAtSection:)]) {
315 | [self.delegate mTableView:self willCloseHeaderAtSection:section];
316 | }
317 | }
318 |
319 | - (UITableViewCellEditingStyle)invoke_editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
320 | if (self.delegate&&[self.delegate respondsToSelector:@selector(mTableView:editingStyleForRowAtIndexPath:)]) {
321 | return (UITableViewCellEditingStyle)[self.delegate mTableView:self editingStyleForRowAtIndexPath:indexPath];
322 | }
323 | return UITableViewCellEditingStyleNone;
324 | }
325 |
326 | - (NSString *)invoke_titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{
327 | if (self.delegate&&[self.delegate respondsToSelector:@selector(mTableView:titleForDeleteConfirmationButtonForRowAtIndexPath:)]) {
328 | return [self.delegate mTableView:self titleForDeleteConfirmationButtonForRowAtIndexPath:indexPath];
329 | }
330 | return @"Delete";
331 | }
332 |
333 | #pragma mark - setter and getter
334 | - (void)setOpenSectionArray:(NSArray *)openSectionArray {
335 | _multopenSectionArray = [NSMutableArray arrayWithArray:openSectionArray];
336 | }
337 |
338 | - (void)setTableViewHeader:(UIView *)tableViewHeader {
339 | self.tableView.tableHeaderView = tableViewHeader;
340 | }
341 |
342 |
343 | @end
344 |
--------------------------------------------------------------------------------