├── show.gif
├── show2.gif
├── TreeTableView.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── yixiang.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── TreeTableView.xccheckout
├── xcuserdata
│ └── yixiang.xcuserdatad
│ │ ├── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── TreeTableView.xcscheme
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
└── project.pbxproj
├── TreeTableView
├── ViewController.h
├── AppDelegate.h
├── main.m
├── View
│ ├── TreeTableView.h
│ └── TreeTableView.m
├── Model
│ ├── Node.m
│ └── Node.h
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
├── Base.lproj
│ ├── Main.storyboard
│ └── LaunchScreen.xib
├── AppDelegate.m
└── ViewController.m
├── TreeTableViewTests
├── Info.plist
└── TreeTableViewTests.m
└── README.md
/show.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixiangboy/TreeTableView/HEAD/show.gif
--------------------------------------------------------------------------------
/show2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixiangboy/TreeTableView/HEAD/show2.gif
--------------------------------------------------------------------------------
/TreeTableView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TreeTableView.xcodeproj/project.xcworkspace/xcuserdata/yixiang.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yixiangboy/TreeTableView/HEAD/TreeTableView.xcodeproj/project.xcworkspace/xcuserdata/yixiang.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/TreeTableView/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // TreeTableView
4 | //
5 | // Created by yixiang on 15/7/3.
6 | // Copyright (c) 2015年 yixiang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/TreeTableView/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // TreeTableView
4 | //
5 | // Created by yixiang on 15/7/3.
6 | // Copyright (c) 2015年 yixiang. 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 |
--------------------------------------------------------------------------------
/TreeTableView/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // TreeTableView
4 | //
5 | // Created by yixiang on 15/7/3.
6 | // Copyright (c) 2015年 yixiang. 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 |
--------------------------------------------------------------------------------
/TreeTableView/View/TreeTableView.h:
--------------------------------------------------------------------------------
1 | //
2 | // TreeTableView.h
3 | // TreeTableView
4 | //
5 | // Created by yixiang on 15/7/3.
6 | // Copyright (c) 2015年 yixiang. All rights reserved.
7 | //
8 |
9 | #import
10 | @class Node;
11 |
12 | @protocol TreeTableCellDelegate
13 |
14 | -(void)cellClick : (Node *)node;
15 |
16 | @end
17 |
18 | @interface TreeTableView : UITableView
19 |
20 | @property (nonatomic , weak) id treeTableCellDelegate;
21 |
22 | -(instancetype)initWithFrame:(CGRect)frame withData : (NSArray *)data;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/TreeTableView/Model/Node.m:
--------------------------------------------------------------------------------
1 | //
2 | // Node.m
3 | // TreeTableView
4 | //
5 | // Created by yixiang on 15/7/3.
6 | // Copyright (c) 2015年 yixiang. All rights reserved.
7 | //
8 |
9 | #import "Node.h"
10 |
11 | @implementation Node
12 |
13 | - (instancetype)initWithParentId : (int)parentId nodeId : (int)nodeId name : (NSString *)name depth : (int)depth expand : (BOOL)expand{
14 | self = [self init];
15 | if (self) {
16 | self.parentId = parentId;
17 | self.nodeId = nodeId;
18 | self.name = name;
19 | self.depth = depth;
20 | self.expand = expand;
21 | }
22 | return self;
23 | }
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/TreeTableView.xcodeproj/xcuserdata/yixiang.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | TreeTableView.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | DAC385CD1B46A6B6002CAEDE
16 |
17 | primary
18 |
19 |
20 | DAC385E61B46A6B6002CAEDE
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/TreeTableView/Images.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 | }
--------------------------------------------------------------------------------
/TreeTableView/Model/Node.h:
--------------------------------------------------------------------------------
1 | //
2 | // Node.h
3 | // TreeTableView
4 | //
5 | // Created by yixiang on 15/7/3.
6 | // Copyright (c) 2015年 yixiang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * 每个节点类型
13 | */
14 | @interface Node : NSObject
15 |
16 | @property (nonatomic , assign) int parentId;//父节点的id,如果为-1表示该节点为根节点
17 |
18 | @property (nonatomic , assign) int nodeId;//本节点的id
19 |
20 | @property (nonatomic , strong) NSString *name;//本节点的名称
21 |
22 | @property (nonatomic , assign) int depth;//该节点的深度
23 |
24 | @property (nonatomic , assign) BOOL expand;//该节点是否处于展开状态
25 |
26 |
27 | /**
28 | *快速实例化该对象模型
29 | */
30 | - (instancetype)initWithParentId : (int)parentId nodeId : (int)nodeId name : (NSString *)name depth : (int)depth expand : (BOOL)expand;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/TreeTableViewTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | alibaba.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/TreeTableViewTests/TreeTableViewTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // TreeTableViewTests.m
3 | // TreeTableViewTests
4 | //
5 | // Created by yixiang on 15/7/3.
6 | // Copyright (c) 2015年 yixiang. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface TreeTableViewTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation TreeTableViewTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/TreeTableView/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | alibaba.$(PRODUCT_NAME:rfc1034identifier)
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 |
--------------------------------------------------------------------------------
/TreeTableView/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 |
--------------------------------------------------------------------------------
/TreeTableView.xcodeproj/project.xcworkspace/xcshareddata/TreeTableView.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 08E33E14-0802-4DF7-924B-FDDA94E341B7
9 | IDESourceControlProjectName
10 | TreeTableView
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | C82DC7F4F778D351B30A23FCB6FD75EDA0547138
14 | https://github.com/yixiangboy/TreeTableView
15 |
16 | IDESourceControlProjectPath
17 | TreeTableView.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | C82DC7F4F778D351B30A23FCB6FD75EDA0547138
21 | ../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/yixiangboy/TreeTableView
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | C82DC7F4F778D351B30A23FCB6FD75EDA0547138
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | C82DC7F4F778D351B30A23FCB6FD75EDA0547138
36 | IDESourceControlWCCName
37 | TreeTableView
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/TreeTableView/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // TreeTableView
4 | //
5 | // Created by yixiang on 15/7/3.
6 | // Copyright (c) 2015年 yixiang. 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 |
--------------------------------------------------------------------------------
/TreeTableView/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/TreeTableView/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // TreeTableView
4 | //
5 | // Created by yixiang on 15/7/3.
6 | // Copyright (c) 2015年 yixiang. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "Node.h"
11 | #import "TreeTableView.h"
12 |
13 | @interface ViewController ()
14 |
15 | @end
16 |
17 | @implementation ViewController
18 |
19 | - (void)viewDidLoad {
20 | [super viewDidLoad];
21 | [self initData];
22 |
23 | }
24 |
25 | -(void)initData{
26 |
27 | //----------------------------------中国的省地市关系图3,2,1--------------------------------------------
28 | Node *country1 = [[Node alloc] initWithParentId:-1 nodeId:0 name:@"中国" depth:0 expand:YES];
29 | Node *province1 = [[Node alloc] initWithParentId:0 nodeId:1 name:@"江苏" depth:1 expand:NO];
30 | Node *city1 = [[Node alloc] initWithParentId:1 nodeId:2 name:@"南通" depth:2 expand:NO];
31 | //Node *subCity1 = [[Node alloc] initWithParentId:2 nodeId:100 name:@"通州" depth:3 expand:NO];
32 | //Node *subCity2 = [[Node alloc] initWithParentId:2 nodeId:101 name:@"如东" depth:3 expand:NO];
33 | Node *city2 = [[Node alloc] initWithParentId:1 nodeId:3 name:@"南京" depth:2 expand:NO];
34 | Node *city3 = [[Node alloc] initWithParentId:1 nodeId:4 name:@"苏州" depth:2 expand:NO];
35 | Node *province2 = [[Node alloc] initWithParentId:0 nodeId:5 name:@"广东" depth:1 expand:NO];
36 | Node *city4 = [[Node alloc] initWithParentId:5 nodeId:6 name:@"深圳" depth:2 expand:NO];
37 | Node *city5 = [[Node alloc] initWithParentId:5 nodeId:7 name:@"广州" depth:2 expand:NO];
38 | Node *province3 = [[Node alloc] initWithParentId:0 nodeId:8 name:@"浙江" depth:1 expand:NO];
39 | Node *city6 = [[Node alloc] initWithParentId:8 nodeId:9 name:@"杭州" depth:2 expand:NO];
40 | //----------------------------------美国的省地市关系图0,1,2--------------------------------------------
41 | Node *country2 = [[Node alloc] initWithParentId:-1 nodeId:10 name:@"美国" depth:0 expand:YES];
42 | Node *province4 = [[Node alloc] initWithParentId:10 nodeId:11 name:@"纽约州" depth:1 expand:NO];
43 | Node *province5 = [[Node alloc] initWithParentId:10 nodeId:12 name:@"德州" depth:1 expand:NO];
44 | Node *city7 = [[Node alloc] initWithParentId:12 nodeId:13 name:@"休斯顿" depth:2 expand:NO];
45 | Node *province6 = [[Node alloc] initWithParentId:10 nodeId:14 name:@"加州" depth:1 expand:NO];
46 | Node *city8 = [[Node alloc] initWithParentId:14 nodeId:15 name:@"洛杉矶" depth:2 expand:NO];
47 | Node *city9 = [[Node alloc] initWithParentId:14 nodeId:16 name:@"旧金山" depth:2 expand:NO];
48 |
49 | //----------------------------------日本的省地市关系图0,1,2--------------------------------------------
50 | Node *country3 = [[Node alloc] initWithParentId:-1 nodeId:17 name:@"日本" depth:0 expand:YES];
51 | Node *province7 = [[Node alloc] initWithParentId:17 nodeId:18 name:@"东京" depth:1 expand:NO];
52 | Node *province8 = [[Node alloc] initWithParentId:17 nodeId:19 name:@"东京1" depth:1 expand:NO];
53 | Node *province9 = [[Node alloc] initWithParentId:17 nodeId:20 name:@"东京2" depth:1 expand:NO];
54 |
55 |
56 | //NSArray *data = [NSArray arrayWithObjects:country1,country2,country3, nil];
57 |
58 | //NSArray *data = [NSArray arrayWithObjects:country1,province1,province2,province3,country2,province4,province5,province6,country3, nil];
59 |
60 | NSArray *data = [NSArray arrayWithObjects:country1,province1,city1,city2,city3,province2,city4,city5,province3,city6,country2,province4,province5,city7,province6,city8,city9,country3,province7,province8,province9, nil];
61 |
62 |
63 | TreeTableView *tableview = [[TreeTableView alloc] initWithFrame:CGRectMake(0, 20, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)-20) withData:data];
64 | tableview.treeTableCellDelegate = self;
65 | [self.view addSubview:tableview];
66 | }
67 |
68 | #pragma mark - TreeTableCellDelegate
69 | -(void)cellClick:(Node *)node{
70 | NSLog(@"%@",node.name);
71 | }
72 |
73 | @end
74 |
--------------------------------------------------------------------------------
/TreeTableView.xcodeproj/xcuserdata/yixiang.xcuserdatad/xcschemes/TreeTableView.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
77 |
83 |
84 |
85 |
86 |
87 |
88 |
94 |
96 |
102 |
103 |
104 |
105 |
107 |
108 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/TreeTableView/View/TreeTableView.m:
--------------------------------------------------------------------------------
1 | //
2 | // TreeTableView.m
3 | // TreeTableView
4 | //
5 | // Created by yixiang on 15/7/3.
6 | // Copyright (c) 2015年 yixiang. All rights reserved.
7 | //
8 |
9 | #import "TreeTableView.h"
10 | #import "Node.h"
11 |
12 | @interface TreeTableView ()
13 |
14 | @property (nonatomic , strong) NSArray *data;//传递过来已经组织好的数据(全量数据)
15 |
16 | @property (nonatomic , strong) NSMutableArray *tempData;//用于存储数据源(部分数据)
17 |
18 |
19 | @end
20 |
21 | @implementation TreeTableView
22 |
23 | -(instancetype)initWithFrame:(CGRect)frame withData : (NSArray *)data{
24 | self = [super initWithFrame:frame style:UITableViewStyleGrouped];
25 | if (self) {
26 | self.dataSource = self;
27 | self.delegate = self;
28 | _data = data;
29 | _tempData = [self createTempData:data];
30 | }
31 | return self;
32 | }
33 |
34 | /**
35 | * 初始化数据源
36 | */
37 | -(NSMutableArray *)createTempData : (NSArray *)data{
38 | NSMutableArray *tempArray = [NSMutableArray array];
39 | for (int i=0; istartPosition) {
165 | [_tempData removeObjectsInRange:NSMakeRange(startPosition+1, endPosition-startPosition-1)];
166 | }
167 | return endPosition;
168 | }
169 |
170 | @end
171 |
--------------------------------------------------------------------------------
/TreeTableView.xcodeproj/xcuserdata/yixiang.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
24 |
36 |
37 |
38 |
40 |
52 |
53 |
54 |
56 |
68 |
69 |
70 |
72 |
84 |
85 |
86 |
88 |
100 |
101 |
102 |
104 |
116 |
117 |
118 |
120 |
132 |
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TreeTableView
2 | ===
3 | ##一、简介
4 |
5 | 树形控件在多列列表、多级菜单中使用比较常见,比如:国家-省份-城市 多级选择、学校-专业-班级 多级选择等等。然而IOS自带控件中并不存在树形控件,我们要在IOS开发中使用树形控件,通常需要自己扩展UITableView列表控件。
现在在这里开源一个自己写的高扩展性,高复用性的IOS树形结构控件。
支持无限极树形结构。
使用的是非递归方式。
代码简单易懂,扩展方便。
图片演示如下:
6 | 
7 |
8 |
9 | ##二、使用说明
10 | ###第一步:建立数据模型
11 | parentId : 该节点的父控件id号,如果为-1则表示该节点为根节点
12 | nodeId : 每个节点自身的id号,是每个节点的唯一标示
13 | name : 节点的名称
14 | depth : 该节点所带的树形结构中的深度,根节点的深度为0
15 | expand : 该节点是否处于展开状态
16 | ```
17 | /**
18 | * 每个节点类型
19 | */
20 | @interface Node : NSObject
21 |
22 | @property (nonatomic , assign) int parentId;//父节点的id,如果为-1表示该节点为根节点
23 |
24 | @property (nonatomic , assign) int nodeId;//本节点的id
25 |
26 | @property (nonatomic , strong) NSString *name;//本节点的名称
27 |
28 | @property (nonatomic , assign) int depth;//该节点的深度
29 |
30 | @property (nonatomic , assign) BOOL expand;//该节点是否处于展开状态
31 |
32 | /**
33 | *快速实例化该对象模型
34 | */
35 | - (instancetype)initWithParentId : (int)parentId nodeId : (int)nodeId name : (NSString *)name depth : (int)depth expand : (BOOL)expand;
36 |
37 | @end
38 | ```
39 | ###第二步:按照以上的数据模型,组装数据,下面以 国家-身份-城市 的三级目录进行演示。
40 |
41 | ```
42 | //----------------------------------中国的省地市关系图3,2,1--------------------------------------------
43 | Node *country1 = [[Node alloc] initWithParentId:-1 nodeId:0 name:@"中国" depth:0 expand:YES];
44 | Node *province1 = [[Node alloc] initWithParentId:0 nodeId:1 name:@"江苏" depth:1 expand:NO];
45 | Node *city1 = [[Node alloc] initWithParentId:1 nodeId:2 name:@"南通" depth:2 expand:NO];
46 | Node *city2 = [[Node alloc] initWithParentId:1 nodeId:3 name:@"南京" depth:2 expand:NO];
47 | Node *city3 = [[Node alloc] initWithParentId:1 nodeId:4 name:@"苏州" depth:2 expand:NO];
48 | Node *province2 = [[Node alloc] initWithParentId:0 nodeId:5 name:@"广东" depth:1 expand:NO];
49 | Node *city4 = [[Node alloc] initWithParentId:5 nodeId:6 name:@"深圳" depth:2 expand:NO];
50 | Node *city5 = [[Node alloc] initWithParentId:5 nodeId:7 name:@"广州" depth:2 expand:NO];
51 | Node *province3 = [[Node alloc] initWithParentId:0 nodeId:8 name:@"浙江" depth:1 expand:NO];
52 | Node *city6 = [[Node alloc] initWithParentId:8 nodeId:9 name:@"杭州" depth:2 expand:NO];
53 | //----------------------------------美国的省地市关系图0,1,2--------------------------------------------
54 | Node *country2 = [[Node alloc] initWithParentId:-1 nodeId:10 name:@"美国" depth:0 expand:YES];
55 | Node *province4 = [[Node alloc] initWithParentId:10 nodeId:11 name:@"纽约州" depth:1 expand:NO];
56 | Node *province5 = [[Node alloc] initWithParentId:10 nodeId:12 name:@"德州" depth:1 expand:NO];
57 | Node *city7 = [[Node alloc] initWithParentId:12 nodeId:13 name:@"休斯顿" depth:2 expand:NO];
58 | Node *province6 = [[Node alloc] initWithParentId:10 nodeId:14 name:@"加州" depth:1 expand:NO];
59 | Node *city8 = [[Node alloc] initWithParentId:14 nodeId:15 name:@"洛杉矶" depth:2 expand:NO];
60 | Node *city9 = [[Node alloc] initWithParentId:14 nodeId:16 name:@"旧金山" depth:2 expand:NO];
61 |
62 | //----------------------------------日本的省地市关系图0,1,2--------------------------------------------
63 | Node *country3 = [[Node alloc] initWithParentId:-1 nodeId:17 name:@"日本" depth:0 expand:YES];
64 | NSArray *data = [NSArray arrayWithObjects:country1,province1,city1,city2,city3,province2,city4,city5,province3,city6,country2,province4,province5,city7,province6,city8,city9,country3, nil];
65 | ```
66 | ###第三步:使用以上数据进行TeeTableView的初始化。
67 |
68 | ```
69 | TreeTableView *tableview = [[TreeTableView alloc] initWithFrame:CGRectMake(0, 20, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)-20) withData:data];
70 | [self.view addSubview:tableview];
71 | ```
72 | 通过简单以上三步,你就可以把该树形控件集成到你的项目中。
73 |
74 |
75 | ##三、实现原理
76 | 树形结构的列表用的其实就是UITableView控件,但是如何能够让UItableView能够动态的增加和删除指定的行数的cell是实现树形结构的关键所在。
77 | 这时候我们需要用到两个UItableView自带的行数:
78 | ```
79 | - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
80 | - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
81 | ```
82 | 第一个函数用来在指定的位置插入cells,第二个函数用来在指定的位置删除cells,并且这二个函数都自带多种动画效果,让删除和插入的过程不至于太突兀、有种渐变的感觉,具有良好的用户体验。
83 | 对于这几个动画做了尝试:
84 | UITableViewRowAnimationFade : 渐变效果
85 | UITableViewRowAnimationRight : 右边进入,右边消失
86 | UITableViewRowAnimationLeft : 左边进入,左边消失
87 | UITableViewRowAnimationTop : 顶部进入,顶部消失
88 | UITableViewRowAnimationBottom : 顶部进入,底部消失
89 |
90 | ###注意点:
91 | 在调用insertRowsAtIndexPaths和deleteRowsAtIndexPaths的时候一定要先改变数据源,在调用上述函数,不然会产生crash。
92 |
93 | 接下来把TreeTableView的主要代码展示出来,因为本来代码量就不大,而且代码中注释也比较全,希望能够帮助大家理解。
94 |
95 | ```
96 | #import "TreeTableView.h"
97 | #import "Node.h"
98 |
99 | @interface TreeTableView ()
100 |
101 | @property (nonatomic , strong) NSArray *data;//传递过来已经组织好的数据(全量数据)
102 |
103 | @property (nonatomic , strong) NSMutableArray *tempData;//用于存储数据源(部分数据)
104 |
105 |
106 | @end
107 |
108 | @implementation TreeTableView
109 |
110 | -(instancetype)initWithFrame:(CGRect)frame withData : (NSArray *)data{
111 | self = [super initWithFrame:frame style:UITableViewStyleGrouped];
112 | if (self) {
113 | self.dataSource = self;
114 | self.delegate = self;
115 | _data = data;
116 | _tempData = [self createTempData:data];
117 | }
118 | return self;
119 | }
120 |
121 | /**
122 | * 初始化数据源
123 | */
124 | -(NSMutableArray *)createTempData : (NSArray *)data{
125 | NSMutableArray *tempArray = [NSMutableArray array];
126 | for (int i=0; istartPosition) {
238 | [_tempData removeObjectsInRange:NSMakeRange(startPosition+1, endPosition-startPosition-1)];
239 | }
240 | return endPosition;
241 | }
242 | ```
243 |
244 |
245 | ##四、总结
246 | 在演示项目中,每个cell我都使用系统自带的cell,样式比较简单,如果你要展现更加漂亮的样式,可以自定义cell。
247 | 同时,你也可以扩展该数据模型,运动到更加复杂的业务处理中。比如以下场景:
248 | 
249 |
250 | ##五、下载地址
251 | github下载地址:[https://github.com/yixiangboy/TreeTableView](https://github.com/yixiangboy/TreeTableView)
252 | 如果觉得对你还有些用,给一颗star吧。你的支持是我继续的动力。
253 | 个人博客地址:[http://blog.csdn.net/yixiangboy](http://blog.csdn.net/yixiangboy)
254 |
255 | ##五、博主的话
256 | 以前看过很多别人的博客,学到不少东西。现在准备自己也开始谢谢博客,希望能够帮到一些人。如果工作不是特别忙的话,准备每周写一篇。
257 | 我的联系方式:[新浪微博](http://weibo.com/p/1005055612984599/home?from=page_100505&mod=TAB#place)
258 |
--------------------------------------------------------------------------------
/TreeTableView.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | DAC385D41B46A6B6002CAEDE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC385D31B46A6B6002CAEDE /* main.m */; };
11 | DAC385D71B46A6B6002CAEDE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC385D61B46A6B6002CAEDE /* AppDelegate.m */; };
12 | DAC385DA1B46A6B6002CAEDE /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC385D91B46A6B6002CAEDE /* ViewController.m */; };
13 | DAC385DD1B46A6B6002CAEDE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DAC385DB1B46A6B6002CAEDE /* Main.storyboard */; };
14 | DAC385DF1B46A6B6002CAEDE /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DAC385DE1B46A6B6002CAEDE /* Images.xcassets */; };
15 | DAC385E21B46A6B6002CAEDE /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = DAC385E01B46A6B6002CAEDE /* LaunchScreen.xib */; };
16 | DAC385EE1B46A6B6002CAEDE /* TreeTableViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC385ED1B46A6B6002CAEDE /* TreeTableViewTests.m */; };
17 | DAC385FB1B46AD76002CAEDE /* Node.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC385FA1B46AD76002CAEDE /* Node.m */; };
18 | DAC385FE1B46AFDB002CAEDE /* TreeTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC385FD1B46AFDB002CAEDE /* TreeTableView.m */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXContainerItemProxy section */
22 | DAC385E81B46A6B6002CAEDE /* PBXContainerItemProxy */ = {
23 | isa = PBXContainerItemProxy;
24 | containerPortal = DAC385C61B46A6B6002CAEDE /* Project object */;
25 | proxyType = 1;
26 | remoteGlobalIDString = DAC385CD1B46A6B6002CAEDE;
27 | remoteInfo = TreeTableView;
28 | };
29 | /* End PBXContainerItemProxy section */
30 |
31 | /* Begin PBXFileReference section */
32 | DAC385CE1B46A6B6002CAEDE /* TreeTableView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TreeTableView.app; sourceTree = BUILT_PRODUCTS_DIR; };
33 | DAC385D21B46A6B6002CAEDE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
34 | DAC385D31B46A6B6002CAEDE /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
35 | DAC385D51B46A6B6002CAEDE /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
36 | DAC385D61B46A6B6002CAEDE /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
37 | DAC385D81B46A6B6002CAEDE /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
38 | DAC385D91B46A6B6002CAEDE /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
39 | DAC385DC1B46A6B6002CAEDE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
40 | DAC385DE1B46A6B6002CAEDE /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
41 | DAC385E11B46A6B6002CAEDE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
42 | DAC385E71B46A6B6002CAEDE /* TreeTableViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TreeTableViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
43 | DAC385EC1B46A6B6002CAEDE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
44 | DAC385ED1B46A6B6002CAEDE /* TreeTableViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TreeTableViewTests.m; sourceTree = ""; };
45 | DAC385F91B46AD76002CAEDE /* Node.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Node.h; sourceTree = ""; };
46 | DAC385FA1B46AD76002CAEDE /* Node.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Node.m; sourceTree = ""; };
47 | DAC385FC1B46AFDB002CAEDE /* TreeTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TreeTableView.h; sourceTree = ""; };
48 | DAC385FD1B46AFDB002CAEDE /* TreeTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TreeTableView.m; sourceTree = ""; };
49 | /* End PBXFileReference section */
50 |
51 | /* Begin PBXFrameworksBuildPhase section */
52 | DAC385CB1B46A6B6002CAEDE /* Frameworks */ = {
53 | isa = PBXFrameworksBuildPhase;
54 | buildActionMask = 2147483647;
55 | files = (
56 | );
57 | runOnlyForDeploymentPostprocessing = 0;
58 | };
59 | DAC385E41B46A6B6002CAEDE /* Frameworks */ = {
60 | isa = PBXFrameworksBuildPhase;
61 | buildActionMask = 2147483647;
62 | files = (
63 | );
64 | runOnlyForDeploymentPostprocessing = 0;
65 | };
66 | /* End PBXFrameworksBuildPhase section */
67 |
68 | /* Begin PBXGroup section */
69 | DAC385C51B46A6B6002CAEDE = {
70 | isa = PBXGroup;
71 | children = (
72 | DAC385D01B46A6B6002CAEDE /* TreeTableView */,
73 | DAC385EA1B46A6B6002CAEDE /* TreeTableViewTests */,
74 | DAC385CF1B46A6B6002CAEDE /* Products */,
75 | );
76 | sourceTree = "";
77 | };
78 | DAC385CF1B46A6B6002CAEDE /* Products */ = {
79 | isa = PBXGroup;
80 | children = (
81 | DAC385CE1B46A6B6002CAEDE /* TreeTableView.app */,
82 | DAC385E71B46A6B6002CAEDE /* TreeTableViewTests.xctest */,
83 | );
84 | name = Products;
85 | sourceTree = "";
86 | };
87 | DAC385D01B46A6B6002CAEDE /* TreeTableView */ = {
88 | isa = PBXGroup;
89 | children = (
90 | DAC385F81B46AD1C002CAEDE /* Model */,
91 | DAC385F71B46AD0F002CAEDE /* View */,
92 | DAC385D51B46A6B6002CAEDE /* AppDelegate.h */,
93 | DAC385D61B46A6B6002CAEDE /* AppDelegate.m */,
94 | DAC385D81B46A6B6002CAEDE /* ViewController.h */,
95 | DAC385D91B46A6B6002CAEDE /* ViewController.m */,
96 | DAC385DB1B46A6B6002CAEDE /* Main.storyboard */,
97 | DAC385DE1B46A6B6002CAEDE /* Images.xcassets */,
98 | DAC385E01B46A6B6002CAEDE /* LaunchScreen.xib */,
99 | DAC385D11B46A6B6002CAEDE /* Supporting Files */,
100 | );
101 | path = TreeTableView;
102 | sourceTree = "";
103 | };
104 | DAC385D11B46A6B6002CAEDE /* Supporting Files */ = {
105 | isa = PBXGroup;
106 | children = (
107 | DAC385D21B46A6B6002CAEDE /* Info.plist */,
108 | DAC385D31B46A6B6002CAEDE /* main.m */,
109 | );
110 | name = "Supporting Files";
111 | sourceTree = "";
112 | };
113 | DAC385EA1B46A6B6002CAEDE /* TreeTableViewTests */ = {
114 | isa = PBXGroup;
115 | children = (
116 | DAC385ED1B46A6B6002CAEDE /* TreeTableViewTests.m */,
117 | DAC385EB1B46A6B6002CAEDE /* Supporting Files */,
118 | );
119 | path = TreeTableViewTests;
120 | sourceTree = "";
121 | };
122 | DAC385EB1B46A6B6002CAEDE /* Supporting Files */ = {
123 | isa = PBXGroup;
124 | children = (
125 | DAC385EC1B46A6B6002CAEDE /* Info.plist */,
126 | );
127 | name = "Supporting Files";
128 | sourceTree = "";
129 | };
130 | DAC385F71B46AD0F002CAEDE /* View */ = {
131 | isa = PBXGroup;
132 | children = (
133 | DAC385FC1B46AFDB002CAEDE /* TreeTableView.h */,
134 | DAC385FD1B46AFDB002CAEDE /* TreeTableView.m */,
135 | );
136 | path = View;
137 | sourceTree = "";
138 | };
139 | DAC385F81B46AD1C002CAEDE /* Model */ = {
140 | isa = PBXGroup;
141 | children = (
142 | DAC385F91B46AD76002CAEDE /* Node.h */,
143 | DAC385FA1B46AD76002CAEDE /* Node.m */,
144 | );
145 | path = Model;
146 | sourceTree = "";
147 | };
148 | /* End PBXGroup section */
149 |
150 | /* Begin PBXNativeTarget section */
151 | DAC385CD1B46A6B6002CAEDE /* TreeTableView */ = {
152 | isa = PBXNativeTarget;
153 | buildConfigurationList = DAC385F11B46A6B6002CAEDE /* Build configuration list for PBXNativeTarget "TreeTableView" */;
154 | buildPhases = (
155 | DAC385CA1B46A6B6002CAEDE /* Sources */,
156 | DAC385CB1B46A6B6002CAEDE /* Frameworks */,
157 | DAC385CC1B46A6B6002CAEDE /* Resources */,
158 | );
159 | buildRules = (
160 | );
161 | dependencies = (
162 | );
163 | name = TreeTableView;
164 | productName = TreeTableView;
165 | productReference = DAC385CE1B46A6B6002CAEDE /* TreeTableView.app */;
166 | productType = "com.apple.product-type.application";
167 | };
168 | DAC385E61B46A6B6002CAEDE /* TreeTableViewTests */ = {
169 | isa = PBXNativeTarget;
170 | buildConfigurationList = DAC385F41B46A6B6002CAEDE /* Build configuration list for PBXNativeTarget "TreeTableViewTests" */;
171 | buildPhases = (
172 | DAC385E31B46A6B6002CAEDE /* Sources */,
173 | DAC385E41B46A6B6002CAEDE /* Frameworks */,
174 | DAC385E51B46A6B6002CAEDE /* Resources */,
175 | );
176 | buildRules = (
177 | );
178 | dependencies = (
179 | DAC385E91B46A6B6002CAEDE /* PBXTargetDependency */,
180 | );
181 | name = TreeTableViewTests;
182 | productName = TreeTableViewTests;
183 | productReference = DAC385E71B46A6B6002CAEDE /* TreeTableViewTests.xctest */;
184 | productType = "com.apple.product-type.bundle.unit-test";
185 | };
186 | /* End PBXNativeTarget section */
187 |
188 | /* Begin PBXProject section */
189 | DAC385C61B46A6B6002CAEDE /* Project object */ = {
190 | isa = PBXProject;
191 | attributes = {
192 | LastUpgradeCheck = 0630;
193 | ORGANIZATIONNAME = yixiang;
194 | TargetAttributes = {
195 | DAC385CD1B46A6B6002CAEDE = {
196 | CreatedOnToolsVersion = 6.3.2;
197 | };
198 | DAC385E61B46A6B6002CAEDE = {
199 | CreatedOnToolsVersion = 6.3.2;
200 | TestTargetID = DAC385CD1B46A6B6002CAEDE;
201 | };
202 | };
203 | };
204 | buildConfigurationList = DAC385C91B46A6B6002CAEDE /* Build configuration list for PBXProject "TreeTableView" */;
205 | compatibilityVersion = "Xcode 3.2";
206 | developmentRegion = English;
207 | hasScannedForEncodings = 0;
208 | knownRegions = (
209 | en,
210 | Base,
211 | );
212 | mainGroup = DAC385C51B46A6B6002CAEDE;
213 | productRefGroup = DAC385CF1B46A6B6002CAEDE /* Products */;
214 | projectDirPath = "";
215 | projectRoot = "";
216 | targets = (
217 | DAC385CD1B46A6B6002CAEDE /* TreeTableView */,
218 | DAC385E61B46A6B6002CAEDE /* TreeTableViewTests */,
219 | );
220 | };
221 | /* End PBXProject section */
222 |
223 | /* Begin PBXResourcesBuildPhase section */
224 | DAC385CC1B46A6B6002CAEDE /* Resources */ = {
225 | isa = PBXResourcesBuildPhase;
226 | buildActionMask = 2147483647;
227 | files = (
228 | DAC385DD1B46A6B6002CAEDE /* Main.storyboard in Resources */,
229 | DAC385E21B46A6B6002CAEDE /* LaunchScreen.xib in Resources */,
230 | DAC385DF1B46A6B6002CAEDE /* Images.xcassets in Resources */,
231 | );
232 | runOnlyForDeploymentPostprocessing = 0;
233 | };
234 | DAC385E51B46A6B6002CAEDE /* Resources */ = {
235 | isa = PBXResourcesBuildPhase;
236 | buildActionMask = 2147483647;
237 | files = (
238 | );
239 | runOnlyForDeploymentPostprocessing = 0;
240 | };
241 | /* End PBXResourcesBuildPhase section */
242 |
243 | /* Begin PBXSourcesBuildPhase section */
244 | DAC385CA1B46A6B6002CAEDE /* Sources */ = {
245 | isa = PBXSourcesBuildPhase;
246 | buildActionMask = 2147483647;
247 | files = (
248 | DAC385DA1B46A6B6002CAEDE /* ViewController.m in Sources */,
249 | DAC385D71B46A6B6002CAEDE /* AppDelegate.m in Sources */,
250 | DAC385FE1B46AFDB002CAEDE /* TreeTableView.m in Sources */,
251 | DAC385D41B46A6B6002CAEDE /* main.m in Sources */,
252 | DAC385FB1B46AD76002CAEDE /* Node.m in Sources */,
253 | );
254 | runOnlyForDeploymentPostprocessing = 0;
255 | };
256 | DAC385E31B46A6B6002CAEDE /* Sources */ = {
257 | isa = PBXSourcesBuildPhase;
258 | buildActionMask = 2147483647;
259 | files = (
260 | DAC385EE1B46A6B6002CAEDE /* TreeTableViewTests.m in Sources */,
261 | );
262 | runOnlyForDeploymentPostprocessing = 0;
263 | };
264 | /* End PBXSourcesBuildPhase section */
265 |
266 | /* Begin PBXTargetDependency section */
267 | DAC385E91B46A6B6002CAEDE /* PBXTargetDependency */ = {
268 | isa = PBXTargetDependency;
269 | target = DAC385CD1B46A6B6002CAEDE /* TreeTableView */;
270 | targetProxy = DAC385E81B46A6B6002CAEDE /* PBXContainerItemProxy */;
271 | };
272 | /* End PBXTargetDependency section */
273 |
274 | /* Begin PBXVariantGroup section */
275 | DAC385DB1B46A6B6002CAEDE /* Main.storyboard */ = {
276 | isa = PBXVariantGroup;
277 | children = (
278 | DAC385DC1B46A6B6002CAEDE /* Base */,
279 | );
280 | name = Main.storyboard;
281 | sourceTree = "";
282 | };
283 | DAC385E01B46A6B6002CAEDE /* LaunchScreen.xib */ = {
284 | isa = PBXVariantGroup;
285 | children = (
286 | DAC385E11B46A6B6002CAEDE /* Base */,
287 | );
288 | name = LaunchScreen.xib;
289 | sourceTree = "";
290 | };
291 | /* End PBXVariantGroup section */
292 |
293 | /* Begin XCBuildConfiguration section */
294 | DAC385EF1B46A6B6002CAEDE /* Debug */ = {
295 | isa = XCBuildConfiguration;
296 | buildSettings = {
297 | ALWAYS_SEARCH_USER_PATHS = NO;
298 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
299 | CLANG_CXX_LIBRARY = "libc++";
300 | CLANG_ENABLE_MODULES = YES;
301 | CLANG_ENABLE_OBJC_ARC = YES;
302 | CLANG_WARN_BOOL_CONVERSION = YES;
303 | CLANG_WARN_CONSTANT_CONVERSION = YES;
304 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
305 | CLANG_WARN_EMPTY_BODY = YES;
306 | CLANG_WARN_ENUM_CONVERSION = YES;
307 | CLANG_WARN_INT_CONVERSION = YES;
308 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
309 | CLANG_WARN_UNREACHABLE_CODE = YES;
310 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
311 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
312 | COPY_PHASE_STRIP = NO;
313 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
314 | ENABLE_STRICT_OBJC_MSGSEND = YES;
315 | GCC_C_LANGUAGE_STANDARD = gnu99;
316 | GCC_DYNAMIC_NO_PIC = NO;
317 | GCC_NO_COMMON_BLOCKS = YES;
318 | GCC_OPTIMIZATION_LEVEL = 0;
319 | GCC_PREPROCESSOR_DEFINITIONS = (
320 | "DEBUG=1",
321 | "$(inherited)",
322 | );
323 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
324 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
325 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
326 | GCC_WARN_UNDECLARED_SELECTOR = YES;
327 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
328 | GCC_WARN_UNUSED_FUNCTION = YES;
329 | GCC_WARN_UNUSED_VARIABLE = YES;
330 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
331 | MTL_ENABLE_DEBUG_INFO = YES;
332 | ONLY_ACTIVE_ARCH = YES;
333 | SDKROOT = iphoneos;
334 | };
335 | name = Debug;
336 | };
337 | DAC385F01B46A6B6002CAEDE /* Release */ = {
338 | isa = XCBuildConfiguration;
339 | buildSettings = {
340 | ALWAYS_SEARCH_USER_PATHS = NO;
341 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
342 | CLANG_CXX_LIBRARY = "libc++";
343 | CLANG_ENABLE_MODULES = YES;
344 | CLANG_ENABLE_OBJC_ARC = YES;
345 | CLANG_WARN_BOOL_CONVERSION = YES;
346 | CLANG_WARN_CONSTANT_CONVERSION = YES;
347 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
348 | CLANG_WARN_EMPTY_BODY = YES;
349 | CLANG_WARN_ENUM_CONVERSION = YES;
350 | CLANG_WARN_INT_CONVERSION = YES;
351 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
352 | CLANG_WARN_UNREACHABLE_CODE = YES;
353 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
354 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
355 | COPY_PHASE_STRIP = NO;
356 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
357 | ENABLE_NS_ASSERTIONS = NO;
358 | ENABLE_STRICT_OBJC_MSGSEND = YES;
359 | GCC_C_LANGUAGE_STANDARD = gnu99;
360 | GCC_NO_COMMON_BLOCKS = YES;
361 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
362 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
363 | GCC_WARN_UNDECLARED_SELECTOR = YES;
364 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
365 | GCC_WARN_UNUSED_FUNCTION = YES;
366 | GCC_WARN_UNUSED_VARIABLE = YES;
367 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
368 | MTL_ENABLE_DEBUG_INFO = NO;
369 | SDKROOT = iphoneos;
370 | VALIDATE_PRODUCT = YES;
371 | };
372 | name = Release;
373 | };
374 | DAC385F21B46A6B6002CAEDE /* Debug */ = {
375 | isa = XCBuildConfiguration;
376 | buildSettings = {
377 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
378 | INFOPLIST_FILE = TreeTableView/Info.plist;
379 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
380 | PRODUCT_NAME = "$(TARGET_NAME)";
381 | };
382 | name = Debug;
383 | };
384 | DAC385F31B46A6B6002CAEDE /* Release */ = {
385 | isa = XCBuildConfiguration;
386 | buildSettings = {
387 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
388 | INFOPLIST_FILE = TreeTableView/Info.plist;
389 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
390 | PRODUCT_NAME = "$(TARGET_NAME)";
391 | };
392 | name = Release;
393 | };
394 | DAC385F51B46A6B6002CAEDE /* Debug */ = {
395 | isa = XCBuildConfiguration;
396 | buildSettings = {
397 | BUNDLE_LOADER = "$(TEST_HOST)";
398 | FRAMEWORK_SEARCH_PATHS = (
399 | "$(SDKROOT)/Developer/Library/Frameworks",
400 | "$(inherited)",
401 | );
402 | GCC_PREPROCESSOR_DEFINITIONS = (
403 | "DEBUG=1",
404 | "$(inherited)",
405 | );
406 | INFOPLIST_FILE = TreeTableViewTests/Info.plist;
407 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
408 | PRODUCT_NAME = "$(TARGET_NAME)";
409 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TreeTableView.app/TreeTableView";
410 | };
411 | name = Debug;
412 | };
413 | DAC385F61B46A6B6002CAEDE /* Release */ = {
414 | isa = XCBuildConfiguration;
415 | buildSettings = {
416 | BUNDLE_LOADER = "$(TEST_HOST)";
417 | FRAMEWORK_SEARCH_PATHS = (
418 | "$(SDKROOT)/Developer/Library/Frameworks",
419 | "$(inherited)",
420 | );
421 | INFOPLIST_FILE = TreeTableViewTests/Info.plist;
422 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
423 | PRODUCT_NAME = "$(TARGET_NAME)";
424 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TreeTableView.app/TreeTableView";
425 | };
426 | name = Release;
427 | };
428 | /* End XCBuildConfiguration section */
429 |
430 | /* Begin XCConfigurationList section */
431 | DAC385C91B46A6B6002CAEDE /* Build configuration list for PBXProject "TreeTableView" */ = {
432 | isa = XCConfigurationList;
433 | buildConfigurations = (
434 | DAC385EF1B46A6B6002CAEDE /* Debug */,
435 | DAC385F01B46A6B6002CAEDE /* Release */,
436 | );
437 | defaultConfigurationIsVisible = 0;
438 | defaultConfigurationName = Release;
439 | };
440 | DAC385F11B46A6B6002CAEDE /* Build configuration list for PBXNativeTarget "TreeTableView" */ = {
441 | isa = XCConfigurationList;
442 | buildConfigurations = (
443 | DAC385F21B46A6B6002CAEDE /* Debug */,
444 | DAC385F31B46A6B6002CAEDE /* Release */,
445 | );
446 | defaultConfigurationIsVisible = 0;
447 | };
448 | DAC385F41B46A6B6002CAEDE /* Build configuration list for PBXNativeTarget "TreeTableViewTests" */ = {
449 | isa = XCConfigurationList;
450 | buildConfigurations = (
451 | DAC385F51B46A6B6002CAEDE /* Debug */,
452 | DAC385F61B46A6B6002CAEDE /* Release */,
453 | );
454 | defaultConfigurationIsVisible = 0;
455 | };
456 | /* End XCConfigurationList section */
457 | };
458 | rootObject = DAC385C61B46A6B6002CAEDE /* Project object */;
459 | }
460 |
--------------------------------------------------------------------------------