├── ExpandableTableView.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── jubinjacob.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── xcshareddata │ └── xcschemes │ │ └── ExpandableTableView.xcscheme └── xcuserdata │ └── jubinjacob.xcuserdatad │ └── xcschemes │ ├── ExpandableTableViewDemo.xcscheme │ └── xcschememanagement.plist ├── ExpandableTableView ├── DisclosureIndicator.swift ├── ExpandableTableView.h ├── ExpandableTableViewCell.swift ├── ExpandableTableViewController.swift └── Info.plist ├── ExpandableTableViewDemo ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── ViewController.swift └── data.json ├── ExpandableTableViewDemoTests ├── ExpandableTableViewDemoTests.swift └── Info.plist ├── ExpandableTableViewDemoUITests ├── ExpandableTableViewDemoUITests.swift └── Info.plist ├── ExpandableTableViewTests ├── ExpandableTableViewTests.swift └── Info.plist └── README.md /ExpandableTableView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7761704F1DA73E3C00CE32EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7761704E1DA73E3C00CE32EE /* AppDelegate.swift */; }; 11 | 776170511DA73E3C00CE32EE /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 776170501DA73E3C00CE32EE /* ViewController.swift */; }; 12 | 776170541DA73E3C00CE32EE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 776170521DA73E3C00CE32EE /* Main.storyboard */; }; 13 | 776170561DA73E3C00CE32EE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 776170551DA73E3C00CE32EE /* Assets.xcassets */; }; 14 | 776170591DA73E3C00CE32EE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 776170571DA73E3C00CE32EE /* LaunchScreen.storyboard */; }; 15 | 776170641DA73E3C00CE32EE /* ExpandableTableViewDemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 776170631DA73E3C00CE32EE /* ExpandableTableViewDemoTests.swift */; }; 16 | 7761706F1DA73E3C00CE32EE /* ExpandableTableViewDemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7761706E1DA73E3C00CE32EE /* ExpandableTableViewDemoUITests.swift */; }; 17 | 7761707B1DA73E6600CE32EE /* data.json in Resources */ = {isa = PBXBuildFile; fileRef = 7761707A1DA73E6600CE32EE /* data.json */; }; 18 | 77D175131D5B9CD300474E55 /* ExpandableTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 77D175121D5B9CD300474E55 /* ExpandableTableView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | 77D1751A1D5B9CD300474E55 /* ExpandableTableView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77D1750F1D5B9CD300474E55 /* ExpandableTableView.framework */; }; 20 | 77D1751F1D5B9CD300474E55 /* ExpandableTableViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77D1751E1D5B9CD300474E55 /* ExpandableTableViewTests.swift */; }; 21 | 77D1752C1D5B9CF500474E55 /* DisclosureIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77D175291D5B9CF500474E55 /* DisclosureIndicator.swift */; }; 22 | 77D1752D1D5B9CF500474E55 /* ExpandableTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77D1752A1D5B9CF500474E55 /* ExpandableTableViewCell.swift */; }; 23 | 77D1752E1D5B9CF500474E55 /* ExpandableTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77D1752B1D5B9CF500474E55 /* ExpandableTableViewController.swift */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXContainerItemProxy section */ 27 | 776170601DA73E3C00CE32EE /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = 77D175061D5B9CD300474E55 /* Project object */; 30 | proxyType = 1; 31 | remoteGlobalIDString = 7761704B1DA73E3C00CE32EE; 32 | remoteInfo = ExpandableTableViewDemo; 33 | }; 34 | 7761706B1DA73E3C00CE32EE /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = 77D175061D5B9CD300474E55 /* Project object */; 37 | proxyType = 1; 38 | remoteGlobalIDString = 7761704B1DA73E3C00CE32EE; 39 | remoteInfo = ExpandableTableViewDemo; 40 | }; 41 | 77D1751B1D5B9CD300474E55 /* PBXContainerItemProxy */ = { 42 | isa = PBXContainerItemProxy; 43 | containerPortal = 77D175061D5B9CD300474E55 /* Project object */; 44 | proxyType = 1; 45 | remoteGlobalIDString = 77D1750E1D5B9CD300474E55; 46 | remoteInfo = ExpandableTableView; 47 | }; 48 | /* End PBXContainerItemProxy section */ 49 | 50 | /* Begin PBXFileReference section */ 51 | 7761704C1DA73E3C00CE32EE /* ExpandableTableViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExpandableTableViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 7761704E1DA73E3C00CE32EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 53 | 776170501DA73E3C00CE32EE /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 54 | 776170531DA73E3C00CE32EE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 55 | 776170551DA73E3C00CE32EE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 56 | 776170581DA73E3C00CE32EE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 57 | 7761705A1DA73E3C00CE32EE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | 7761705F1DA73E3C00CE32EE /* ExpandableTableViewDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExpandableTableViewDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | 776170631DA73E3C00CE32EE /* ExpandableTableViewDemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandableTableViewDemoTests.swift; sourceTree = ""; }; 60 | 776170651DA73E3C00CE32EE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 61 | 7761706A1DA73E3C00CE32EE /* ExpandableTableViewDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExpandableTableViewDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | 7761706E1DA73E3C00CE32EE /* ExpandableTableViewDemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandableTableViewDemoUITests.swift; sourceTree = ""; }; 63 | 776170701DA73E3C00CE32EE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 64 | 7761707A1DA73E6600CE32EE /* data.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = data.json; sourceTree = ""; }; 65 | 77D1750F1D5B9CD300474E55 /* ExpandableTableView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ExpandableTableView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 66 | 77D175121D5B9CD300474E55 /* ExpandableTableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExpandableTableView.h; sourceTree = ""; }; 67 | 77D175141D5B9CD300474E55 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 68 | 77D175191D5B9CD300474E55 /* ExpandableTableViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExpandableTableViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 69 | 77D1751E1D5B9CD300474E55 /* ExpandableTableViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpandableTableViewTests.swift; sourceTree = ""; }; 70 | 77D175201D5B9CD300474E55 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 71 | 77D175291D5B9CF500474E55 /* DisclosureIndicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisclosureIndicator.swift; sourceTree = ""; }; 72 | 77D1752A1D5B9CF500474E55 /* ExpandableTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExpandableTableViewCell.swift; sourceTree = ""; }; 73 | 77D1752B1D5B9CF500474E55 /* ExpandableTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExpandableTableViewController.swift; sourceTree = ""; }; 74 | /* End PBXFileReference section */ 75 | 76 | /* Begin PBXFrameworksBuildPhase section */ 77 | 776170491DA73E3C00CE32EE /* Frameworks */ = { 78 | isa = PBXFrameworksBuildPhase; 79 | buildActionMask = 2147483647; 80 | files = ( 81 | ); 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | 7761705C1DA73E3C00CE32EE /* Frameworks */ = { 85 | isa = PBXFrameworksBuildPhase; 86 | buildActionMask = 2147483647; 87 | files = ( 88 | ); 89 | runOnlyForDeploymentPostprocessing = 0; 90 | }; 91 | 776170671DA73E3C00CE32EE /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | ); 96 | runOnlyForDeploymentPostprocessing = 0; 97 | }; 98 | 77D1750B1D5B9CD300474E55 /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | ); 103 | runOnlyForDeploymentPostprocessing = 0; 104 | }; 105 | 77D175161D5B9CD300474E55 /* Frameworks */ = { 106 | isa = PBXFrameworksBuildPhase; 107 | buildActionMask = 2147483647; 108 | files = ( 109 | 77D1751A1D5B9CD300474E55 /* ExpandableTableView.framework in Frameworks */, 110 | ); 111 | runOnlyForDeploymentPostprocessing = 0; 112 | }; 113 | /* End PBXFrameworksBuildPhase section */ 114 | 115 | /* Begin PBXGroup section */ 116 | 7761704D1DA73E3C00CE32EE /* ExpandableTableViewDemo */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 7761707A1DA73E6600CE32EE /* data.json */, 120 | 7761704E1DA73E3C00CE32EE /* AppDelegate.swift */, 121 | 776170501DA73E3C00CE32EE /* ViewController.swift */, 122 | 776170521DA73E3C00CE32EE /* Main.storyboard */, 123 | 776170551DA73E3C00CE32EE /* Assets.xcassets */, 124 | 776170571DA73E3C00CE32EE /* LaunchScreen.storyboard */, 125 | 7761705A1DA73E3C00CE32EE /* Info.plist */, 126 | ); 127 | path = ExpandableTableViewDemo; 128 | sourceTree = ""; 129 | }; 130 | 776170621DA73E3C00CE32EE /* ExpandableTableViewDemoTests */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 776170631DA73E3C00CE32EE /* ExpandableTableViewDemoTests.swift */, 134 | 776170651DA73E3C00CE32EE /* Info.plist */, 135 | ); 136 | path = ExpandableTableViewDemoTests; 137 | sourceTree = ""; 138 | }; 139 | 7761706D1DA73E3C00CE32EE /* ExpandableTableViewDemoUITests */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | 7761706E1DA73E3C00CE32EE /* ExpandableTableViewDemoUITests.swift */, 143 | 776170701DA73E3C00CE32EE /* Info.plist */, 144 | ); 145 | path = ExpandableTableViewDemoUITests; 146 | sourceTree = ""; 147 | }; 148 | 77D175051D5B9CD300474E55 = { 149 | isa = PBXGroup; 150 | children = ( 151 | 77D175111D5B9CD300474E55 /* ExpandableTableView */, 152 | 77D1751D1D5B9CD300474E55 /* ExpandableTableViewTests */, 153 | 7761704D1DA73E3C00CE32EE /* ExpandableTableViewDemo */, 154 | 776170621DA73E3C00CE32EE /* ExpandableTableViewDemoTests */, 155 | 7761706D1DA73E3C00CE32EE /* ExpandableTableViewDemoUITests */, 156 | 77D175101D5B9CD300474E55 /* Products */, 157 | ); 158 | sourceTree = ""; 159 | }; 160 | 77D175101D5B9CD300474E55 /* Products */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 77D1750F1D5B9CD300474E55 /* ExpandableTableView.framework */, 164 | 77D175191D5B9CD300474E55 /* ExpandableTableViewTests.xctest */, 165 | 7761704C1DA73E3C00CE32EE /* ExpandableTableViewDemo.app */, 166 | 7761705F1DA73E3C00CE32EE /* ExpandableTableViewDemoTests.xctest */, 167 | 7761706A1DA73E3C00CE32EE /* ExpandableTableViewDemoUITests.xctest */, 168 | ); 169 | name = Products; 170 | sourceTree = ""; 171 | }; 172 | 77D175111D5B9CD300474E55 /* ExpandableTableView */ = { 173 | isa = PBXGroup; 174 | children = ( 175 | 77D175291D5B9CF500474E55 /* DisclosureIndicator.swift */, 176 | 77D1752A1D5B9CF500474E55 /* ExpandableTableViewCell.swift */, 177 | 77D1752B1D5B9CF500474E55 /* ExpandableTableViewController.swift */, 178 | 77D175121D5B9CD300474E55 /* ExpandableTableView.h */, 179 | 77D175141D5B9CD300474E55 /* Info.plist */, 180 | ); 181 | path = ExpandableTableView; 182 | sourceTree = ""; 183 | }; 184 | 77D1751D1D5B9CD300474E55 /* ExpandableTableViewTests */ = { 185 | isa = PBXGroup; 186 | children = ( 187 | 77D1751E1D5B9CD300474E55 /* ExpandableTableViewTests.swift */, 188 | 77D175201D5B9CD300474E55 /* Info.plist */, 189 | ); 190 | path = ExpandableTableViewTests; 191 | sourceTree = ""; 192 | }; 193 | /* End PBXGroup section */ 194 | 195 | /* Begin PBXHeadersBuildPhase section */ 196 | 77D1750C1D5B9CD300474E55 /* Headers */ = { 197 | isa = PBXHeadersBuildPhase; 198 | buildActionMask = 2147483647; 199 | files = ( 200 | 77D175131D5B9CD300474E55 /* ExpandableTableView.h in Headers */, 201 | ); 202 | runOnlyForDeploymentPostprocessing = 0; 203 | }; 204 | /* End PBXHeadersBuildPhase section */ 205 | 206 | /* Begin PBXNativeTarget section */ 207 | 7761704B1DA73E3C00CE32EE /* ExpandableTableViewDemo */ = { 208 | isa = PBXNativeTarget; 209 | buildConfigurationList = 776170771DA73E3C00CE32EE /* Build configuration list for PBXNativeTarget "ExpandableTableViewDemo" */; 210 | buildPhases = ( 211 | 776170481DA73E3C00CE32EE /* Sources */, 212 | 776170491DA73E3C00CE32EE /* Frameworks */, 213 | 7761704A1DA73E3C00CE32EE /* Resources */, 214 | ); 215 | buildRules = ( 216 | ); 217 | dependencies = ( 218 | ); 219 | name = ExpandableTableViewDemo; 220 | productName = ExpandableTableViewDemo; 221 | productReference = 7761704C1DA73E3C00CE32EE /* ExpandableTableViewDemo.app */; 222 | productType = "com.apple.product-type.application"; 223 | }; 224 | 7761705E1DA73E3C00CE32EE /* ExpandableTableViewDemoTests */ = { 225 | isa = PBXNativeTarget; 226 | buildConfigurationList = 776170781DA73E3C00CE32EE /* Build configuration list for PBXNativeTarget "ExpandableTableViewDemoTests" */; 227 | buildPhases = ( 228 | 7761705B1DA73E3C00CE32EE /* Sources */, 229 | 7761705C1DA73E3C00CE32EE /* Frameworks */, 230 | 7761705D1DA73E3C00CE32EE /* Resources */, 231 | ); 232 | buildRules = ( 233 | ); 234 | dependencies = ( 235 | 776170611DA73E3C00CE32EE /* PBXTargetDependency */, 236 | ); 237 | name = ExpandableTableViewDemoTests; 238 | productName = ExpandableTableViewDemoTests; 239 | productReference = 7761705F1DA73E3C00CE32EE /* ExpandableTableViewDemoTests.xctest */; 240 | productType = "com.apple.product-type.bundle.unit-test"; 241 | }; 242 | 776170691DA73E3C00CE32EE /* ExpandableTableViewDemoUITests */ = { 243 | isa = PBXNativeTarget; 244 | buildConfigurationList = 776170791DA73E3C00CE32EE /* Build configuration list for PBXNativeTarget "ExpandableTableViewDemoUITests" */; 245 | buildPhases = ( 246 | 776170661DA73E3C00CE32EE /* Sources */, 247 | 776170671DA73E3C00CE32EE /* Frameworks */, 248 | 776170681DA73E3C00CE32EE /* Resources */, 249 | ); 250 | buildRules = ( 251 | ); 252 | dependencies = ( 253 | 7761706C1DA73E3C00CE32EE /* PBXTargetDependency */, 254 | ); 255 | name = ExpandableTableViewDemoUITests; 256 | productName = ExpandableTableViewDemoUITests; 257 | productReference = 7761706A1DA73E3C00CE32EE /* ExpandableTableViewDemoUITests.xctest */; 258 | productType = "com.apple.product-type.bundle.ui-testing"; 259 | }; 260 | 77D1750E1D5B9CD300474E55 /* ExpandableTableView */ = { 261 | isa = PBXNativeTarget; 262 | buildConfigurationList = 77D175231D5B9CD300474E55 /* Build configuration list for PBXNativeTarget "ExpandableTableView" */; 263 | buildPhases = ( 264 | 77D1750A1D5B9CD300474E55 /* Sources */, 265 | 77D1750B1D5B9CD300474E55 /* Frameworks */, 266 | 77D1750C1D5B9CD300474E55 /* Headers */, 267 | 77D1750D1D5B9CD300474E55 /* Resources */, 268 | ); 269 | buildRules = ( 270 | ); 271 | dependencies = ( 272 | ); 273 | name = ExpandableTableView; 274 | productName = ExpandableTableView; 275 | productReference = 77D1750F1D5B9CD300474E55 /* ExpandableTableView.framework */; 276 | productType = "com.apple.product-type.framework"; 277 | }; 278 | 77D175181D5B9CD300474E55 /* ExpandableTableViewTests */ = { 279 | isa = PBXNativeTarget; 280 | buildConfigurationList = 77D175261D5B9CD300474E55 /* Build configuration list for PBXNativeTarget "ExpandableTableViewTests" */; 281 | buildPhases = ( 282 | 77D175151D5B9CD300474E55 /* Sources */, 283 | 77D175161D5B9CD300474E55 /* Frameworks */, 284 | 77D175171D5B9CD300474E55 /* Resources */, 285 | ); 286 | buildRules = ( 287 | ); 288 | dependencies = ( 289 | 77D1751C1D5B9CD300474E55 /* PBXTargetDependency */, 290 | ); 291 | name = ExpandableTableViewTests; 292 | productName = ExpandableTableViewTests; 293 | productReference = 77D175191D5B9CD300474E55 /* ExpandableTableViewTests.xctest */; 294 | productType = "com.apple.product-type.bundle.unit-test"; 295 | }; 296 | /* End PBXNativeTarget section */ 297 | 298 | /* Begin PBXProject section */ 299 | 77D175061D5B9CD300474E55 /* Project object */ = { 300 | isa = PBXProject; 301 | attributes = { 302 | LastSwiftUpdateCheck = 0800; 303 | LastUpgradeCheck = 0800; 304 | ORGANIZATIONNAME = J; 305 | TargetAttributes = { 306 | 7761704B1DA73E3C00CE32EE = { 307 | CreatedOnToolsVersion = 8.0; 308 | ProvisioningStyle = Automatic; 309 | }; 310 | 7761705E1DA73E3C00CE32EE = { 311 | CreatedOnToolsVersion = 8.0; 312 | ProvisioningStyle = Automatic; 313 | TestTargetID = 7761704B1DA73E3C00CE32EE; 314 | }; 315 | 776170691DA73E3C00CE32EE = { 316 | CreatedOnToolsVersion = 8.0; 317 | ProvisioningStyle = Automatic; 318 | TestTargetID = 7761704B1DA73E3C00CE32EE; 319 | }; 320 | 77D1750E1D5B9CD300474E55 = { 321 | CreatedOnToolsVersion = 7.3.1; 322 | LastSwiftMigration = 0800; 323 | }; 324 | 77D175181D5B9CD300474E55 = { 325 | CreatedOnToolsVersion = 7.3.1; 326 | LastSwiftMigration = 0800; 327 | }; 328 | }; 329 | }; 330 | buildConfigurationList = 77D175091D5B9CD300474E55 /* Build configuration list for PBXProject "ExpandableTableView" */; 331 | compatibilityVersion = "Xcode 3.2"; 332 | developmentRegion = English; 333 | hasScannedForEncodings = 0; 334 | knownRegions = ( 335 | en, 336 | Base, 337 | ); 338 | mainGroup = 77D175051D5B9CD300474E55; 339 | productRefGroup = 77D175101D5B9CD300474E55 /* Products */; 340 | projectDirPath = ""; 341 | projectRoot = ""; 342 | targets = ( 343 | 77D1750E1D5B9CD300474E55 /* ExpandableTableView */, 344 | 77D175181D5B9CD300474E55 /* ExpandableTableViewTests */, 345 | 7761704B1DA73E3C00CE32EE /* ExpandableTableViewDemo */, 346 | 7761705E1DA73E3C00CE32EE /* ExpandableTableViewDemoTests */, 347 | 776170691DA73E3C00CE32EE /* ExpandableTableViewDemoUITests */, 348 | ); 349 | }; 350 | /* End PBXProject section */ 351 | 352 | /* Begin PBXResourcesBuildPhase section */ 353 | 7761704A1DA73E3C00CE32EE /* Resources */ = { 354 | isa = PBXResourcesBuildPhase; 355 | buildActionMask = 2147483647; 356 | files = ( 357 | 776170591DA73E3C00CE32EE /* LaunchScreen.storyboard in Resources */, 358 | 776170561DA73E3C00CE32EE /* Assets.xcassets in Resources */, 359 | 776170541DA73E3C00CE32EE /* Main.storyboard in Resources */, 360 | 7761707B1DA73E6600CE32EE /* data.json in Resources */, 361 | ); 362 | runOnlyForDeploymentPostprocessing = 0; 363 | }; 364 | 7761705D1DA73E3C00CE32EE /* Resources */ = { 365 | isa = PBXResourcesBuildPhase; 366 | buildActionMask = 2147483647; 367 | files = ( 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | }; 371 | 776170681DA73E3C00CE32EE /* Resources */ = { 372 | isa = PBXResourcesBuildPhase; 373 | buildActionMask = 2147483647; 374 | files = ( 375 | ); 376 | runOnlyForDeploymentPostprocessing = 0; 377 | }; 378 | 77D1750D1D5B9CD300474E55 /* Resources */ = { 379 | isa = PBXResourcesBuildPhase; 380 | buildActionMask = 2147483647; 381 | files = ( 382 | ); 383 | runOnlyForDeploymentPostprocessing = 0; 384 | }; 385 | 77D175171D5B9CD300474E55 /* Resources */ = { 386 | isa = PBXResourcesBuildPhase; 387 | buildActionMask = 2147483647; 388 | files = ( 389 | ); 390 | runOnlyForDeploymentPostprocessing = 0; 391 | }; 392 | /* End PBXResourcesBuildPhase section */ 393 | 394 | /* Begin PBXSourcesBuildPhase section */ 395 | 776170481DA73E3C00CE32EE /* Sources */ = { 396 | isa = PBXSourcesBuildPhase; 397 | buildActionMask = 2147483647; 398 | files = ( 399 | 776170511DA73E3C00CE32EE /* ViewController.swift in Sources */, 400 | 7761704F1DA73E3C00CE32EE /* AppDelegate.swift in Sources */, 401 | ); 402 | runOnlyForDeploymentPostprocessing = 0; 403 | }; 404 | 7761705B1DA73E3C00CE32EE /* Sources */ = { 405 | isa = PBXSourcesBuildPhase; 406 | buildActionMask = 2147483647; 407 | files = ( 408 | 776170641DA73E3C00CE32EE /* ExpandableTableViewDemoTests.swift in Sources */, 409 | ); 410 | runOnlyForDeploymentPostprocessing = 0; 411 | }; 412 | 776170661DA73E3C00CE32EE /* Sources */ = { 413 | isa = PBXSourcesBuildPhase; 414 | buildActionMask = 2147483647; 415 | files = ( 416 | 7761706F1DA73E3C00CE32EE /* ExpandableTableViewDemoUITests.swift in Sources */, 417 | ); 418 | runOnlyForDeploymentPostprocessing = 0; 419 | }; 420 | 77D1750A1D5B9CD300474E55 /* Sources */ = { 421 | isa = PBXSourcesBuildPhase; 422 | buildActionMask = 2147483647; 423 | files = ( 424 | 77D1752C1D5B9CF500474E55 /* DisclosureIndicator.swift in Sources */, 425 | 77D1752E1D5B9CF500474E55 /* ExpandableTableViewController.swift in Sources */, 426 | 77D1752D1D5B9CF500474E55 /* ExpandableTableViewCell.swift in Sources */, 427 | ); 428 | runOnlyForDeploymentPostprocessing = 0; 429 | }; 430 | 77D175151D5B9CD300474E55 /* Sources */ = { 431 | isa = PBXSourcesBuildPhase; 432 | buildActionMask = 2147483647; 433 | files = ( 434 | 77D1751F1D5B9CD300474E55 /* ExpandableTableViewTests.swift in Sources */, 435 | ); 436 | runOnlyForDeploymentPostprocessing = 0; 437 | }; 438 | /* End PBXSourcesBuildPhase section */ 439 | 440 | /* Begin PBXTargetDependency section */ 441 | 776170611DA73E3C00CE32EE /* PBXTargetDependency */ = { 442 | isa = PBXTargetDependency; 443 | target = 7761704B1DA73E3C00CE32EE /* ExpandableTableViewDemo */; 444 | targetProxy = 776170601DA73E3C00CE32EE /* PBXContainerItemProxy */; 445 | }; 446 | 7761706C1DA73E3C00CE32EE /* PBXTargetDependency */ = { 447 | isa = PBXTargetDependency; 448 | target = 7761704B1DA73E3C00CE32EE /* ExpandableTableViewDemo */; 449 | targetProxy = 7761706B1DA73E3C00CE32EE /* PBXContainerItemProxy */; 450 | }; 451 | 77D1751C1D5B9CD300474E55 /* PBXTargetDependency */ = { 452 | isa = PBXTargetDependency; 453 | target = 77D1750E1D5B9CD300474E55 /* ExpandableTableView */; 454 | targetProxy = 77D1751B1D5B9CD300474E55 /* PBXContainerItemProxy */; 455 | }; 456 | /* End PBXTargetDependency section */ 457 | 458 | /* Begin PBXVariantGroup section */ 459 | 776170521DA73E3C00CE32EE /* Main.storyboard */ = { 460 | isa = PBXVariantGroup; 461 | children = ( 462 | 776170531DA73E3C00CE32EE /* Base */, 463 | ); 464 | name = Main.storyboard; 465 | sourceTree = ""; 466 | }; 467 | 776170571DA73E3C00CE32EE /* LaunchScreen.storyboard */ = { 468 | isa = PBXVariantGroup; 469 | children = ( 470 | 776170581DA73E3C00CE32EE /* Base */, 471 | ); 472 | name = LaunchScreen.storyboard; 473 | sourceTree = ""; 474 | }; 475 | /* End PBXVariantGroup section */ 476 | 477 | /* Begin XCBuildConfiguration section */ 478 | 776170711DA73E3C00CE32EE /* Debug */ = { 479 | isa = XCBuildConfiguration; 480 | buildSettings = { 481 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 482 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 483 | CLANG_WARN_INFINITE_RECURSION = YES; 484 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 485 | INFOPLIST_FILE = ExpandableTableViewDemo/Info.plist; 486 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 487 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 488 | PRODUCT_BUNDLE_IDENTIFIER = J.ExpandableTableViewDemo; 489 | PRODUCT_NAME = "$(TARGET_NAME)"; 490 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 491 | SWIFT_VERSION = 3.0; 492 | }; 493 | name = Debug; 494 | }; 495 | 776170721DA73E3C00CE32EE /* Release */ = { 496 | isa = XCBuildConfiguration; 497 | buildSettings = { 498 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 499 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 500 | CLANG_WARN_INFINITE_RECURSION = YES; 501 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 502 | INFOPLIST_FILE = ExpandableTableViewDemo/Info.plist; 503 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 504 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 505 | PRODUCT_BUNDLE_IDENTIFIER = J.ExpandableTableViewDemo; 506 | PRODUCT_NAME = "$(TARGET_NAME)"; 507 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 508 | SWIFT_VERSION = 3.0; 509 | }; 510 | name = Release; 511 | }; 512 | 776170731DA73E3C00CE32EE /* Debug */ = { 513 | isa = XCBuildConfiguration; 514 | buildSettings = { 515 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 516 | BUNDLE_LOADER = "$(TEST_HOST)"; 517 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 518 | CLANG_WARN_INFINITE_RECURSION = YES; 519 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 520 | INFOPLIST_FILE = ExpandableTableViewDemoTests/Info.plist; 521 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 522 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 523 | PRODUCT_BUNDLE_IDENTIFIER = J.ExpandableTableViewDemoTests; 524 | PRODUCT_NAME = "$(TARGET_NAME)"; 525 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 526 | SWIFT_VERSION = 3.0; 527 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ExpandableTableViewDemo.app/ExpandableTableViewDemo"; 528 | }; 529 | name = Debug; 530 | }; 531 | 776170741DA73E3C00CE32EE /* Release */ = { 532 | isa = XCBuildConfiguration; 533 | buildSettings = { 534 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 535 | BUNDLE_LOADER = "$(TEST_HOST)"; 536 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 537 | CLANG_WARN_INFINITE_RECURSION = YES; 538 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 539 | INFOPLIST_FILE = ExpandableTableViewDemoTests/Info.plist; 540 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 541 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 542 | PRODUCT_BUNDLE_IDENTIFIER = J.ExpandableTableViewDemoTests; 543 | PRODUCT_NAME = "$(TARGET_NAME)"; 544 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 545 | SWIFT_VERSION = 3.0; 546 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ExpandableTableViewDemo.app/ExpandableTableViewDemo"; 547 | }; 548 | name = Release; 549 | }; 550 | 776170751DA73E3C00CE32EE /* Debug */ = { 551 | isa = XCBuildConfiguration; 552 | buildSettings = { 553 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 554 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 555 | CLANG_WARN_INFINITE_RECURSION = YES; 556 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 557 | INFOPLIST_FILE = ExpandableTableViewDemoUITests/Info.plist; 558 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 559 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 560 | PRODUCT_BUNDLE_IDENTIFIER = J.ExpandableTableViewDemoUITests; 561 | PRODUCT_NAME = "$(TARGET_NAME)"; 562 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 563 | SWIFT_VERSION = 3.0; 564 | TEST_TARGET_NAME = ExpandableTableViewDemo; 565 | }; 566 | name = Debug; 567 | }; 568 | 776170761DA73E3C00CE32EE /* Release */ = { 569 | isa = XCBuildConfiguration; 570 | buildSettings = { 571 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 572 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 573 | CLANG_WARN_INFINITE_RECURSION = YES; 574 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 575 | INFOPLIST_FILE = ExpandableTableViewDemoUITests/Info.plist; 576 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 577 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 578 | PRODUCT_BUNDLE_IDENTIFIER = J.ExpandableTableViewDemoUITests; 579 | PRODUCT_NAME = "$(TARGET_NAME)"; 580 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 581 | SWIFT_VERSION = 3.0; 582 | TEST_TARGET_NAME = ExpandableTableViewDemo; 583 | }; 584 | name = Release; 585 | }; 586 | 77D175211D5B9CD300474E55 /* Debug */ = { 587 | isa = XCBuildConfiguration; 588 | buildSettings = { 589 | ALWAYS_SEARCH_USER_PATHS = NO; 590 | CLANG_ANALYZER_NONNULL = YES; 591 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 592 | CLANG_CXX_LIBRARY = "libc++"; 593 | CLANG_ENABLE_MODULES = YES; 594 | CLANG_ENABLE_OBJC_ARC = YES; 595 | CLANG_WARN_BOOL_CONVERSION = YES; 596 | CLANG_WARN_CONSTANT_CONVERSION = YES; 597 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 598 | CLANG_WARN_EMPTY_BODY = YES; 599 | CLANG_WARN_ENUM_CONVERSION = YES; 600 | CLANG_WARN_INFINITE_RECURSION = YES; 601 | CLANG_WARN_INT_CONVERSION = YES; 602 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 603 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 604 | CLANG_WARN_UNREACHABLE_CODE = YES; 605 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 606 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 607 | COPY_PHASE_STRIP = NO; 608 | CURRENT_PROJECT_VERSION = 1; 609 | DEBUG_INFORMATION_FORMAT = dwarf; 610 | ENABLE_STRICT_OBJC_MSGSEND = YES; 611 | ENABLE_TESTABILITY = YES; 612 | GCC_C_LANGUAGE_STANDARD = gnu99; 613 | GCC_DYNAMIC_NO_PIC = NO; 614 | GCC_NO_COMMON_BLOCKS = YES; 615 | GCC_OPTIMIZATION_LEVEL = 0; 616 | GCC_PREPROCESSOR_DEFINITIONS = ( 617 | "DEBUG=1", 618 | "$(inherited)", 619 | ); 620 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 621 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 622 | GCC_WARN_UNDECLARED_SELECTOR = YES; 623 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 624 | GCC_WARN_UNUSED_FUNCTION = YES; 625 | GCC_WARN_UNUSED_VARIABLE = YES; 626 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 627 | MTL_ENABLE_DEBUG_INFO = YES; 628 | ONLY_ACTIVE_ARCH = YES; 629 | SDKROOT = iphoneos; 630 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 631 | TARGETED_DEVICE_FAMILY = "1,2"; 632 | VERSIONING_SYSTEM = "apple-generic"; 633 | VERSION_INFO_PREFIX = ""; 634 | }; 635 | name = Debug; 636 | }; 637 | 77D175221D5B9CD300474E55 /* Release */ = { 638 | isa = XCBuildConfiguration; 639 | buildSettings = { 640 | ALWAYS_SEARCH_USER_PATHS = NO; 641 | CLANG_ANALYZER_NONNULL = YES; 642 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 643 | CLANG_CXX_LIBRARY = "libc++"; 644 | CLANG_ENABLE_MODULES = YES; 645 | CLANG_ENABLE_OBJC_ARC = YES; 646 | CLANG_WARN_BOOL_CONVERSION = YES; 647 | CLANG_WARN_CONSTANT_CONVERSION = YES; 648 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 649 | CLANG_WARN_EMPTY_BODY = YES; 650 | CLANG_WARN_ENUM_CONVERSION = YES; 651 | CLANG_WARN_INFINITE_RECURSION = YES; 652 | CLANG_WARN_INT_CONVERSION = YES; 653 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 654 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 655 | CLANG_WARN_UNREACHABLE_CODE = YES; 656 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 657 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 658 | COPY_PHASE_STRIP = NO; 659 | CURRENT_PROJECT_VERSION = 1; 660 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 661 | ENABLE_NS_ASSERTIONS = NO; 662 | ENABLE_STRICT_OBJC_MSGSEND = YES; 663 | GCC_C_LANGUAGE_STANDARD = gnu99; 664 | GCC_NO_COMMON_BLOCKS = YES; 665 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 666 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 667 | GCC_WARN_UNDECLARED_SELECTOR = YES; 668 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 669 | GCC_WARN_UNUSED_FUNCTION = YES; 670 | GCC_WARN_UNUSED_VARIABLE = YES; 671 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 672 | MTL_ENABLE_DEBUG_INFO = NO; 673 | SDKROOT = iphoneos; 674 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 675 | TARGETED_DEVICE_FAMILY = "1,2"; 676 | VALIDATE_PRODUCT = YES; 677 | VERSIONING_SYSTEM = "apple-generic"; 678 | VERSION_INFO_PREFIX = ""; 679 | }; 680 | name = Release; 681 | }; 682 | 77D175241D5B9CD300474E55 /* Debug */ = { 683 | isa = XCBuildConfiguration; 684 | buildSettings = { 685 | CLANG_ENABLE_MODULES = YES; 686 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 687 | DEFINES_MODULE = YES; 688 | DYLIB_COMPATIBILITY_VERSION = 1; 689 | DYLIB_CURRENT_VERSION = 1; 690 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 691 | INFOPLIST_FILE = ExpandableTableView/Info.plist; 692 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 693 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 694 | PRODUCT_BUNDLE_IDENTIFIER = J.ExpandableTableView; 695 | PRODUCT_NAME = "$(TARGET_NAME)"; 696 | SKIP_INSTALL = YES; 697 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 698 | SWIFT_VERSION = 3.0; 699 | }; 700 | name = Debug; 701 | }; 702 | 77D175251D5B9CD300474E55 /* Release */ = { 703 | isa = XCBuildConfiguration; 704 | buildSettings = { 705 | CLANG_ENABLE_MODULES = YES; 706 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 707 | DEFINES_MODULE = YES; 708 | DYLIB_COMPATIBILITY_VERSION = 1; 709 | DYLIB_CURRENT_VERSION = 1; 710 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 711 | INFOPLIST_FILE = ExpandableTableView/Info.plist; 712 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 713 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 714 | PRODUCT_BUNDLE_IDENTIFIER = J.ExpandableTableView; 715 | PRODUCT_NAME = "$(TARGET_NAME)"; 716 | SKIP_INSTALL = YES; 717 | SWIFT_VERSION = 3.0; 718 | }; 719 | name = Release; 720 | }; 721 | 77D175271D5B9CD300474E55 /* Debug */ = { 722 | isa = XCBuildConfiguration; 723 | buildSettings = { 724 | INFOPLIST_FILE = ExpandableTableViewTests/Info.plist; 725 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 726 | PRODUCT_BUNDLE_IDENTIFIER = J.ExpandableTableViewTests; 727 | PRODUCT_NAME = "$(TARGET_NAME)"; 728 | SWIFT_VERSION = 3.0; 729 | }; 730 | name = Debug; 731 | }; 732 | 77D175281D5B9CD300474E55 /* Release */ = { 733 | isa = XCBuildConfiguration; 734 | buildSettings = { 735 | INFOPLIST_FILE = ExpandableTableViewTests/Info.plist; 736 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 737 | PRODUCT_BUNDLE_IDENTIFIER = J.ExpandableTableViewTests; 738 | PRODUCT_NAME = "$(TARGET_NAME)"; 739 | SWIFT_VERSION = 3.0; 740 | }; 741 | name = Release; 742 | }; 743 | /* End XCBuildConfiguration section */ 744 | 745 | /* Begin XCConfigurationList section */ 746 | 776170771DA73E3C00CE32EE /* Build configuration list for PBXNativeTarget "ExpandableTableViewDemo" */ = { 747 | isa = XCConfigurationList; 748 | buildConfigurations = ( 749 | 776170711DA73E3C00CE32EE /* Debug */, 750 | 776170721DA73E3C00CE32EE /* Release */, 751 | ); 752 | defaultConfigurationIsVisible = 0; 753 | }; 754 | 776170781DA73E3C00CE32EE /* Build configuration list for PBXNativeTarget "ExpandableTableViewDemoTests" */ = { 755 | isa = XCConfigurationList; 756 | buildConfigurations = ( 757 | 776170731DA73E3C00CE32EE /* Debug */, 758 | 776170741DA73E3C00CE32EE /* Release */, 759 | ); 760 | defaultConfigurationIsVisible = 0; 761 | }; 762 | 776170791DA73E3C00CE32EE /* Build configuration list for PBXNativeTarget "ExpandableTableViewDemoUITests" */ = { 763 | isa = XCConfigurationList; 764 | buildConfigurations = ( 765 | 776170751DA73E3C00CE32EE /* Debug */, 766 | 776170761DA73E3C00CE32EE /* Release */, 767 | ); 768 | defaultConfigurationIsVisible = 0; 769 | }; 770 | 77D175091D5B9CD300474E55 /* Build configuration list for PBXProject "ExpandableTableView" */ = { 771 | isa = XCConfigurationList; 772 | buildConfigurations = ( 773 | 77D175211D5B9CD300474E55 /* Debug */, 774 | 77D175221D5B9CD300474E55 /* Release */, 775 | ); 776 | defaultConfigurationIsVisible = 0; 777 | defaultConfigurationName = Release; 778 | }; 779 | 77D175231D5B9CD300474E55 /* Build configuration list for PBXNativeTarget "ExpandableTableView" */ = { 780 | isa = XCConfigurationList; 781 | buildConfigurations = ( 782 | 77D175241D5B9CD300474E55 /* Debug */, 783 | 77D175251D5B9CD300474E55 /* Release */, 784 | ); 785 | defaultConfigurationIsVisible = 0; 786 | defaultConfigurationName = Release; 787 | }; 788 | 77D175261D5B9CD300474E55 /* Build configuration list for PBXNativeTarget "ExpandableTableViewTests" */ = { 789 | isa = XCConfigurationList; 790 | buildConfigurations = ( 791 | 77D175271D5B9CD300474E55 /* Debug */, 792 | 77D175281D5B9CD300474E55 /* Release */, 793 | ); 794 | defaultConfigurationIsVisible = 0; 795 | defaultConfigurationName = Release; 796 | }; 797 | /* End XCConfigurationList section */ 798 | }; 799 | rootObject = 77D175061D5B9CD300474E55 /* Project object */; 800 | } 801 | -------------------------------------------------------------------------------- /ExpandableTableView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ExpandableTableView.xcodeproj/project.xcworkspace/xcuserdata/jubinjacob.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jubinjacob19/ExpandableTableView/8c8e60e564b1fb23488e62b2650c92f153926a61/ExpandableTableView.xcodeproj/project.xcworkspace/xcuserdata/jubinjacob.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ExpandableTableView.xcodeproj/xcshareddata/xcschemes/ExpandableTableView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /ExpandableTableView.xcodeproj/xcuserdata/jubinjacob.xcuserdatad/xcschemes/ExpandableTableViewDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /ExpandableTableView.xcodeproj/xcuserdata/jubinjacob.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ExpandableTableView.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | ExpandableTableViewDemo.xcscheme 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 7761704B1DA73E3C00CE32EE 21 | 22 | primary 23 | 24 | 25 | 7761705E1DA73E3C00CE32EE 26 | 27 | primary 28 | 29 | 30 | 776170691DA73E3C00CE32EE 31 | 32 | primary 33 | 34 | 35 | 77D1750E1D5B9CD300474E55 36 | 37 | primary 38 | 39 | 40 | 77D175181D5B9CD300474E55 41 | 42 | primary 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ExpandableTableView/DisclosureIndicator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DisclosureIndicator.swift 3 | // ExpandableTableView 4 | // 5 | // Created by Jubin Jacob on 22/01/16. 6 | // Copyright © 2016 J. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum ArrowDirection : Int { 12 | case top 13 | case bottom 14 | } 15 | 16 | class DisclosureIndicator: UIView { 17 | 18 | convenience init(direction:ArrowDirection) { 19 | self.init(frame:CGRect.zero) 20 | self.direction = direction 21 | self.backgroundColor = UIColor.clear 22 | } 23 | 24 | override init(frame: CGRect) { 25 | super.init(frame: frame) 26 | } 27 | 28 | required init?(coder aDecoder: NSCoder) { 29 | fatalError("init(coder:) has not been implemented") 30 | } 31 | 32 | 33 | var direction : ArrowDirection? 34 | 35 | override func draw(_ rect: CGRect) { 36 | let width = rect.size.width 37 | let padding : CGFloat = 15 38 | let path = UIBezierPath() 39 | path.lineJoinStyle = CGLineJoin.round 40 | path.lineWidth = 2.0 41 | 42 | if(self.direction == ArrowDirection.bottom) { 43 | let origin = CGPoint(x: padding/2, y: padding/2) 44 | path.move(to: origin) 45 | path.addLine(to: CGPoint(x: width/2, y: width-padding)) 46 | path.addLine(to: CGPoint(x: width-(padding/2), y: padding/2)) 47 | UIColor.darkGray.setStroke() 48 | path.stroke() 49 | } else { 50 | let origin = CGPoint(x: padding/2, y: width - padding) 51 | path.move(to: origin) 52 | path.addLine(to: CGPoint(x: width/2, y: padding/2)) 53 | path.addLine(to: CGPoint(x: width-(padding/2),y: width - padding)) 54 | UIColor.darkGray.setStroke() 55 | path.stroke() 56 | } 57 | 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /ExpandableTableView/ExpandableTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ExpandableTableView.h 3 | // ExpandableTableView 4 | // 5 | // Created by Jubin Jacob on 10/08/16. 6 | // Copyright © 2016 J. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for ExpandableTableView. 12 | FOUNDATION_EXPORT double ExpandableTableViewVersionNumber; 13 | 14 | //! Project version string for ExpandableTableView. 15 | FOUNDATION_EXPORT const unsigned char ExpandableTableViewVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /ExpandableTableView/ExpandableTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExpandableTableViewCell.swift 3 | // ExpandableTableView 4 | // 5 | // Created by Jubin Jacob on 22/01/16. 6 | // Copyright © 2016 J. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public struct ItemModel { 12 | public let question : String 13 | public let answer : String 14 | public init(question:String, answer:String) { 15 | self.question = question 16 | self.answer = answer 17 | } 18 | } 19 | 20 | class ExpandableTableViewCell: UITableViewCell { 21 | 22 | 23 | fileprivate lazy var questionLabel : UILabel = { 24 | let lbl = UILabel() 25 | lbl.translatesAutoresizingMaskIntoConstraints = false 26 | lbl.numberOfLines = 3 27 | lbl.textColor = UIColor.black 28 | lbl.font = UIFont.systemFont(ofSize: 13.0) 29 | return lbl 30 | } () 31 | 32 | fileprivate lazy var answerLabel : UILabel = { 33 | let lbl = UILabel() 34 | lbl.translatesAutoresizingMaskIntoConstraints = false 35 | lbl.numberOfLines = 0 36 | lbl.textColor = UIColor.darkGray 37 | lbl.font = UIFont.systemFont(ofSize: 11.0) 38 | return lbl 39 | } () 40 | 41 | fileprivate lazy var topSpacerView : UIView = { 42 | let view = UIView() 43 | view.translatesAutoresizingMaskIntoConstraints = false 44 | return view 45 | } () 46 | 47 | fileprivate lazy var spacerView : UIView = { 48 | let view = UIView() 49 | view.translatesAutoresizingMaskIntoConstraints = false 50 | return view 51 | } () 52 | 53 | fileprivate lazy var bottomSpacerView : UIView = { 54 | let view = UIView() 55 | view.translatesAutoresizingMaskIntoConstraints = false 56 | return view 57 | } () 58 | 59 | lazy var disclosureView : DisclosureIndicator = { 60 | let view = DisclosureIndicator(direction: ArrowDirection.bottom) 61 | view.translatesAutoresizingMaskIntoConstraints = false 62 | return view 63 | } () 64 | 65 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 66 | super.init(style: style, reuseIdentifier: reuseIdentifier) 67 | self.addSubviews() 68 | } 69 | 70 | required init?(coder aDecoder: NSCoder) { 71 | fatalError("init(coder:) has not been implemented") 72 | } 73 | 74 | fileprivate func addSubviews() { 75 | self.contentView.addSubview(self.topSpacerView) 76 | self.contentView.addSubview(self.questionLabel) 77 | self.contentView.addSubview(self.disclosureView) 78 | self.contentView.addSubview(self.spacerView) 79 | self.contentView.addSubview(self.answerLabel) 80 | self.contentView.addSubview(self.bottomSpacerView) 81 | self.setLayoutConstraints() 82 | } 83 | 84 | fileprivate func setLayoutConstraints() { 85 | let views = ["qn":self.questionLabel,"ans":self.answerLabel,"view":self.spacerView,"top":self.topSpacerView,"btm":self.bottomSpacerView,"btn":self.disclosureView] 86 | let metrics = ["padding":10] 87 | self.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(padding)-[qn]-(padding)-[btn(==32)]-(padding)-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: metrics, views: views)) 88 | self.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(padding)-[ans]-(padding)-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: metrics, views: views)) 89 | self.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: metrics, views: views)) 90 | self.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[top]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: metrics, views: views)) 91 | self.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[btm]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: metrics, views: views)) 92 | self.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[top(==padding)][qn][view(==padding)][ans][btm(==padding)]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: metrics, views: views)) 93 | self.contentView.addConstraint(NSLayoutConstraint(item: self.disclosureView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 32)) 94 | self.contentView.addConstraint(NSLayoutConstraint(item: self.disclosureView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: self.questionLabel, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0)) 95 | } 96 | 97 | func setCellContent(_ item : ItemModel, isExpanded : Bool) { 98 | self.questionLabel.text = item.question 99 | self.answerLabel.text = isExpanded ? item.answer : "" 100 | self.disclosureView.direction = isExpanded ? ArrowDirection.top : ArrowDirection.bottom 101 | self.disclosureView.setNeedsDisplay() 102 | 103 | } 104 | 105 | func cellContentHeight()->CGFloat { 106 | return self.questionLabel.intrinsicContentSize.height + self.answerLabel.intrinsicContentSize.height + 35.0 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /ExpandableTableView/ExpandableTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExpandableTableViewController.swift 3 | // CollapsibleTableView 4 | // 5 | // Created by Jubin Jacob on 10/08/16. 6 | // Copyright © 2016 J. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class ExpandableTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 12 | 13 | 14 | fileprivate lazy var sizingCell : ExpandableTableViewCell = { 15 | guard let cell = self.tableView.dequeueReusableCell(withIdentifier:"CellID") as? ExpandableTableViewCell else{ 16 | preconditionFailure("reusable cell not found") 17 | } 18 | return cell 19 | } () 20 | 21 | fileprivate lazy var tableView : UITableView = { 22 | let tbl = UITableView(frame: CGRect.zero) 23 | tbl.separatorColor = UIColor.lightGray 24 | tbl.translatesAutoresizingMaskIntoConstraints = false 25 | tbl.dataSource = self 26 | tbl.delegate = self 27 | tbl.register(ExpandableTableViewCell.self, forCellReuseIdentifier: "CellID") 28 | return tbl 29 | } () 30 | 31 | open var dataSourceArray = [ItemModel]() 32 | 33 | var expandedIndexPaths : [IndexPath] = [IndexPath]() 34 | 35 | public convenience init(faqs: [ItemModel]) { 36 | self.init(nibName: nil, bundle: nil) 37 | self.dataSourceArray = faqs 38 | } 39 | 40 | public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { 41 | super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 42 | } 43 | 44 | required public init?(coder aDecoder: NSCoder) { 45 | fatalError("init(coder:) has not been implemented") 46 | } 47 | 48 | override open func viewDidLoad() { 49 | super.viewDidLoad() 50 | self.title = "FAQ" 51 | self.addSubviews() 52 | } 53 | 54 | fileprivate func addSubviews() { 55 | self.view.addSubview(self.tableView) 56 | let views = ["view":self.tableView] 57 | self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)) 58 | self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[view]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views)) 59 | } 60 | 61 | 62 | //MARK: table view datasource 63 | 64 | open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 65 | guard let cell : ExpandableTableViewCell = tableView.dequeueReusableCell(withIdentifier: "CellID") as? ExpandableTableViewCell else { 66 | preconditionFailure("reusable cell not found") 67 | } 68 | let item = self.dataSourceArray[(indexPath as NSIndexPath).row] 69 | cell.setCellContent(item, isExpanded: self.expandedIndexPaths.contains(indexPath)) 70 | cell.selectionStyle = UITableViewCellSelectionStyle.none 71 | return cell 72 | } 73 | 74 | open func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 75 | return self.dataSourceArray.count 76 | } 77 | 78 | open func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 79 | if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) { 80 | return UITableViewAutomaticDimension 81 | } else { 82 | return self.dynamicCellHeight(indexPath) 83 | } 84 | } 85 | 86 | open func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { 87 | return self.dynamicCellHeight(indexPath) 88 | } 89 | 90 | open func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 91 | tableView.separatorInset = UIEdgeInsets.zero 92 | tableView.layoutMargins = UIEdgeInsets.zero 93 | cell.layoutMargins = UIEdgeInsets.zero 94 | 95 | } 96 | 97 | //MARK: table view delegate 98 | 99 | open func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 100 | if(self.expandedIndexPaths.contains(indexPath)) { 101 | let idx = self.expandedIndexPaths.index(of: indexPath) 102 | self.expandedIndexPaths.remove(at: idx!) 103 | } else { 104 | self.expandedIndexPaths.append(indexPath) 105 | } 106 | self.tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.automatic) 107 | } 108 | 109 | 110 | //MARK: compute cell height 111 | 112 | fileprivate func dynamicCellHeight(_ indexPath:IndexPath)->CGFloat { 113 | 114 | let item = self.dataSourceArray[(indexPath as NSIndexPath).row] 115 | sizingCell.setCellContent(item, isExpanded: self.expandedIndexPaths.contains(indexPath)) 116 | sizingCell.setNeedsUpdateConstraints() 117 | sizingCell.updateConstraintsIfNeeded() 118 | sizingCell.setNeedsLayout() 119 | sizingCell.layoutIfNeeded() 120 | return sizingCell.cellContentHeight() 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ExpandableTableView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ExpandableTableViewDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // ExpandableTableViewDemo 4 | // 5 | // Created by Jubin Jacob on 07/10/16. 6 | // Copyright © 2016 J. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import ExpandableTableView 11 | 12 | @UIApplicationMain 13 | class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | 18 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 19 | loadTableView() 20 | return true 21 | } 22 | 23 | private func loadTableView() { 24 | let path = NSURL.fileURL(withPath: Bundle.main.path(forResource: "data", ofType: "json")!) 25 | let data = try! Data(contentsOf: path, options: .mappedIfSafe) 26 | let json = try! JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as! [[String:String]] 27 | let dataSource = json.map({return ItemModel(question: $0["Question"]!, answer: $0["Answer"]!)}) 28 | self.window?.rootViewController = ExpandableTableViewController(faqs: dataSource) 29 | } 30 | 31 | 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /ExpandableTableViewDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /ExpandableTableViewDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ExpandableTableViewDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ExpandableTableViewDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 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 | -------------------------------------------------------------------------------- /ExpandableTableViewDemo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // ExpandableTableViewDemo 4 | // 5 | // Created by Jubin Jacob on 07/10/16. 6 | // Copyright © 2016 J. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | } 16 | 17 | } 18 | 19 | -------------------------------------------------------------------------------- /ExpandableTableViewDemo/data.json: -------------------------------------------------------------------------------- 1 | [{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo li","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis ","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo lig"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet ad","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean com"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugi","Question":"Lorem ipsum dolor sit amet, consectetuer adipisc"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, f","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies n","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Mae","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget d"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem ne","Question":"Lorem ipsum dolor "},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet","Question":"Lorem ip"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, f","Question":"Lorem i"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate e","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aen"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet ad","Question":"Lorem i"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibu","Question":"Lorem "},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eg","Question":"Lorem ipsum dolor sit a"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean v","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo "},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. ","Question":"Lorem ipsum dolor sit amet, consectetuer adipisci"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh.","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. "},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibu","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. A"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagitti","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo l"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient","Question":"L"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultr","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo "},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, r","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean comm"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim jus","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et ma","Question":"Lorem ipsum dolor "},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales","Question":"Lorem "},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus v","Question":"Lorem ipsum dolor sit "},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eg","Question":"Lorem ipsum dolor sit amet, con"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra null","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo l"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aene","Question":"Lorem ipsum dolor sit amet, consectetuer adi"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula e"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean comm"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penat","Question":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean comm"},{"Answer":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, vi","Question":"Lorem ipsum dolor sit amet, consectetuer adipisci"}] 2 | -------------------------------------------------------------------------------- /ExpandableTableViewDemoTests/ExpandableTableViewDemoTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExpandableTableViewDemoTests.swift 3 | // ExpandableTableViewDemoTests 4 | // 5 | // Created by Jubin Jacob on 07/10/16. 6 | // Copyright © 2016 J. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import ExpandableTableViewDemo 11 | 12 | class ExpandableTableViewDemoTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ExpandableTableViewDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ExpandableTableViewDemoUITests/ExpandableTableViewDemoUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExpandableTableViewDemoUITests.swift 3 | // ExpandableTableViewDemoUITests 4 | // 5 | // Created by Jubin Jacob on 07/10/16. 6 | // Copyright © 2016 J. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class ExpandableTableViewDemoUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ExpandableTableViewDemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /ExpandableTableViewTests/ExpandableTableViewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExpandableTableViewTests.swift 3 | // ExpandableTableViewTests 4 | // 5 | // Created by Jubin Jacob on 10/08/16. 6 | // Copyright © 2016 J. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import ExpandableTableView 11 | 12 | class ExpandableTableViewTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ExpandableTableViewTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 2 | 3 | # ExpandableTableView 4 | 5 | Generic View Controller which can be used to show expandable sections in apps like FAQs. Accepts json data in the form [{"Question":"Question 1","Answer":"Answer 1"] and loads it in tableview with expandable/collapsible cells 6 | 7 | # Installation with Carthage 8 | 9 | To integrate ExpandableTableView into your Xcode project using Carthage, specify it in your Cartfile: 10 | ```carthage 11 | github "jubinjacob19/ExpandableTableView" 12 | ``` 13 | 14 | # Usage 15 | 16 | Initialize ExpandableTableViewController with an array of ItemModel objects 17 | 18 | ```swift 19 | let faqs : [ItemModel] = // fetch ItemModel from your app 20 | let expandableTableVC = ExpandableTableViewController(faqs: fetchQuestions()) 21 | ``` 22 | 23 | Creating Item model 24 | ```swift 25 | let item = ItemModel(question: "question", answer: "answer") 26 | ``` 27 | --------------------------------------------------------------------------------