├── 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 | ![项目演示](http://img.my.csdn.net/uploads/201507/05/1436079831_2869.gif) 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 | ![这里写图片描述](http://img.my.csdn.net/uploads/201507/05/1436079894_7992.gif) 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 | --------------------------------------------------------------------------------