├── Desktop └── LJMMultiLevelTableView │ ├── LJMMultiLevelTableView.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── ljm.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── ljm.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── LJMMultiLevelTableView.xcscheme │ │ └── xcschememanagement.plist │ └── LJMMultiLevelTableView │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── jiahao.imageset │ │ ├── Contents.json │ │ └── jiahao.png │ ├── jianhao.imageset │ │ ├── Contents.json │ │ └── jianhao.png │ ├── open.imageset │ │ ├── Contents.json │ │ └── open.png │ └── unopen.imageset │ │ ├── Contents.json │ │ └── unopen.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── LJMMultiLevelTableView.swift │ ├── ViewController.swift │ └── territory.txt └── README.md /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1AAFBF791F2775BC00ECF224 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AAFBF781F2775BC00ECF224 /* AppDelegate.swift */; }; 11 | 1AAFBF7B1F2775BC00ECF224 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AAFBF7A1F2775BC00ECF224 /* ViewController.swift */; }; 12 | 1AAFBF7E1F2775BC00ECF224 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1AAFBF7C1F2775BC00ECF224 /* Main.storyboard */; }; 13 | 1AAFBF801F2775BC00ECF224 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1AAFBF7F1F2775BC00ECF224 /* Assets.xcassets */; }; 14 | 1AAFBF831F2775BC00ECF224 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1AAFBF811F2775BC00ECF224 /* LaunchScreen.storyboard */; }; 15 | 1AAFBF8B1F2775D600ECF224 /* LJMMultiLevelTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AAFBF8A1F2775D600ECF224 /* LJMMultiLevelTableView.swift */; }; 16 | 1AAFBF931F2784E100ECF224 /* territory.txt in Resources */ = {isa = PBXBuildFile; fileRef = 1AAFBF921F2784E100ECF224 /* territory.txt */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 1AAFBF751F2775BC00ECF224 /* LJMMultiLevelTableView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LJMMultiLevelTableView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 21 | 1AAFBF781F2775BC00ECF224 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 22 | 1AAFBF7A1F2775BC00ECF224 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 23 | 1AAFBF7D1F2775BC00ECF224 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 24 | 1AAFBF7F1F2775BC00ECF224 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 25 | 1AAFBF821F2775BC00ECF224 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 26 | 1AAFBF841F2775BC00ECF224 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 27 | 1AAFBF8A1F2775D600ECF224 /* LJMMultiLevelTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LJMMultiLevelTableView.swift; sourceTree = ""; }; 28 | 1AAFBF921F2784E100ECF224 /* territory.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = territory.txt; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 1AAFBF721F2775BC00ECF224 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | 1AAFBF6C1F2775BC00ECF224 = { 43 | isa = PBXGroup; 44 | children = ( 45 | 1AAFBF771F2775BC00ECF224 /* LJMMultiLevelTableView */, 46 | 1AAFBF761F2775BC00ECF224 /* Products */, 47 | ); 48 | sourceTree = ""; 49 | }; 50 | 1AAFBF761F2775BC00ECF224 /* Products */ = { 51 | isa = PBXGroup; 52 | children = ( 53 | 1AAFBF751F2775BC00ECF224 /* LJMMultiLevelTableView.app */, 54 | ); 55 | name = Products; 56 | sourceTree = ""; 57 | }; 58 | 1AAFBF771F2775BC00ECF224 /* LJMMultiLevelTableView */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 1AAFBF781F2775BC00ECF224 /* AppDelegate.swift */, 62 | 1AAFBF7A1F2775BC00ECF224 /* ViewController.swift */, 63 | 1AAFBF8A1F2775D600ECF224 /* LJMMultiLevelTableView.swift */, 64 | 1AAFBF921F2784E100ECF224 /* territory.txt */, 65 | 1AAFBF7C1F2775BC00ECF224 /* Main.storyboard */, 66 | 1AAFBF7F1F2775BC00ECF224 /* Assets.xcassets */, 67 | 1AAFBF811F2775BC00ECF224 /* LaunchScreen.storyboard */, 68 | 1AAFBF841F2775BC00ECF224 /* Info.plist */, 69 | ); 70 | path = LJMMultiLevelTableView; 71 | sourceTree = ""; 72 | }; 73 | /* End PBXGroup section */ 74 | 75 | /* Begin PBXNativeTarget section */ 76 | 1AAFBF741F2775BC00ECF224 /* LJMMultiLevelTableView */ = { 77 | isa = PBXNativeTarget; 78 | buildConfigurationList = 1AAFBF871F2775BC00ECF224 /* Build configuration list for PBXNativeTarget "LJMMultiLevelTableView" */; 79 | buildPhases = ( 80 | 1AAFBF711F2775BC00ECF224 /* Sources */, 81 | 1AAFBF721F2775BC00ECF224 /* Frameworks */, 82 | 1AAFBF731F2775BC00ECF224 /* Resources */, 83 | ); 84 | buildRules = ( 85 | ); 86 | dependencies = ( 87 | ); 88 | name = LJMMultiLevelTableView; 89 | productName = LJMMultiLevelTableView; 90 | productReference = 1AAFBF751F2775BC00ECF224 /* LJMMultiLevelTableView.app */; 91 | productType = "com.apple.product-type.application"; 92 | }; 93 | /* End PBXNativeTarget section */ 94 | 95 | /* Begin PBXProject section */ 96 | 1AAFBF6D1F2775BC00ECF224 /* Project object */ = { 97 | isa = PBXProject; 98 | attributes = { 99 | LastSwiftUpdateCheck = 0820; 100 | LastUpgradeCheck = 0820; 101 | ORGANIZATIONNAME = com.ljm; 102 | TargetAttributes = { 103 | 1AAFBF741F2775BC00ECF224 = { 104 | CreatedOnToolsVersion = 8.2.1; 105 | DevelopmentTeam = GMF4R345FZ; 106 | ProvisioningStyle = Automatic; 107 | }; 108 | }; 109 | }; 110 | buildConfigurationList = 1AAFBF701F2775BC00ECF224 /* Build configuration list for PBXProject "LJMMultiLevelTableView" */; 111 | compatibilityVersion = "Xcode 3.2"; 112 | developmentRegion = English; 113 | hasScannedForEncodings = 0; 114 | knownRegions = ( 115 | en, 116 | Base, 117 | ); 118 | mainGroup = 1AAFBF6C1F2775BC00ECF224; 119 | productRefGroup = 1AAFBF761F2775BC00ECF224 /* Products */; 120 | projectDirPath = ""; 121 | projectRoot = ""; 122 | targets = ( 123 | 1AAFBF741F2775BC00ECF224 /* LJMMultiLevelTableView */, 124 | ); 125 | }; 126 | /* End PBXProject section */ 127 | 128 | /* Begin PBXResourcesBuildPhase section */ 129 | 1AAFBF731F2775BC00ECF224 /* Resources */ = { 130 | isa = PBXResourcesBuildPhase; 131 | buildActionMask = 2147483647; 132 | files = ( 133 | 1AAFBF831F2775BC00ECF224 /* LaunchScreen.storyboard in Resources */, 134 | 1AAFBF801F2775BC00ECF224 /* Assets.xcassets in Resources */, 135 | 1AAFBF7E1F2775BC00ECF224 /* Main.storyboard in Resources */, 136 | 1AAFBF931F2784E100ECF224 /* territory.txt in Resources */, 137 | ); 138 | runOnlyForDeploymentPostprocessing = 0; 139 | }; 140 | /* End PBXResourcesBuildPhase section */ 141 | 142 | /* Begin PBXSourcesBuildPhase section */ 143 | 1AAFBF711F2775BC00ECF224 /* Sources */ = { 144 | isa = PBXSourcesBuildPhase; 145 | buildActionMask = 2147483647; 146 | files = ( 147 | 1AAFBF7B1F2775BC00ECF224 /* ViewController.swift in Sources */, 148 | 1AAFBF8B1F2775D600ECF224 /* LJMMultiLevelTableView.swift in Sources */, 149 | 1AAFBF791F2775BC00ECF224 /* AppDelegate.swift in Sources */, 150 | ); 151 | runOnlyForDeploymentPostprocessing = 0; 152 | }; 153 | /* End PBXSourcesBuildPhase section */ 154 | 155 | /* Begin PBXVariantGroup section */ 156 | 1AAFBF7C1F2775BC00ECF224 /* Main.storyboard */ = { 157 | isa = PBXVariantGroup; 158 | children = ( 159 | 1AAFBF7D1F2775BC00ECF224 /* Base */, 160 | ); 161 | name = Main.storyboard; 162 | sourceTree = ""; 163 | }; 164 | 1AAFBF811F2775BC00ECF224 /* LaunchScreen.storyboard */ = { 165 | isa = PBXVariantGroup; 166 | children = ( 167 | 1AAFBF821F2775BC00ECF224 /* Base */, 168 | ); 169 | name = LaunchScreen.storyboard; 170 | sourceTree = ""; 171 | }; 172 | /* End PBXVariantGroup section */ 173 | 174 | /* Begin XCBuildConfiguration section */ 175 | 1AAFBF851F2775BC00ECF224 /* Debug */ = { 176 | isa = XCBuildConfiguration; 177 | buildSettings = { 178 | ALWAYS_SEARCH_USER_PATHS = NO; 179 | CLANG_ANALYZER_NONNULL = YES; 180 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 181 | CLANG_CXX_LIBRARY = "libc++"; 182 | CLANG_ENABLE_MODULES = YES; 183 | CLANG_ENABLE_OBJC_ARC = YES; 184 | CLANG_WARN_BOOL_CONVERSION = YES; 185 | CLANG_WARN_CONSTANT_CONVERSION = YES; 186 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 187 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 188 | CLANG_WARN_EMPTY_BODY = YES; 189 | CLANG_WARN_ENUM_CONVERSION = YES; 190 | CLANG_WARN_INFINITE_RECURSION = YES; 191 | CLANG_WARN_INT_CONVERSION = YES; 192 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 193 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 194 | CLANG_WARN_UNREACHABLE_CODE = YES; 195 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 196 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 197 | COPY_PHASE_STRIP = NO; 198 | DEBUG_INFORMATION_FORMAT = dwarf; 199 | ENABLE_STRICT_OBJC_MSGSEND = YES; 200 | ENABLE_TESTABILITY = YES; 201 | GCC_C_LANGUAGE_STANDARD = gnu99; 202 | GCC_DYNAMIC_NO_PIC = NO; 203 | GCC_NO_COMMON_BLOCKS = YES; 204 | GCC_OPTIMIZATION_LEVEL = 0; 205 | GCC_PREPROCESSOR_DEFINITIONS = ( 206 | "DEBUG=1", 207 | "$(inherited)", 208 | ); 209 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 210 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 211 | GCC_WARN_UNDECLARED_SELECTOR = YES; 212 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 213 | GCC_WARN_UNUSED_FUNCTION = YES; 214 | GCC_WARN_UNUSED_VARIABLE = YES; 215 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 216 | MTL_ENABLE_DEBUG_INFO = YES; 217 | ONLY_ACTIVE_ARCH = YES; 218 | SDKROOT = iphoneos; 219 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 220 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 221 | }; 222 | name = Debug; 223 | }; 224 | 1AAFBF861F2775BC00ECF224 /* Release */ = { 225 | isa = XCBuildConfiguration; 226 | buildSettings = { 227 | ALWAYS_SEARCH_USER_PATHS = NO; 228 | CLANG_ANALYZER_NONNULL = YES; 229 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 230 | CLANG_CXX_LIBRARY = "libc++"; 231 | CLANG_ENABLE_MODULES = YES; 232 | CLANG_ENABLE_OBJC_ARC = YES; 233 | CLANG_WARN_BOOL_CONVERSION = YES; 234 | CLANG_WARN_CONSTANT_CONVERSION = YES; 235 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 236 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 237 | CLANG_WARN_EMPTY_BODY = YES; 238 | CLANG_WARN_ENUM_CONVERSION = YES; 239 | CLANG_WARN_INFINITE_RECURSION = YES; 240 | CLANG_WARN_INT_CONVERSION = YES; 241 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 242 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 243 | CLANG_WARN_UNREACHABLE_CODE = YES; 244 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 245 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 246 | COPY_PHASE_STRIP = NO; 247 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 248 | ENABLE_NS_ASSERTIONS = NO; 249 | ENABLE_STRICT_OBJC_MSGSEND = YES; 250 | GCC_C_LANGUAGE_STANDARD = gnu99; 251 | GCC_NO_COMMON_BLOCKS = YES; 252 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 253 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 254 | GCC_WARN_UNDECLARED_SELECTOR = YES; 255 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 256 | GCC_WARN_UNUSED_FUNCTION = YES; 257 | GCC_WARN_UNUSED_VARIABLE = YES; 258 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 259 | MTL_ENABLE_DEBUG_INFO = NO; 260 | SDKROOT = iphoneos; 261 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 262 | VALIDATE_PRODUCT = YES; 263 | }; 264 | name = Release; 265 | }; 266 | 1AAFBF881F2775BC00ECF224 /* Debug */ = { 267 | isa = XCBuildConfiguration; 268 | buildSettings = { 269 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 270 | DEVELOPMENT_TEAM = GMF4R345FZ; 271 | INFOPLIST_FILE = LJMMultiLevelTableView/Info.plist; 272 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 273 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 274 | PRODUCT_BUNDLE_IDENTIFIER = com.ljm; 275 | PRODUCT_NAME = "$(TARGET_NAME)"; 276 | SWIFT_VERSION = 3.0; 277 | }; 278 | name = Debug; 279 | }; 280 | 1AAFBF891F2775BC00ECF224 /* Release */ = { 281 | isa = XCBuildConfiguration; 282 | buildSettings = { 283 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 284 | DEVELOPMENT_TEAM = GMF4R345FZ; 285 | INFOPLIST_FILE = LJMMultiLevelTableView/Info.plist; 286 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 287 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 288 | PRODUCT_BUNDLE_IDENTIFIER = com.ljm; 289 | PRODUCT_NAME = "$(TARGET_NAME)"; 290 | SWIFT_VERSION = 3.0; 291 | }; 292 | name = Release; 293 | }; 294 | /* End XCBuildConfiguration section */ 295 | 296 | /* Begin XCConfigurationList section */ 297 | 1AAFBF701F2775BC00ECF224 /* Build configuration list for PBXProject "LJMMultiLevelTableView" */ = { 298 | isa = XCConfigurationList; 299 | buildConfigurations = ( 300 | 1AAFBF851F2775BC00ECF224 /* Debug */, 301 | 1AAFBF861F2775BC00ECF224 /* Release */, 302 | ); 303 | defaultConfigurationIsVisible = 0; 304 | defaultConfigurationName = Release; 305 | }; 306 | 1AAFBF871F2775BC00ECF224 /* Build configuration list for PBXNativeTarget "LJMMultiLevelTableView" */ = { 307 | isa = XCConfigurationList; 308 | buildConfigurations = ( 309 | 1AAFBF881F2775BC00ECF224 /* Debug */, 310 | 1AAFBF891F2775BC00ECF224 /* Release */, 311 | ); 312 | defaultConfigurationIsVisible = 0; 313 | }; 314 | /* End XCConfigurationList section */ 315 | }; 316 | rootObject = 1AAFBF6D1F2775BC00ECF224 /* Project object */; 317 | } 318 | -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView.xcodeproj/project.xcworkspace/xcuserdata/ljm.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljmkimqx/LJMMultiLevelTableView/da7ca6d8c189aa04ad235e8c46aaa8399b948852/Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView.xcodeproj/project.xcworkspace/xcuserdata/ljm.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView.xcodeproj/xcuserdata/ljm.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView.xcodeproj/xcuserdata/ljm.xcuserdatad/xcschemes/LJMMultiLevelTableView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView.xcodeproj/xcuserdata/ljm.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LJMMultiLevelTableView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 1AAFBF741F2775BC00ECF224 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // LJMMultiLevelTableView 4 | // 5 | // 6 | 7 | import UIKit 8 | 9 | @UIApplicationMain 10 | class AppDelegate: UIResponder, UIApplicationDelegate { 11 | 12 | var window: UIWindow? 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | func applicationWillResignActive(_ application: UIApplication) { 21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 22 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 23 | } 24 | 25 | func applicationDidEnterBackground(_ application: UIApplication) { 26 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 27 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 28 | } 29 | 30 | func applicationWillEnterForeground(_ application: UIApplication) { 31 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 32 | } 33 | 34 | func applicationDidBecomeActive(_ application: UIApplication) { 35 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 36 | } 37 | 38 | func applicationWillTerminate(_ application: UIApplication) { 39 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 40 | } 41 | 42 | 43 | } 44 | 45 | -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/jiahao.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "jiahao.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/jiahao.imageset/jiahao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljmkimqx/LJMMultiLevelTableView/da7ca6d8c189aa04ad235e8c46aaa8399b948852/Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/jiahao.imageset/jiahao.png -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/jianhao.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "jianhao.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/jianhao.imageset/jianhao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljmkimqx/LJMMultiLevelTableView/da7ca6d8c189aa04ad235e8c46aaa8399b948852/Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/jianhao.imageset/jianhao.png -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/open.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "open.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/open.imageset/open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljmkimqx/LJMMultiLevelTableView/da7ca6d8c189aa04ad235e8c46aaa8399b948852/Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/open.imageset/open.png -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/unopen.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "unopen.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/unopen.imageset/unopen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljmkimqx/LJMMultiLevelTableView/da7ca6d8c189aa04ad235e8c46aaa8399b948852/Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/Assets.xcassets/unopen.imageset/unopen.png -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/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 | -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/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 | -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/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 | 38 | 39 | -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/LJMMultiLevelTableView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LJMMultiLevelTableView.swift 3 | // test 4 | // 5 | // 6 | 7 | import UIKit 8 | 9 | /*************************** 工具 ***********************************************/ 10 | /// 窗口宽度 11 | var QDEV_W = UIScreen.main.bounds.size.width 12 | /// 获取视图当前宽度 13 | func GETVW(_ view : UIView) ->CGFloat { return view.frame.width } 14 | /// 获取视图高度 15 | func GETVH(_ view : UIView) ->CGFloat { return view.frame.height } 16 | 17 | func QRect(_ X : CGFloat , Y : CGFloat , W : CGFloat , H : CGFloat) ->CGRect { return CGRect(x: X, y: Y, width: W, height: H) } 18 | 19 | typealias leafObj = ()->Void 20 | typealias ResObj = (_ obj: Any)->Void 21 | 22 | /// 点击手势 23 | class QTapGesture: UITapGestureRecognizer { 24 | 25 | var tapend : ResObj? 26 | 27 | class func addguest(_ view : UIView , action : @escaping ResObj){ 28 | let tap = QTapGesture.init(); 29 | tap.tapend = action 30 | tap.addTarget(tap, action: #selector(QTapGesture.tapgesture(_:))); 31 | view.isUserInteractionEnabled = true 32 | view.addGestureRecognizer(tap) 33 | } 34 | 35 | func tapgesture(_ tap : UITapGestureRecognizer){ 36 | if (self.tapend != nil){ 37 | self.tapend!(tap.view!) 38 | } 39 | } 40 | } 41 | 42 | //四个角变圆(未使用) 43 | func setAllround(_ view : UIView,size : CGFloat,corners:UIRectCorner){ 44 | let path = UIBezierPath.init(roundedRect: view.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: size, height: size)) 45 | let layer = CAShapeLayer() 46 | layer.frame = view.bounds 47 | layer.path = path.cgPath 48 | 49 | 50 | view.layer.mask = layer 51 | layer.shadowPath = UIBezierPath(rect: view.bounds).cgPath 52 | } 53 | 54 | ///色值一样的 55 | func RGBAsame(_ RGB : Double , A : CGFloat) ->UIColor { return UIColor.init(red: CGFloat(RGB/255.0), green: CGFloat(RGB/255.0), blue: CGFloat(RGB/255.0), alpha: A) } 56 | 57 | /*************************************************************************************/ 58 | 59 | 60 | class LJMMultiLevelTableView: UITableView ,UITableViewDelegate,UITableViewDataSource{ 61 | 62 | var companys : [CTMLObj] = [] 63 | 64 | var tempNodes : [[MLNodelObj]] = [] //当前展示的节点数据,每个元素数组存储的是每个组里面的所有正在展示的cell 65 | var reloadArray : [IndexPath]! //存储要插入的数据 66 | 67 | var leafblock : leafObj! //点击叶子回调 68 | 69 | var preservation : Bool = false //收起后再展开是否保留之前的展开状态 70 | 71 | private var isInitializeed : Bool = false //是否已经初始化过 72 | 73 | convenience init(_ frame : CGRect ,needPreservation : Bool, objs : AnyObject?){ 74 | self.init(frame: frame, style: UITableViewStyle.grouped) 75 | if objs != nil { 76 | companys = objs as! [CTMLObj] 77 | } 78 | for _ in 0.. Int { 117 | return self.companys.count 118 | } 119 | //每组多少cell 120 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 121 | return tempNodes[section].count 122 | } 123 | //自定义组头 124 | func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 125 | let head = tableView.dequeueReusableHeaderFooterView(withIdentifier: "CTMLCHeader") as! CTMLCHeaderView 126 | let comobj = companys[section] 127 | head.setInfo(comobj) 128 | head.tap = { (obj) in 129 | 130 | comobj.isopen = !comobj.isopen 131 | 132 | if comobj.isopen { 133 | let _ = self.expandNodes(section: section, parentID: comobj.ownID, index: -1) 134 | }else{ 135 | self.tempNodes[section].removeAll() 136 | } 137 | self.reloadArray.removeAll() 138 | tableView.reloadSections(IndexSet(integer: section), with: UITableViewRowAnimation.automatic) 139 | 140 | } 141 | return head 142 | } 143 | //组头高度 144 | func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 145 | return 50 146 | } 147 | //组尾高度 148 | func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { 149 | return 10 150 | } 151 | //每个cell高度 152 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 153 | return 50 154 | } 155 | //设置cell 156 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 157 | let cell = tableView.dequeueReusableCell(withIdentifier: "CTMLCell", for: indexPath) as! CTMLCell 158 | let obj = tempNodes[indexPath.section][indexPath.row] 159 | cell.setcellinfo(obj) 160 | 161 | return cell 162 | } 163 | //点击cell 164 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 165 | let currentnode = tempNodes[indexPath.section][indexPath.row] 166 | if currentnode.leaf { 167 | print("点击叶子,\(currentnode.name)") 168 | if self.leafblock != nil { 169 | self.leafblock() 170 | } 171 | return 172 | }else{ 173 | currentnode.expand = !currentnode.expand 174 | } 175 | reloadArray.removeAll() 176 | 177 | if currentnode.expand { 178 | let _ = self.expandNodes(section: indexPath.section, parentID: currentnode.ownID, index: indexPath.row) 179 | //插入cell 180 | tableView.insertRows(at: reloadArray as [IndexPath], with: UITableViewRowAnimation.none) 181 | }else{ 182 | self.foldNodes(section: indexPath.section, level: currentnode.level, currentIndex: indexPath.row) 183 | //删除cell 184 | tableView.deleteRows(at: reloadArray, with: UITableViewRowAnimation.none) 185 | } 186 | //刷新这行cell的显示 187 | tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.none) 188 | } 189 | 190 | //记录展开的数据 191 | func expandNodes(section : Int, parentID:String,index:Int)->Int{ 192 | 193 | var insertindex = index 194 | 195 | for i in 0..= startI { 235 | tempNodes[section].removeSubrange(startI...endI) 236 | } 237 | } 238 | } 239 | } 240 | 241 | /**************** 组头 ***************************/ 242 | class CTMLCHeaderView: UITableViewHeaderFooterView { 243 | 244 | var bgv : UIView! 245 | var descLbl : UILabel! 246 | var imgBtn : UIButton! 247 | 248 | var tap : ResObj! 249 | 250 | override init(reuseIdentifier: String?) { 251 | super.init(reuseIdentifier: reuseIdentifier) 252 | creatView() 253 | } 254 | 255 | required init?(coder aDecoder: NSCoder) { 256 | fatalError("init(coder:) has not been implemented") 257 | } 258 | 259 | func creatView(){ 260 | bgv = UIView(frame: QRect(15, Y: 0, W: QDEV_W - 30, H: 50)) 261 | bgv.backgroundColor = RGBAsame(233, A: 1.0) 262 | bgv.layer.borderColor = RGBAsame(211, A: 1.0).cgColor 263 | bgv.layer.borderWidth = 1.0 264 | bgv.layer.cornerRadius = 5 265 | bgv.layer.masksToBounds = true 266 | 267 | let imgw : CGFloat = 30 268 | imgBtn = UIButton(frame: QRect(GETVW(bgv)-imgw, Y: (GETVH(bgv)-imgw)/2.0, W: imgw, H: imgw)) 269 | imgBtn.isUserInteractionEnabled = false 270 | imgBtn.setImage(UIImage(named: "jiahao"), for: UIControlState.normal) 271 | imgBtn.setImage(UIImage(named: "jianhao"), for: UIControlState.selected) 272 | imgBtn.imageView?.contentMode = .scaleAspectFit 273 | imgBtn.contentEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10) 274 | bgv.addSubview(imgBtn) 275 | 276 | descLbl = UILabel(frame: QRect(10, Y: 0, W: GETVW(bgv)-10-imgw, H: GETVH(bgv))) 277 | descLbl.font = UIFont.systemFont(ofSize: 13) 278 | descLbl.textColor = UIColor.black 279 | descLbl.textAlignment = NSTextAlignment.left 280 | descLbl.backgroundColor = bgv.backgroundColor 281 | bgv.addSubview(descLbl) 282 | 283 | self.addSubview(bgv) 284 | 285 | QTapGesture.addguest(bgv) { (obj) in 286 | if self.tap != nil { self.tap(obj) } 287 | } 288 | } 289 | 290 | func setInfo(_ obj : CTMLObj){ 291 | descLbl.text = obj.name 292 | imgBtn.isSelected = obj.isopen 293 | } 294 | 295 | } 296 | 297 | class CTMLCell: UITableViewCell { 298 | 299 | var bgv : UIView! 300 | var descLbl : UILabel! 301 | var imgBtn : UIButton! 302 | 303 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 304 | super.init(style: style, reuseIdentifier: reuseIdentifier) 305 | self.contentView.frame = QRect(0, Y: 0, W: QDEV_W, H: 0) 306 | 307 | creatsubview() 308 | } 309 | 310 | required init?(coder aDecoder: NSCoder) { 311 | fatalError("init(coder:) has not been implemented") 312 | } 313 | 314 | func creatsubview() { 315 | self.selectionStyle = UITableViewCellSelectionStyle.none 316 | 317 | bgv = UIView(frame: QRect(15, Y: 0, W: QDEV_W - 30, H: 50)) 318 | bgv.backgroundColor = RGBAsame(245, A: 1.0) 319 | bgv.layer.borderColor = RGBAsame(211, A: 1.0).cgColor 320 | bgv.layer.borderWidth = 1.0 321 | 322 | let imgw : CGFloat = 30 323 | imgBtn = UIButton(frame: QRect(GETVW(bgv)-imgw, Y: (GETVH(bgv)-imgw)/2.0, W: imgw, H: imgw)) 324 | imgBtn.isUserInteractionEnabled = false 325 | imgBtn.setImage(UIImage(named: "unopen"), for: UIControlState.normal) 326 | imgBtn.setImage(UIImage(named: "open"), for: UIControlState.selected) 327 | imgBtn.imageView?.contentMode = .scaleAspectFit 328 | imgBtn.contentEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10) 329 | bgv.addSubview(imgBtn) 330 | 331 | descLbl = UILabel(frame: QRect(10, Y: 0, W: GETVW(bgv)-10-imgw, H: GETVH(bgv))) 332 | descLbl.font = UIFont.systemFont(ofSize: 13) 333 | descLbl.textColor = UIColor.black 334 | descLbl.textAlignment = NSTextAlignment.left 335 | descLbl.backgroundColor = bgv.backgroundColor 336 | bgv.addSubview(descLbl) 337 | 338 | self.addSubview(bgv) 339 | } 340 | 341 | func setcellinfo(_ id: AnyObject) { 342 | let obj = id as! MLNodelObj 343 | descLbl.text = obj.name 344 | imgBtn.isSelected = obj.expand 345 | imgBtn.isHidden = obj.leaf 346 | layoutView(obj) 347 | } 348 | 349 | func layoutView(_ obj : MLNodelObj){ 350 | let interval : CGFloat = 30 351 | var leMargin : CGFloat = 10 352 | for _ in 2...obj.level { 353 | leMargin += interval 354 | } 355 | 356 | descLbl.frame = QRect(leMargin, Y: 0, W: GETVW(bgv)-leMargin-30, H: GETVH(bgv)) 357 | bgv.backgroundColor = obj.level == 2 ? RGBAsame(245, A: 1.0) : RGBAsame(255, A: 1.0) 358 | descLbl.backgroundColor = bgv.backgroundColor 359 | } 360 | 361 | 362 | 363 | } 364 | 365 | 366 | 367 | class CTMLObj : NSObject{ 368 | 369 | var name : String = "" 370 | var ownID : String = "" //自身ID 371 | var level : Int = 1 372 | var isopen : Bool = false 373 | 374 | var subNodes : [MLNodelObj] = [] 375 | 376 | class func node(ownID:String,name:String,level:NSInteger)->CTMLObj{ 377 | let ctmlobj = CTMLObj() 378 | ctmlobj.name = name 379 | ctmlobj.ownID = ownID 380 | ctmlobj.level = level 381 | return ctmlobj 382 | } 383 | 384 | } 385 | 386 | 387 | //节点数据 388 | class MLNodelObj: NSObject { 389 | 390 | var parentID : String = "" //父ID 391 | var ownID : String = "" //自身ID 392 | var name : String = "" //自身内容 393 | var level : NSInteger = 0 //级别 394 | var expand : Bool = false //是否展开 395 | var leaf : Bool = false //是否叶子(没有子节点) 396 | var root : Bool = false //是否根节点 397 | 398 | class func node(parentID:String,ownID:String,name:String,level:NSInteger,isleaf:Bool,isroot:Bool,isExpand:Bool)->MLNodelObj{ 399 | let mlnode = MLNodelObj() 400 | mlnode.parentID = parentID 401 | mlnode.ownID = ownID 402 | mlnode.name = name 403 | mlnode.level = level 404 | mlnode.leaf = isleaf 405 | mlnode.root = isroot 406 | mlnode.expand = isExpand 407 | 408 | return mlnode 409 | } 410 | 411 | } 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // LJMMultiLevelTableView 4 | // 5 | // 6 | 7 | import UIKit 8 | import Foundation 9 | 10 | class ViewController: UIViewController { 11 | 12 | var listobj : AnyObject! 13 | var levelList : LJMMultiLevelTableView! 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | let path = Bundle.main.path(forResource: "territory", ofType: "txt") 19 | 20 | let url = URL(fileURLWithPath: path!) 21 | 22 | do { 23 | let data = try Data(contentsOf: url) 24 | let jsondata = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) 25 | listobj = getdata(jsondata as AnyObject) 26 | 27 | } catch { 28 | print("报错") 29 | } 30 | 31 | levelList = LJMMultiLevelTableView(QRect(0, Y: 50, W: GETVW(self.view), H: GETVH(self.view)-50), needPreservation: true, objs: listobj) 32 | self.view.addSubview(levelList) 33 | 34 | 35 | } 36 | 37 | func getdata(_ obj :AnyObject)->AnyObject{ 38 | 39 | let dict = obj as! NSDictionary 40 | let array = dict["data"] as! NSArray 41 | var objs = [AnyObject]() 42 | 43 | //洲 44 | for obj in array{ 45 | let continent = obj as! NSDictionary 46 | let continentName = continent["洲"] as! String 47 | let continentid = continent["continentID"] as! String 48 | let continentC = CTMLObj.node(ownID: continentid, name: continentName, level: 1) 49 | objs.append(continentC) 50 | 51 | //国家 52 | let countryArray = continent["国家"] as? NSArray 53 | if countryArray != nil{ 54 | for obj in countryArray!{ 55 | let country = obj as! NSDictionary 56 | let countryName = country["国家名称"] as! String 57 | let countryid = country["countryID"] as! String 58 | let countryM = MLNodelObj.node(parentID: continentid, ownID: countryid, name: countryName, level: 2, isleaf: false, isroot: false, isExpand: false) 59 | continentC.subNodes.append(countryM) 60 | 61 | //城市 62 | let cityArray = country["城市"] as? NSArray 63 | if cityArray != nil{ 64 | for obj in cityArray!{ 65 | let city = obj as! NSDictionary 66 | let cityName = city["城市"] as! String 67 | let cityid = city["cityID"] as! String 68 | let cityM = MLNodelObj.node(parentID: countryid, ownID: cityid, name: cityName, level: 3, isleaf: true, isroot: false, isExpand: false) 69 | continentC.subNodes.append(cityM) 70 | } 71 | } 72 | } 73 | } 74 | } 75 | 76 | return objs as AnyObject 77 | } 78 | 79 | 80 | 81 | override func didReceiveMemoryWarning() { 82 | super.didReceiveMemoryWarning() 83 | // Dispose of any resources that can be recreated. 84 | } 85 | 86 | 87 | } 88 | 89 | -------------------------------------------------------------------------------- /Desktop/LJMMultiLevelTableView/LJMMultiLevelTableView/territory.txt: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "洲": "亚洲", 5 | "continentID": "00", 6 | "国家": [ 7 | { 8 | "countryID": "000", 9 | "国家名称": "中国", 10 | "城市": [ 11 | { 12 | "cityID": "0001", 13 | "城市": "北京" 14 | }, 15 | { 16 | "cityID": "0002", 17 | "城市": "上海" 18 | }, 19 | { 20 | "cityID": "0003", 21 | "城市": "深圳" 22 | }, 23 | { 24 | "cityID": "0004", 25 | "城市": "广州" 26 | } 27 | ] 28 | }, 29 | { 30 | "countryID": "001", 31 | "国家名称": "俄罗斯", 32 | "城市": [ 33 | { 34 | "cityID": "0011", 35 | "城市": "莫斯科" 36 | }, 37 | { 38 | "cityID": "0012", 39 | "城市": "新西伯利亚" 40 | }, 41 | { 42 | "cityID": "0013", 43 | "城市": "叶卡捷琳堡" 44 | } 45 | ] 46 | } 47 | ] 48 | }, 49 | { 50 | "洲": "南美洲", 51 | "continentID": "01", 52 | "国家": [ 53 | { 54 | "countryID": "010", 55 | "国家名称": "巴西", 56 | "城市": [ 57 | { 58 | "cityID": "0101", 59 | "城市": "里约热内卢" 60 | }, 61 | { 62 | "cityID": "0102", 63 | "城市": "圣保罗" 64 | }, 65 | { 66 | "cityID": "0103", 67 | "城市": "萨尔瓦多" 68 | }, 69 | { 70 | "cityID": "0104", 71 | "城市": "巴西利亚" 72 | } 73 | ] 74 | }, 75 | { 76 | "countryID": "011", 77 | "国家名称": "阿根廷", 78 | "城市": [ 79 | { 80 | "cityID": "0111", 81 | "城市": "布宜诺斯艾利斯" 82 | }, 83 | { 84 | "cityID": "0112", 85 | "城市": "科尔多瓦" 86 | }, 87 | { 88 | "cityID": "0113", 89 | "城市": "罗萨里奥" 90 | }, 91 | { 92 | "cityID": "0114", 93 | "城市": "拉普拉塔" 94 | } 95 | ] 96 | } 97 | ] 98 | }, 99 | { 100 | "洲": "澳洲", 101 | "continentID": "02", 102 | "国家": [ 103 | { 104 | "countryID": "020", 105 | "国家名称": "澳大利亚", 106 | "城市": [ 107 | { 108 | "cityID": "0201", 109 | "城市": "悉尼" 110 | }, 111 | { 112 | "cityID": "0202", 113 | "城市": "墨尔本" 114 | }, 115 | { 116 | "cityID": "0203", 117 | "城市": "堪培拉" 118 | }, 119 | { 120 | "cityID": "0204", 121 | "城市": "布里斯本" 122 | } 123 | ] 124 | }, 125 | { 126 | "countryID": "021", 127 | "国家名称": "新西兰", 128 | "城市": [ 129 | { 130 | "cityID": "0211", 131 | "城市": "奥克兰" 132 | }, 133 | { 134 | "cityID": "0212", 135 | "城市": "惠灵顿" 136 | }, 137 | { 138 | "cityID": "0213", 139 | "城市": "基督城" 140 | }, 141 | { 142 | "cityID": "0214", 143 | "城市": "哈密尔顿" 144 | } 145 | ] 146 | } 147 | ] 148 | } 149 | ] 150 | } 151 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LJMMultiLevelTableView 2 | 较为美观的多级展开列表 3 | --------------------------------------------------------------------------------