├── LICENSE-MIT ├── README.md ├── TreeTableView.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── vallard.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── vallard.xcuserdatad │ ├── xcdebugger │ └── Breakpoints.xcbkptlist │ └── xcschemes │ ├── TreeTableView.xcscheme │ └── xcschememanagement.plist ├── TreeTableView ├── Default-568h@2x.png ├── Default.png ├── Default@2x.png ├── TTAppDelegate.h ├── TTAppDelegate.m ├── TTCell.h ├── TTCell.m ├── TTExampleTreeTableViewController.h ├── TTExampleTreeTableViewController.m ├── TTSkin.h ├── TTTableViewController.h ├── TTTableViewController.m ├── TreeTableView-Info.plist ├── TreeTableView-Prefix.pch ├── disclosure.png ├── disclosure@2x.png ├── en.lproj │ └── InfoPlist.strings ├── main.m └── version1-screenshot.png └── TreeTableViewTests ├── TreeTableViewTests-Info.plist ├── TreeTableViewTests.h ├── TreeTableViewTests.m └── en.lproj └── InfoPlist.strings /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Vallard Benincosa 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | iOS-TreeTableViewController 2 | =========================== 3 | 4 | Creates an expandable tree table for iOS build on UITableViewController. Use this for putting a left hand navigation tree in the left of an iPad project. 5 | 6 | ![Picture](https://raw.github.com/vallard/iOS-TreeTableViewController/master/TreeTableView/version1-screenshot.png "Picture of app") 7 | -------------------------------------------------------------------------------- /TreeTableView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5E35A79116DC6626006492A3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E35A79016DC6626006492A3 /* UIKit.framework */; }; 11 | 5E35A79316DC6626006492A3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E35A79216DC6626006492A3 /* Foundation.framework */; }; 12 | 5E35A79516DC6626006492A3 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E35A79416DC6626006492A3 /* CoreGraphics.framework */; }; 13 | 5E35A79B16DC6626006492A3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5E35A79916DC6626006492A3 /* InfoPlist.strings */; }; 14 | 5E35A79D16DC6626006492A3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E35A79C16DC6626006492A3 /* main.m */; }; 15 | 5E35A7A116DC6626006492A3 /* TTAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E35A7A016DC6626006492A3 /* TTAppDelegate.m */; }; 16 | 5E35A7A316DC6626006492A3 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 5E35A7A216DC6626006492A3 /* Default.png */; }; 17 | 5E35A7A516DC6626006492A3 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5E35A7A416DC6626006492A3 /* Default@2x.png */; }; 18 | 5E35A7A716DC6626006492A3 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5E35A7A616DC6626006492A3 /* Default-568h@2x.png */; }; 19 | 5E35A7AF16DC6626006492A3 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E35A7AE16DC6626006492A3 /* SenTestingKit.framework */; }; 20 | 5E35A7B016DC6626006492A3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E35A79016DC6626006492A3 /* UIKit.framework */; }; 21 | 5E35A7B116DC6626006492A3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E35A79216DC6626006492A3 /* Foundation.framework */; }; 22 | 5E35A7B916DC6626006492A3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5E35A7B716DC6626006492A3 /* InfoPlist.strings */; }; 23 | 5E35A7BC16DC6626006492A3 /* TreeTableViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E35A7BB16DC6626006492A3 /* TreeTableViewTests.m */; }; 24 | 5E35A7C716DC6656006492A3 /* TTTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E35A7C616DC6655006492A3 /* TTTableViewController.m */; }; 25 | 5E35A7CA16DC670B006492A3 /* TTExampleTreeTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E35A7C916DC670A006492A3 /* TTExampleTreeTableViewController.m */; }; 26 | 5E35A7CD16DC6CD1006492A3 /* TTCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E35A7CC16DC6CD0006492A3 /* TTCell.m */; }; 27 | 5E35A7D516DC7898006492A3 /* disclosure.png in Resources */ = {isa = PBXBuildFile; fileRef = 5E35A7D316DC7898006492A3 /* disclosure.png */; }; 28 | 5E35A7D616DC7898006492A3 /* disclosure@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5E35A7D416DC7898006492A3 /* disclosure@2x.png */; }; 29 | 5EDA0FFF16EB210A0037ADF4 /* version1-screenshot.png in Resources */ = {isa = PBXBuildFile; fileRef = 5EDA0FFE16EB210A0037ADF4 /* version1-screenshot.png */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXContainerItemProxy section */ 33 | 5E35A7B216DC6626006492A3 /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = 5E35A78316DC6626006492A3 /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = 5E35A78B16DC6626006492A3; 38 | remoteInfo = TreeTableView; 39 | }; 40 | /* End PBXContainerItemProxy section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 5E35A78C16DC6626006492A3 /* TreeTableView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TreeTableView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 5E35A79016DC6626006492A3 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 45 | 5E35A79216DC6626006492A3 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 46 | 5E35A79416DC6626006492A3 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 47 | 5E35A79816DC6626006492A3 /* TreeTableView-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TreeTableView-Info.plist"; sourceTree = ""; }; 48 | 5E35A79A16DC6626006492A3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 49 | 5E35A79C16DC6626006492A3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 50 | 5E35A79E16DC6626006492A3 /* TreeTableView-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TreeTableView-Prefix.pch"; sourceTree = ""; }; 51 | 5E35A79F16DC6626006492A3 /* TTAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TTAppDelegate.h; sourceTree = ""; }; 52 | 5E35A7A016DC6626006492A3 /* TTAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TTAppDelegate.m; sourceTree = ""; }; 53 | 5E35A7A216DC6626006492A3 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 54 | 5E35A7A416DC6626006492A3 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 55 | 5E35A7A616DC6626006492A3 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 56 | 5E35A7AD16DC6626006492A3 /* TreeTableViewTests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TreeTableViewTests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; 57 | 5E35A7AE16DC6626006492A3 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; }; 58 | 5E35A7B616DC6626006492A3 /* TreeTableViewTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TreeTableViewTests-Info.plist"; sourceTree = ""; }; 59 | 5E35A7B816DC6626006492A3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 60 | 5E35A7BA16DC6626006492A3 /* TreeTableViewTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TreeTableViewTests.h; sourceTree = ""; }; 61 | 5E35A7BB16DC6626006492A3 /* TreeTableViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TreeTableViewTests.m; sourceTree = ""; }; 62 | 5E35A7C516DC6655006492A3 /* TTTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTTableViewController.h; sourceTree = ""; }; 63 | 5E35A7C616DC6655006492A3 /* TTTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTableViewController.m; sourceTree = ""; }; 64 | 5E35A7C816DC670A006492A3 /* TTExampleTreeTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTExampleTreeTableViewController.h; sourceTree = ""; }; 65 | 5E35A7C916DC670A006492A3 /* TTExampleTreeTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTExampleTreeTableViewController.m; sourceTree = ""; }; 66 | 5E35A7CB16DC6CD0006492A3 /* TTCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTCell.h; sourceTree = ""; }; 67 | 5E35A7CC16DC6CD0006492A3 /* TTCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTCell.m; sourceTree = ""; }; 68 | 5E35A7CE16DC6E12006492A3 /* TTSkin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TTSkin.h; sourceTree = ""; }; 69 | 5E35A7D316DC7898006492A3 /* disclosure.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = disclosure.png; sourceTree = ""; }; 70 | 5E35A7D416DC7898006492A3 /* disclosure@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "disclosure@2x.png"; sourceTree = ""; }; 71 | 5EDA0FFE16EB210A0037ADF4 /* version1-screenshot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "version1-screenshot.png"; sourceTree = ""; }; 72 | /* End PBXFileReference section */ 73 | 74 | /* Begin PBXFrameworksBuildPhase section */ 75 | 5E35A78916DC6626006492A3 /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | 5E35A79116DC6626006492A3 /* UIKit.framework in Frameworks */, 80 | 5E35A79316DC6626006492A3 /* Foundation.framework in Frameworks */, 81 | 5E35A79516DC6626006492A3 /* CoreGraphics.framework in Frameworks */, 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | 5E35A7A916DC6626006492A3 /* Frameworks */ = { 86 | isa = PBXFrameworksBuildPhase; 87 | buildActionMask = 2147483647; 88 | files = ( 89 | 5E35A7AF16DC6626006492A3 /* SenTestingKit.framework in Frameworks */, 90 | 5E35A7B016DC6626006492A3 /* UIKit.framework in Frameworks */, 91 | 5E35A7B116DC6626006492A3 /* Foundation.framework in Frameworks */, 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | /* End PBXFrameworksBuildPhase section */ 96 | 97 | /* Begin PBXGroup section */ 98 | 5E35A78116DC6626006492A3 = { 99 | isa = PBXGroup; 100 | children = ( 101 | 5E35A79616DC6626006492A3 /* TreeTableView */, 102 | 5E35A7B416DC6626006492A3 /* TreeTableViewTests */, 103 | 5E35A78F16DC6626006492A3 /* Frameworks */, 104 | 5E35A78D16DC6626006492A3 /* Products */, 105 | ); 106 | sourceTree = ""; 107 | }; 108 | 5E35A78D16DC6626006492A3 /* Products */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 5E35A78C16DC6626006492A3 /* TreeTableView.app */, 112 | 5E35A7AD16DC6626006492A3 /* TreeTableViewTests.octest */, 113 | ); 114 | name = Products; 115 | sourceTree = ""; 116 | }; 117 | 5E35A78F16DC6626006492A3 /* Frameworks */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 5E35A79016DC6626006492A3 /* UIKit.framework */, 121 | 5E35A79216DC6626006492A3 /* Foundation.framework */, 122 | 5E35A79416DC6626006492A3 /* CoreGraphics.framework */, 123 | 5E35A7AE16DC6626006492A3 /* SenTestingKit.framework */, 124 | ); 125 | name = Frameworks; 126 | sourceTree = ""; 127 | }; 128 | 5E35A79616DC6626006492A3 /* TreeTableView */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 5E35A7D716DC78A1006492A3 /* Images */, 132 | 5E35A7CE16DC6E12006492A3 /* TTSkin.h */, 133 | 5E35A7C516DC6655006492A3 /* TTTableViewController.h */, 134 | 5E35A7C616DC6655006492A3 /* TTTableViewController.m */, 135 | 5E35A7CB16DC6CD0006492A3 /* TTCell.h */, 136 | 5E35A7CC16DC6CD0006492A3 /* TTCell.m */, 137 | 5E35A79F16DC6626006492A3 /* TTAppDelegate.h */, 138 | 5E35A7A016DC6626006492A3 /* TTAppDelegate.m */, 139 | 5E35A79716DC6626006492A3 /* Supporting Files */, 140 | 5E35A7C816DC670A006492A3 /* TTExampleTreeTableViewController.h */, 141 | 5E35A7C916DC670A006492A3 /* TTExampleTreeTableViewController.m */, 142 | ); 143 | path = TreeTableView; 144 | sourceTree = ""; 145 | }; 146 | 5E35A79716DC6626006492A3 /* Supporting Files */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 5E35A79816DC6626006492A3 /* TreeTableView-Info.plist */, 150 | 5E35A79916DC6626006492A3 /* InfoPlist.strings */, 151 | 5E35A79C16DC6626006492A3 /* main.m */, 152 | 5E35A79E16DC6626006492A3 /* TreeTableView-Prefix.pch */, 153 | 5E35A7A216DC6626006492A3 /* Default.png */, 154 | 5E35A7A416DC6626006492A3 /* Default@2x.png */, 155 | 5E35A7A616DC6626006492A3 /* Default-568h@2x.png */, 156 | ); 157 | name = "Supporting Files"; 158 | sourceTree = ""; 159 | }; 160 | 5E35A7B416DC6626006492A3 /* TreeTableViewTests */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 5E35A7BA16DC6626006492A3 /* TreeTableViewTests.h */, 164 | 5E35A7BB16DC6626006492A3 /* TreeTableViewTests.m */, 165 | 5E35A7B516DC6626006492A3 /* Supporting Files */, 166 | ); 167 | path = TreeTableViewTests; 168 | sourceTree = ""; 169 | }; 170 | 5E35A7B516DC6626006492A3 /* Supporting Files */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | 5E35A7B616DC6626006492A3 /* TreeTableViewTests-Info.plist */, 174 | 5E35A7B716DC6626006492A3 /* InfoPlist.strings */, 175 | ); 176 | name = "Supporting Files"; 177 | sourceTree = ""; 178 | }; 179 | 5E35A7D716DC78A1006492A3 /* Images */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 5EDA0FFE16EB210A0037ADF4 /* version1-screenshot.png */, 183 | 5E35A7D316DC7898006492A3 /* disclosure.png */, 184 | 5E35A7D416DC7898006492A3 /* disclosure@2x.png */, 185 | ); 186 | name = Images; 187 | sourceTree = ""; 188 | }; 189 | /* End PBXGroup section */ 190 | 191 | /* Begin PBXNativeTarget section */ 192 | 5E35A78B16DC6626006492A3 /* TreeTableView */ = { 193 | isa = PBXNativeTarget; 194 | buildConfigurationList = 5E35A7BF16DC6626006492A3 /* Build configuration list for PBXNativeTarget "TreeTableView" */; 195 | buildPhases = ( 196 | 5E35A78816DC6626006492A3 /* Sources */, 197 | 5E35A78916DC6626006492A3 /* Frameworks */, 198 | 5E35A78A16DC6626006492A3 /* Resources */, 199 | ); 200 | buildRules = ( 201 | ); 202 | dependencies = ( 203 | ); 204 | name = TreeTableView; 205 | productName = TreeTableView; 206 | productReference = 5E35A78C16DC6626006492A3 /* TreeTableView.app */; 207 | productType = "com.apple.product-type.application"; 208 | }; 209 | 5E35A7AC16DC6626006492A3 /* TreeTableViewTests */ = { 210 | isa = PBXNativeTarget; 211 | buildConfigurationList = 5E35A7C216DC6626006492A3 /* Build configuration list for PBXNativeTarget "TreeTableViewTests" */; 212 | buildPhases = ( 213 | 5E35A7A816DC6626006492A3 /* Sources */, 214 | 5E35A7A916DC6626006492A3 /* Frameworks */, 215 | 5E35A7AA16DC6626006492A3 /* Resources */, 216 | 5E35A7AB16DC6626006492A3 /* ShellScript */, 217 | ); 218 | buildRules = ( 219 | ); 220 | dependencies = ( 221 | 5E35A7B316DC6626006492A3 /* PBXTargetDependency */, 222 | ); 223 | name = TreeTableViewTests; 224 | productName = TreeTableViewTests; 225 | productReference = 5E35A7AD16DC6626006492A3 /* TreeTableViewTests.octest */; 226 | productType = "com.apple.product-type.bundle"; 227 | }; 228 | /* End PBXNativeTarget section */ 229 | 230 | /* Begin PBXProject section */ 231 | 5E35A78316DC6626006492A3 /* Project object */ = { 232 | isa = PBXProject; 233 | attributes = { 234 | CLASSPREFIX = TT; 235 | LastUpgradeCheck = 0450; 236 | ORGANIZATIONNAME = "Vallard Benincosa"; 237 | }; 238 | buildConfigurationList = 5E35A78616DC6626006492A3 /* Build configuration list for PBXProject "TreeTableView" */; 239 | compatibilityVersion = "Xcode 3.2"; 240 | developmentRegion = English; 241 | hasScannedForEncodings = 0; 242 | knownRegions = ( 243 | en, 244 | ); 245 | mainGroup = 5E35A78116DC6626006492A3; 246 | productRefGroup = 5E35A78D16DC6626006492A3 /* Products */; 247 | projectDirPath = ""; 248 | projectRoot = ""; 249 | targets = ( 250 | 5E35A78B16DC6626006492A3 /* TreeTableView */, 251 | 5E35A7AC16DC6626006492A3 /* TreeTableViewTests */, 252 | ); 253 | }; 254 | /* End PBXProject section */ 255 | 256 | /* Begin PBXResourcesBuildPhase section */ 257 | 5E35A78A16DC6626006492A3 /* Resources */ = { 258 | isa = PBXResourcesBuildPhase; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | 5E35A79B16DC6626006492A3 /* InfoPlist.strings in Resources */, 262 | 5E35A7A316DC6626006492A3 /* Default.png in Resources */, 263 | 5E35A7A516DC6626006492A3 /* Default@2x.png in Resources */, 264 | 5E35A7A716DC6626006492A3 /* Default-568h@2x.png in Resources */, 265 | 5E35A7D516DC7898006492A3 /* disclosure.png in Resources */, 266 | 5E35A7D616DC7898006492A3 /* disclosure@2x.png in Resources */, 267 | 5EDA0FFF16EB210A0037ADF4 /* version1-screenshot.png in Resources */, 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | }; 271 | 5E35A7AA16DC6626006492A3 /* Resources */ = { 272 | isa = PBXResourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | 5E35A7B916DC6626006492A3 /* InfoPlist.strings in Resources */, 276 | ); 277 | runOnlyForDeploymentPostprocessing = 0; 278 | }; 279 | /* End PBXResourcesBuildPhase section */ 280 | 281 | /* Begin PBXShellScriptBuildPhase section */ 282 | 5E35A7AB16DC6626006492A3 /* ShellScript */ = { 283 | isa = PBXShellScriptBuildPhase; 284 | buildActionMask = 2147483647; 285 | files = ( 286 | ); 287 | inputPaths = ( 288 | ); 289 | outputPaths = ( 290 | ); 291 | runOnlyForDeploymentPostprocessing = 0; 292 | shellPath = /bin/sh; 293 | shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; 294 | }; 295 | /* End PBXShellScriptBuildPhase section */ 296 | 297 | /* Begin PBXSourcesBuildPhase section */ 298 | 5E35A78816DC6626006492A3 /* Sources */ = { 299 | isa = PBXSourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | 5E35A79D16DC6626006492A3 /* main.m in Sources */, 303 | 5E35A7A116DC6626006492A3 /* TTAppDelegate.m in Sources */, 304 | 5E35A7C716DC6656006492A3 /* TTTableViewController.m in Sources */, 305 | 5E35A7CA16DC670B006492A3 /* TTExampleTreeTableViewController.m in Sources */, 306 | 5E35A7CD16DC6CD1006492A3 /* TTCell.m in Sources */, 307 | ); 308 | runOnlyForDeploymentPostprocessing = 0; 309 | }; 310 | 5E35A7A816DC6626006492A3 /* Sources */ = { 311 | isa = PBXSourcesBuildPhase; 312 | buildActionMask = 2147483647; 313 | files = ( 314 | 5E35A7BC16DC6626006492A3 /* TreeTableViewTests.m in Sources */, 315 | ); 316 | runOnlyForDeploymentPostprocessing = 0; 317 | }; 318 | /* End PBXSourcesBuildPhase section */ 319 | 320 | /* Begin PBXTargetDependency section */ 321 | 5E35A7B316DC6626006492A3 /* PBXTargetDependency */ = { 322 | isa = PBXTargetDependency; 323 | target = 5E35A78B16DC6626006492A3 /* TreeTableView */; 324 | targetProxy = 5E35A7B216DC6626006492A3 /* PBXContainerItemProxy */; 325 | }; 326 | /* End PBXTargetDependency section */ 327 | 328 | /* Begin PBXVariantGroup section */ 329 | 5E35A79916DC6626006492A3 /* InfoPlist.strings */ = { 330 | isa = PBXVariantGroup; 331 | children = ( 332 | 5E35A79A16DC6626006492A3 /* en */, 333 | ); 334 | name = InfoPlist.strings; 335 | sourceTree = ""; 336 | }; 337 | 5E35A7B716DC6626006492A3 /* InfoPlist.strings */ = { 338 | isa = PBXVariantGroup; 339 | children = ( 340 | 5E35A7B816DC6626006492A3 /* en */, 341 | ); 342 | name = InfoPlist.strings; 343 | sourceTree = ""; 344 | }; 345 | /* End PBXVariantGroup section */ 346 | 347 | /* Begin XCBuildConfiguration section */ 348 | 5E35A7BD16DC6626006492A3 /* Debug */ = { 349 | isa = XCBuildConfiguration; 350 | buildSettings = { 351 | ALWAYS_SEARCH_USER_PATHS = NO; 352 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 353 | CLANG_CXX_LIBRARY = "libc++"; 354 | CLANG_ENABLE_OBJC_ARC = YES; 355 | CLANG_WARN_EMPTY_BODY = YES; 356 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 357 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 358 | COPY_PHASE_STRIP = NO; 359 | GCC_C_LANGUAGE_STANDARD = gnu99; 360 | GCC_DYNAMIC_NO_PIC = NO; 361 | GCC_OPTIMIZATION_LEVEL = 0; 362 | GCC_PREPROCESSOR_DEFINITIONS = ( 363 | "DEBUG=1", 364 | "$(inherited)", 365 | ); 366 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 367 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 368 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 369 | GCC_WARN_UNUSED_VARIABLE = YES; 370 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 371 | ONLY_ACTIVE_ARCH = YES; 372 | SDKROOT = iphoneos; 373 | TARGETED_DEVICE_FAMILY = "1,2"; 374 | }; 375 | name = Debug; 376 | }; 377 | 5E35A7BE16DC6626006492A3 /* Release */ = { 378 | isa = XCBuildConfiguration; 379 | buildSettings = { 380 | ALWAYS_SEARCH_USER_PATHS = NO; 381 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 382 | CLANG_CXX_LIBRARY = "libc++"; 383 | CLANG_ENABLE_OBJC_ARC = YES; 384 | CLANG_WARN_EMPTY_BODY = YES; 385 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 386 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 387 | COPY_PHASE_STRIP = YES; 388 | GCC_C_LANGUAGE_STANDARD = gnu99; 389 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 390 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 391 | GCC_WARN_UNUSED_VARIABLE = YES; 392 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 393 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 394 | SDKROOT = iphoneos; 395 | TARGETED_DEVICE_FAMILY = "1,2"; 396 | VALIDATE_PRODUCT = YES; 397 | }; 398 | name = Release; 399 | }; 400 | 5E35A7C016DC6626006492A3 /* Debug */ = { 401 | isa = XCBuildConfiguration; 402 | buildSettings = { 403 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 404 | GCC_PREFIX_HEADER = "TreeTableView/TreeTableView-Prefix.pch"; 405 | INFOPLIST_FILE = "TreeTableView/TreeTableView-Info.plist"; 406 | PRODUCT_NAME = "$(TARGET_NAME)"; 407 | WRAPPER_EXTENSION = app; 408 | }; 409 | name = Debug; 410 | }; 411 | 5E35A7C116DC6626006492A3 /* Release */ = { 412 | isa = XCBuildConfiguration; 413 | buildSettings = { 414 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 415 | GCC_PREFIX_HEADER = "TreeTableView/TreeTableView-Prefix.pch"; 416 | INFOPLIST_FILE = "TreeTableView/TreeTableView-Info.plist"; 417 | PRODUCT_NAME = "$(TARGET_NAME)"; 418 | WRAPPER_EXTENSION = app; 419 | }; 420 | name = Release; 421 | }; 422 | 5E35A7C316DC6626006492A3 /* Debug */ = { 423 | isa = XCBuildConfiguration; 424 | buildSettings = { 425 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/TreeTableView.app/TreeTableView"; 426 | FRAMEWORK_SEARCH_PATHS = ( 427 | "\"$(SDKROOT)/Developer/Library/Frameworks\"", 428 | "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", 429 | ); 430 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 431 | GCC_PREFIX_HEADER = "TreeTableView/TreeTableView-Prefix.pch"; 432 | INFOPLIST_FILE = "TreeTableViewTests/TreeTableViewTests-Info.plist"; 433 | PRODUCT_NAME = "$(TARGET_NAME)"; 434 | TEST_HOST = "$(BUNDLE_LOADER)"; 435 | WRAPPER_EXTENSION = octest; 436 | }; 437 | name = Debug; 438 | }; 439 | 5E35A7C416DC6626006492A3 /* Release */ = { 440 | isa = XCBuildConfiguration; 441 | buildSettings = { 442 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/TreeTableView.app/TreeTableView"; 443 | FRAMEWORK_SEARCH_PATHS = ( 444 | "\"$(SDKROOT)/Developer/Library/Frameworks\"", 445 | "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", 446 | ); 447 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 448 | GCC_PREFIX_HEADER = "TreeTableView/TreeTableView-Prefix.pch"; 449 | INFOPLIST_FILE = "TreeTableViewTests/TreeTableViewTests-Info.plist"; 450 | PRODUCT_NAME = "$(TARGET_NAME)"; 451 | TEST_HOST = "$(BUNDLE_LOADER)"; 452 | WRAPPER_EXTENSION = octest; 453 | }; 454 | name = Release; 455 | }; 456 | /* End XCBuildConfiguration section */ 457 | 458 | /* Begin XCConfigurationList section */ 459 | 5E35A78616DC6626006492A3 /* Build configuration list for PBXProject "TreeTableView" */ = { 460 | isa = XCConfigurationList; 461 | buildConfigurations = ( 462 | 5E35A7BD16DC6626006492A3 /* Debug */, 463 | 5E35A7BE16DC6626006492A3 /* Release */, 464 | ); 465 | defaultConfigurationIsVisible = 0; 466 | defaultConfigurationName = Release; 467 | }; 468 | 5E35A7BF16DC6626006492A3 /* Build configuration list for PBXNativeTarget "TreeTableView" */ = { 469 | isa = XCConfigurationList; 470 | buildConfigurations = ( 471 | 5E35A7C016DC6626006492A3 /* Debug */, 472 | 5E35A7C116DC6626006492A3 /* Release */, 473 | ); 474 | defaultConfigurationIsVisible = 0; 475 | defaultConfigurationName = Release; 476 | }; 477 | 5E35A7C216DC6626006492A3 /* Build configuration list for PBXNativeTarget "TreeTableViewTests" */ = { 478 | isa = XCConfigurationList; 479 | buildConfigurations = ( 480 | 5E35A7C316DC6626006492A3 /* Debug */, 481 | 5E35A7C416DC6626006492A3 /* Release */, 482 | ); 483 | defaultConfigurationIsVisible = 0; 484 | defaultConfigurationName = Release; 485 | }; 486 | /* End XCConfigurationList section */ 487 | }; 488 | rootObject = 5E35A78316DC6626006492A3 /* Project object */; 489 | } 490 | -------------------------------------------------------------------------------- /TreeTableView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TreeTableView.xcodeproj/project.xcworkspace/xcuserdata/vallard.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallard/iOS-TreeTableViewController/d1099ca5b30ded02b3aabf64c7d0c1914866d809/TreeTableView.xcodeproj/project.xcworkspace/xcuserdata/vallard.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /TreeTableView.xcodeproj/xcuserdata/vallard.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /TreeTableView.xcodeproj/xcuserdata/vallard.xcuserdatad/xcschemes/TreeTableView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /TreeTableView.xcodeproj/xcuserdata/vallard.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 | 5E35A78B16DC6626006492A3 16 | 17 | primary 18 | 19 | 20 | 5E35A7AC16DC6626006492A3 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /TreeTableView/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallard/iOS-TreeTableViewController/d1099ca5b30ded02b3aabf64c7d0c1914866d809/TreeTableView/Default-568h@2x.png -------------------------------------------------------------------------------- /TreeTableView/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallard/iOS-TreeTableViewController/d1099ca5b30ded02b3aabf64c7d0c1914866d809/TreeTableView/Default.png -------------------------------------------------------------------------------- /TreeTableView/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallard/iOS-TreeTableViewController/d1099ca5b30ded02b3aabf64c7d0c1914866d809/TreeTableView/Default@2x.png -------------------------------------------------------------------------------- /TreeTableView/TTAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // TTAppDelegate.h 3 | // TreeTableView 4 | // 5 | // Created by Vallard Benincosa on 2/25/13. 6 | // Copyright (c) 2013 Vallard Benincosa. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TTExampleTreeTableViewController.h" 11 | 12 | @interface TTAppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /TreeTableView/TTAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // TTAppDelegate.m 3 | // TreeTableView 4 | // 5 | // Created by Vallard Benincosa on 2/25/13. 6 | // Copyright (c) 2013 Vallard Benincosa. All rights reserved. 7 | // 8 | 9 | #import "TTAppDelegate.h" 10 | 11 | @implementation TTAppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 16 | self.window.backgroundColor = [UIColor whiteColor]; 17 | // sample Dictionary 18 | NSArray *sampleArray = @[ @"1", 19 | @"2", 20 | @[@"3", 21 | @[@"3-1", @"3-1-1", @"3-1-2" ] , @"3-2", @"3-3", @"3-4"], 22 | @"4", 23 | @"5", 24 | @"6"]; 25 | 26 | NSArray *servers = @[@"Servers", @"server 1", @"server 2", @"server 3"]; 27 | 28 | NSArray *backplainPorts = @[@"BackPlane Ports", @"Backplane Port 1/1", @"Backplane Port 1/2", @"Backplane Port 1/3"]; 29 | NSArray *fabricPorts = @[@"Fabric Ports", @"Fabric Port 1/1", @"Fabric Port 1/2"]; 30 | NSArray *iomodules = @[@"IO Modules", @[@"IO Module 1", backplainPorts, fabricPorts], @[@"IO Module 2", backplainPorts, fabricPorts]]; 31 | NSArray *chassisArray = @[@"Chassis", @[@"Chassis 1", iomodules, servers], @[@"Chassis 2", iomodules, servers]]; 32 | NSArray *equipmentArray = @[@[@"Equipment", chassisArray, sampleArray, sampleArray]]; 33 | 34 | // Create Example Tree Table 35 | //TTExampleTreeTableViewController *ttable = [[TTExampleTreeTableViewController alloc] initWithArray:sampleArray]; 36 | TTExampleTreeTableViewController *ttable = [[TTExampleTreeTableViewController alloc] initWithArray:equipmentArray]; 37 | self.window.rootViewController = ttable; 38 | [self.window makeKeyAndVisible]; 39 | return YES; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /TreeTableView/TTCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // TTCell.h 3 | // TreeTableView 4 | // 5 | // Created by Vallard Benincosa on 2/25/13. 6 | // Copyright (c) 2013 Vallard Benincosa. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class TTTableViewController; 12 | @protocol TTCellDelegate; 13 | 14 | @interface TTCell : UITableViewCell { 15 | BOOL expanded; 16 | int numberOfVisibleCells; 17 | } 18 | 19 | @property (nonatomic, copy) NSArray *subTree; 20 | @property (nonatomic, strong) UILabel *label; 21 | @property (nonatomic, strong) UIButton *twister; 22 | @property (nonatomic, strong) TTTableViewController *subTTTableViewController; 23 | @property (nonatomic, strong) TTTableViewController *delegate; 24 | 25 | 26 | - (void)twisterTapped; 27 | - (void)twistUp; 28 | - (void)twistDown; 29 | - (void)showSubTable; 30 | - (void)showTwister; 31 | - (void)hideTwister; 32 | 33 | 34 | @end 35 | 36 | @protocol TTCellDelegate 37 | 38 | - (void)cellSizeChanged:(TTCell *)ttCell numberOfCells:(NSNumber *)numberOfCells; 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /TreeTableView/TTCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // TTCell.m 3 | // TreeTableView 4 | // 5 | // Created by Vallard Benincosa on 2/25/13. 6 | // Copyright (c) 2013 Vallard Benincosa. All rights reserved. 7 | // 8 | 9 | #import "TTCell.h" 10 | #import "TTTableViewController.h" 11 | #import "TTSkin.h" 12 | 13 | 14 | @interface TTCell() 15 | 16 | @end 17 | 18 | 19 | @implementation TTCell 20 | 21 | 22 | 23 | 24 | - (UILabel *)label { 25 | if (!_label) { 26 | CGRect labelRect = CGRectMake(TWISTER_BOX_SIZE, 0, self.frame.size.width - TWISTER_BOX_SIZE, TABLE_CELL_HEIGHT); 27 | _label = [[UILabel alloc] initWithFrame:labelRect]; 28 | _label.backgroundColor = [UIColor clearColor]; 29 | _label.textColor = TABLE_FONT_COLOR; 30 | _label.textAlignment = NSTextAlignmentLeft; 31 | [self.contentView addSubview:_label]; 32 | 33 | } 34 | return _label; 35 | } 36 | 37 | - (UIButton *)twister { 38 | if (!_twister ) { 39 | float y = (TABLE_CELL_HEIGHT - TWISTER_BOX_SIZE) / 2; 40 | CGRect twisterRect = CGRectMake(0, y, TWISTER_BOX_SIZE, TWISTER_BOX_SIZE); 41 | _twister = [[UIButton alloc] initWithFrame:twisterRect]; 42 | [_twister setImage:[UIImage imageNamed:@"disclosure"] forState:UIControlStateNormal]; 43 | [_twister addTarget:self action:@selector(twisterTapped) forControlEvents:UIControlEventTouchUpInside]; 44 | _twister.alpha = 0.45; 45 | } 46 | return _twister; 47 | } 48 | 49 | 50 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 51 | { 52 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 53 | if (self) { 54 | // Initialization code 55 | self.contentView.backgroundColor = TABLE_CELL_COLOR; 56 | self.contentView.clipsToBounds = YES; 57 | self.clipsToBounds = YES; 58 | self.selectionStyle = UITableViewCellSelectionStyleNone; 59 | } 60 | return self; 61 | } 62 | 63 | - (void)showTwister{ 64 | [self.contentView addSubview:self.twister]; 65 | } 66 | 67 | - (void)hideTwister{ 68 | if (self.twister) { 69 | [self.twister removeFromSuperview]; 70 | } 71 | } 72 | 73 | 74 | 75 | - (void)showSubTable { 76 | NSRange myRange; 77 | myRange.location =1; 78 | myRange.length = [self.subTree count] - 1; 79 | NSArray *subArray = [self.subTree subarrayWithRange:myRange]; 80 | self.subTTTableViewController = [[TTTableViewController alloc] initWithArray:subArray]; 81 | 82 | UIView *parentView = [self superview]; 83 | CGRect parentRect = parentView.frame; 84 | CGRect tableRect = CGRectMake(parentRect.origin.x + TABLE_INDENTATION_SIZE, TABLE_CELL_HEIGHT, parentRect.size.width - TABLE_INDENTATION_SIZE, TABLE_CELL_HEIGHT*([self.subTree count] - 1) ); 85 | //NSLog(@"tableRect %f, %f, %f, %f", tableRect.origin.x, tableRect.origin.y, tableRect.size.width, tableRect.size.height); 86 | 87 | self.subTTTableViewController.view.frame = tableRect; 88 | self.subTTTableViewController.delegate = self; 89 | [self addSubview:self.subTTTableViewController.view]; 90 | 91 | 92 | } 93 | 94 | 95 | - (void)twistDown { 96 | // twist down (expand) 97 | [UIView beginAnimations:@"Rotate Down" context:nil]; 98 | [UIView setAnimationDuration:0.2]; 99 | self.twister.transform = CGAffineTransformMakeRotation(M_PI*2.5); 100 | [UIView commitAnimations]; 101 | } 102 | 103 | - (void)twistUp { 104 | // twist up (collapse) 105 | [UIView beginAnimations:@"rotateDisclosureButt" context:nil]; 106 | [UIView setAnimationDuration:0.2]; 107 | self.twister.transform = CGAffineTransformMakeRotation(M_PI*2); 108 | [UIView commitAnimations]; 109 | } 110 | 111 | - (void)twisterTapped { 112 | if (expanded) { 113 | [self twistUp]; 114 | expanded = NO; 115 | // not expanded anymore. remove total visible cells except one! 116 | NSLog(@"new size of cell in containing table: %d", 1); 117 | 118 | [self.delegate cellSizeChanged:self numberOfCells:[NSNumber numberWithInt:1]]; 119 | 120 | // find some way to close everyone elses trees or remember the size. 121 | }else { 122 | [self twistDown]; 123 | expanded = YES; 124 | // expand, make bigger. 125 | 126 | if (! numberOfVisibleCells) { 127 | numberOfVisibleCells = [self.subTree count]; 128 | } 129 | NSLog(@"new size of cell in containing table: %d", numberOfVisibleCells); 130 | [self.delegate cellSizeChanged:self numberOfCells:[NSNumber numberWithInt:(numberOfVisibleCells)]]; 131 | } 132 | 133 | } 134 | 135 | #pragma mark - 136 | #pragma mark - TTTableExpanderDelegate Method 137 | 138 | // Double recursion! Agghhh! 139 | - (void)updateNumberOfTableCells:(TTTableViewController *)tableViewController numberOfCells:(NSNumber *)numberOfCells { 140 | // tack on one for the first cell? 141 | 142 | NSLog(@"UPDATNUMBEROFTABLECELLS"); 143 | //assert(numberOfCells.intValue >= [self.subTree count]); 144 | if (numberOfCells.intValue < [self.subTree count] && expanded) { 145 | numberOfCells = [NSNumber numberWithInt:[self.subTree count]]; 146 | } 147 | numberOfVisibleCells = numberOfCells.intValue; 148 | NSLog(@"\theight of table is will now be: %d", numberOfVisibleCells); 149 | [self.delegate cellSizeChanged:self numberOfCells:numberOfCells]; 150 | } 151 | 152 | 153 | @end 154 | -------------------------------------------------------------------------------- /TreeTableView/TTExampleTreeTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TTExampleTreeTableViewController.h 3 | // TreeTableView 4 | // 5 | // Created by Vallard Benincosa on 2/25/13. 6 | // Copyright (c) 2013 Vallard Benincosa. All rights reserved. 7 | // 8 | 9 | #import "TTTableViewController.h" 10 | 11 | @interface TTExampleTreeTableViewController : TTTableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TreeTableView/TTExampleTreeTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TTExampleTreeTableViewController.m 3 | // TreeTableView 4 | // 5 | // Created by Vallard Benincosa on 2/25/13. 6 | // Copyright (c) 2013 Vallard Benincosa. All rights reserved. 7 | // 8 | 9 | #import "TTExampleTreeTableViewController.h" 10 | 11 | @interface TTExampleTreeTableViewController () 12 | 13 | @end 14 | 15 | @implementation TTExampleTreeTableViewController 16 | 17 | 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /TreeTableView/TTSkin.h: -------------------------------------------------------------------------------- 1 | // 2 | // TTSkin.h 3 | // TreeTableView 4 | // 5 | // Created by Vallard Benincosa on 2/25/13. 6 | // Copyright (c) 2013 Vallard Benincosa. All rights reserved. 7 | // 8 | 9 | #ifndef TreeTableView_TTSkin_h 10 | #define TreeTableView_TTSkin_h 11 | 12 | #define UIColorFromRGB(rgbValue) [UIColor \ 13 | colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \ 14 | green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \ 15 | blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0] 16 | 17 | // TABLE VIEW 18 | #define TABLEVIEW_BACKGROUND_COLOR UIColorFromRGB(0x550011) 19 | #define TABLEVIEW_SEPARATOR_COLOR UIColorFromRGB(0x555555) 20 | 21 | // Table Cell Height 22 | #define TABLE_CELL_HEIGHT 44.0 23 | #define TABLE_CELL_COLOR UIColorFromRGB(0x555550) 24 | #define TABLE_FONT_COLOR UIColorFromRGB(0xeeeeee) 25 | #define TABLE_INDENTATION_SIZE 5.0 26 | /* 27 | Make sure TWISTER_BOX_SIZE is not greater than TABLE_CELL_HEIGHT 28 | */ 29 | #define TWISTER_BOX_SIZE 40.0 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /TreeTableView/TTTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TTTableViewController.h 3 | // TreeTableView 4 | // 5 | // Created by Vallard Benincosa on 2/25/13. 6 | // Copyright (c) 2013 Vallard Benincosa. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TTSkin.h" 11 | #import "TTCell.h" 12 | 13 | @class TTTableViewController; 14 | 15 | @protocol TTTableExpanderDelegate 16 | 17 | - (void)updateNumberOfTableCells:(TTTableViewController *)tableViewController numberOfCells:(NSNumber *)numberOfCells; 18 | 19 | @end 20 | 21 | 22 | @interface TTTableViewController : UITableViewController 23 | 24 | @property (nonatomic) NSInteger level; 25 | @property (nonatomic, strong) NSArray *tree; 26 | @property (nonatomic, strong) TTCell *delegate; 27 | 28 | - (id)initWithArray:(NSArray *)tree; 29 | 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /TreeTableView/TTTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TTTableViewController.m 3 | // TreeTableView 4 | // 5 | // Created by Vallard Benincosa on 2/25/13. 6 | // Copyright (c) 2013 Vallard Benincosa. All rights reserved. 7 | // 8 | 9 | #import "TTTableViewController.h" 10 | #import "TTCell.h" 11 | 12 | #define TTCELL_IDENTIFIER @"TTCell" 13 | 14 | 15 | @interface TTTableViewController () 16 | 17 | @property (nonatomic, strong) NSMutableDictionary *cellHeights; 18 | 19 | @end 20 | 21 | @implementation TTTableViewController 22 | 23 | @synthesize cellHeights = _cellHeights; 24 | 25 | 26 | #pragma mark - TTCell Delegate Methods 27 | 28 | // look out! Double recursion!! 29 | - (void)cellSizeChanged:(TTCell *)ttCell numberOfCells:(NSNumber *)numberOfCells { 30 | NSIndexPath *indexPath = [self strictIndexPath:[self.tableView indexPathForCell:ttCell]]; 31 | if (numberOfCells.intValue == 1) { 32 | [self.cellHeights removeObjectForKey:indexPath]; 33 | }else { 34 | [self.cellHeights setObject:numberOfCells forKey:indexPath]; // this is now the size of our cell. 35 | } 36 | 37 | if (self.delegate) { 38 | int tableHeight = [self.tree count]; 39 | for (id key in self.cellHeights){ 40 | int thisHeight = ((NSNumber *)[self.cellHeights objectForKey:key]).intValue; 41 | tableHeight += thisHeight; // this height takes the place of the old height. 42 | tableHeight -= 1; // subtract the standard height of the cell 43 | } 44 | tableHeight += 1; // add the height of the cell header which is not in this tree. 45 | [self.delegate updateNumberOfTableCells:self numberOfCells:[NSNumber numberWithInt:tableHeight]]; 46 | } 47 | // I found this cool trick on the internet. Resizes cells without reloading data! 48 | [self.tableView beginUpdates]; 49 | [self.tableView endUpdates]; 50 | } 51 | 52 | 53 | 54 | #pragma mark - Init Methods 55 | - (id)initWithArray:(NSArray *)tree{ 56 | self = [super initWithStyle:UITableViewStylePlain]; 57 | if (self) { 58 | self.tree = tree; 59 | self.level = 0; 60 | self.cellHeights = [[NSMutableDictionary alloc] init]; 61 | } 62 | return self; 63 | } 64 | 65 | 66 | 67 | 68 | 69 | - (void)viewDidLoad 70 | { 71 | [super viewDidLoad]; 72 | [self.tableView registerClass:[TTCell class] forCellReuseIdentifier:TTCELL_IDENTIFIER]; 73 | //self.tableView.rowHeight = TABLE_CELL_HEIGHT; 74 | self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 75 | self.tableView.backgroundColor = TABLEVIEW_BACKGROUND_COLOR; 76 | //self.tableView.separatorColor = TABLEVIEW_SEPARATOR_COLOR; 77 | } 78 | 79 | - (void)didReceiveMemoryWarning 80 | { 81 | [super didReceiveMemoryWarning]; 82 | // Dispose of any resources that can be recreated. 83 | } 84 | 85 | #pragma mark - Table view data source 86 | 87 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 88 | { 89 | // We don't support sections in Tree Table View 90 | return 1; 91 | } 92 | 93 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 94 | { 95 | return [self.tree count]; 96 | } 97 | 98 | // recursive function to get the first element of the sub tree. 99 | // goes all the way down to the bottom most turtle. 100 | 101 | - (NSString *)getRootForBranch:(NSObject *)item { 102 | if ([item isKindOfClass:[NSString class]]) { 103 | return (NSString *)item; 104 | }else if([item isKindOfClass:[NSArray class]]){ 105 | return [self getRootForBranch:[(NSArray *)item objectAtIndex:0]]; 106 | }else { 107 | NSLog(@"errror in data formation. This should not happen"); 108 | } 109 | return nil; 110 | } 111 | 112 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 113 | { 114 | TTCell *cell = [tableView dequeueReusableCellWithIdentifier:TTCELL_IDENTIFIER forIndexPath:indexPath]; 115 | cell.delegate = self; 116 | cell.label.text = [self getRootForBranch:[self.tree objectAtIndex:indexPath.row]]; 117 | if ([[self.tree objectAtIndex:indexPath.row] isKindOfClass:[NSArray class]]) { 118 | cell.subTree = [self.tree objectAtIndex:indexPath.row]; 119 | [cell showTwister]; 120 | [cell showSubTable]; 121 | }else { 122 | [cell hideTwister]; 123 | } 124 | return cell; 125 | } 126 | 127 | #pragma mark - Table Appearance Properties 128 | 129 | 130 | - (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 131 | { 132 | CGFloat heightForCell = TABLE_CELL_HEIGHT; 133 | if ([self.cellHeights objectForKey:[self strictIndexPath:indexPath]]) { 134 | heightForCell = [(NSNumber *)[self.cellHeights objectForKey:[self strictIndexPath:indexPath]] floatValue] * TABLE_CELL_HEIGHT; 135 | } 136 | 137 | return heightForCell; 138 | } 139 | 140 | 141 | 142 | #pragma mark - Table view delegate 143 | 144 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 145 | { 146 | // Navigation logic may go here. Create and push another view controller. 147 | /* 148 | *detailViewController = [[ta alloc] initWithNibName:@"<#Nib name#>" bundle:nil]; 149 | // ... 150 | // Pass the selected object to the new view controller. 151 | [self.navigationController pushViewController:detailViewController animated:YES]; 152 | */ 153 | } 154 | 155 | - (NSIndexPath *)strictIndexPath:(NSIndexPath *)indexPath 156 | { 157 | if ([indexPath class] == [NSIndexPath class]) { 158 | return indexPath; 159 | } 160 | return [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section]; 161 | } 162 | 163 | @end 164 | -------------------------------------------------------------------------------- /TreeTableView/TreeTableView-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | Vallard-Benincosa.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /TreeTableView/TreeTableView-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'TreeTableView' target in the 'TreeTableView' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_3_0 8 | #warning "This project uses features only available in iOS SDK 3.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /TreeTableView/disclosure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallard/iOS-TreeTableViewController/d1099ca5b30ded02b3aabf64c7d0c1914866d809/TreeTableView/disclosure.png -------------------------------------------------------------------------------- /TreeTableView/disclosure@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallard/iOS-TreeTableViewController/d1099ca5b30ded02b3aabf64c7d0c1914866d809/TreeTableView/disclosure@2x.png -------------------------------------------------------------------------------- /TreeTableView/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /TreeTableView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // TreeTableView 4 | // 5 | // Created by Vallard Benincosa on 2/25/13. 6 | // Copyright (c) 2013 Vallard Benincosa. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "TTAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([TTAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /TreeTableView/version1-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vallard/iOS-TreeTableViewController/d1099ca5b30ded02b3aabf64c7d0c1914866d809/TreeTableView/version1-screenshot.png -------------------------------------------------------------------------------- /TreeTableViewTests/TreeTableViewTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | Vallard-Benincosa.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /TreeTableViewTests/TreeTableViewTests.h: -------------------------------------------------------------------------------- 1 | // 2 | // TreeTableViewTests.h 3 | // TreeTableViewTests 4 | // 5 | // Created by Vallard Benincosa on 2/25/13. 6 | // Copyright (c) 2013 Vallard Benincosa. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TreeTableViewTests : SenTestCase 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TreeTableViewTests/TreeTableViewTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // TreeTableViewTests.m 3 | // TreeTableViewTests 4 | // 5 | // Created by Vallard Benincosa on 2/25/13. 6 | // Copyright (c) 2013 Vallard Benincosa. All rights reserved. 7 | // 8 | 9 | #import "TreeTableViewTests.h" 10 | 11 | @implementation TreeTableViewTests 12 | 13 | - (void)setUp 14 | { 15 | [super setUp]; 16 | 17 | // Set-up code here. 18 | } 19 | 20 | - (void)tearDown 21 | { 22 | // Tear-down code here. 23 | 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample 28 | { 29 | STFail(@"Unit tests are not implemented yet in TreeTableViewTests"); 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /TreeTableViewTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | --------------------------------------------------------------------------------