├── .gitignore ├── CFMultistageDropdownMenuView ├── CFMultistageDropdownMenuView.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata └── CFMultistageDropdownMenuView │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── 测试紫箭头.imageset │ │ ├── Contents.json │ │ ├── 测试紫箭头@2x.png │ │ └── 测试紫箭头@3x.png │ └── 测试红箭头.imageset │ │ ├── Contents.json │ │ ├── 测试红箭头@2x.png │ │ └── 测试红箭头@3x.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── CFMultistageDropdownMenuView.bundle │ ├── 天蓝箭头@2x.png │ ├── 天蓝箭头@3x.png │ ├── 橙箭头@2x.png │ ├── 橙箭头@3x.png │ ├── 淡紫箭头@2x.png │ ├── 淡紫箭头@3x.png │ ├── 深灰箭头@2x.png │ ├── 深灰箭头@3x.png │ ├── 深绿箭头@2x.png │ ├── 深绿箭头@3x.png │ ├── 深蓝箭头@2x.png │ ├── 深蓝箭头@3x.png │ ├── 灰箭头@2x.png │ ├── 灰箭头@3x.png │ ├── 白箭头@2x.png │ ├── 白箭头@3x.png │ ├── 粉箭头@2x.png │ ├── 粉箭头@3x.png │ ├── 紫箭头@2x.png │ ├── 紫箭头@3x.png │ ├── 红箭头@2x.png │ ├── 红箭头@3x.png │ ├── 绿箭头@2x.png │ ├── 绿箭头@3x.png │ ├── 黄箭头@2x.png │ └── 黄箭头@3x.png │ ├── Info.plist │ ├── Lib │ ├── CFLabelOnLeftButton.h │ ├── CFLabelOnLeftButton.m │ ├── CFMacro.h │ ├── CFMultistageConditionTableView.h │ ├── CFMultistageConditionTableView.m │ ├── CFMultistageDropdownMenuView.h │ ├── CFMultistageDropdownMenuView.m │ ├── UIView+CFFrame.h │ └── UIView+CFFrame.m │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── LICENSE ├── README.md ├── 公司项目实际使用.gif ├── 实现第一个代理方法.gif └── 实现第二个代理方法.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | 55 | #Code Injection 56 | # 57 | # After new code Injection tools there's a generated folder /iOSInjectionProject 58 | # https://github.com/johnno1962/injectionforxcode 59 | 60 | iOSInjectionProject/ 61 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5F04F3861E7B95C800F872D3 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F04F3851E7B95C800F872D3 /* ViewController.m */; }; 11 | 8A06ACF11E67B834005E57A5 /* CFMultistageDropdownMenuView.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 8A06ACF01E67B834005E57A5 /* CFMultistageDropdownMenuView.bundle */; }; 12 | 8AB2C6EB1E65175E0018E74E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AB2C6EA1E65175E0018E74E /* main.m */; }; 13 | 8AB2C6EE1E65175E0018E74E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AB2C6ED1E65175E0018E74E /* AppDelegate.m */; }; 14 | 8AB2C6F41E65175E0018E74E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8AB2C6F21E65175E0018E74E /* Main.storyboard */; }; 15 | 8AB2C6F61E65175E0018E74E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8AB2C6F51E65175E0018E74E /* Assets.xcassets */; }; 16 | 8AB2C6F91E65175E0018E74E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8AB2C6F71E65175E0018E74E /* LaunchScreen.storyboard */; }; 17 | 8AB2C7041E651A3F0018E74E /* CFMultistageDropdownMenuView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AB2C7031E651A3F0018E74E /* CFMultistageDropdownMenuView.m */; }; 18 | 8AB2C70A1E651BC10018E74E /* CFLabelOnLeftButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AB2C7061E651BC10018E74E /* CFLabelOnLeftButton.m */; }; 19 | 8AB2C70B1E651BC10018E74E /* UIView+CFFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AB2C7091E651BC10018E74E /* UIView+CFFrame.m */; }; 20 | 8AB2C70E1E6558530018E74E /* CFMultistageConditionTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8AB2C70D1E6558530018E74E /* CFMultistageConditionTableView.m */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXFileReference section */ 24 | 5F04F3841E7B95C800F872D3 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 25 | 5F04F3851E7B95C800F872D3 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 26 | 8A06ACF01E67B834005E57A5 /* CFMultistageDropdownMenuView.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = CFMultistageDropdownMenuView.bundle; sourceTree = ""; }; 27 | 8AB2C6E61E65175E0018E74E /* CFMultistageDropdownMenuView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CFMultistageDropdownMenuView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | 8AB2C6EA1E65175E0018E74E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 29 | 8AB2C6EC1E65175E0018E74E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 30 | 8AB2C6ED1E65175E0018E74E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 31 | 8AB2C6F31E65175E0018E74E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 32 | 8AB2C6F51E65175E0018E74E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 33 | 8AB2C6F81E65175E0018E74E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 34 | 8AB2C6FA1E65175E0018E74E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 35 | 8AB2C7021E651A3F0018E74E /* CFMultistageDropdownMenuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFMultistageDropdownMenuView.h; sourceTree = ""; }; 36 | 8AB2C7031E651A3F0018E74E /* CFMultistageDropdownMenuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CFMultistageDropdownMenuView.m; sourceTree = ""; }; 37 | 8AB2C7051E651BC10018E74E /* CFLabelOnLeftButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFLabelOnLeftButton.h; sourceTree = ""; }; 38 | 8AB2C7061E651BC10018E74E /* CFLabelOnLeftButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CFLabelOnLeftButton.m; sourceTree = ""; }; 39 | 8AB2C7071E651BC10018E74E /* CFMacro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFMacro.h; sourceTree = ""; }; 40 | 8AB2C7081E651BC10018E74E /* UIView+CFFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+CFFrame.h"; sourceTree = ""; }; 41 | 8AB2C7091E651BC10018E74E /* UIView+CFFrame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+CFFrame.m"; sourceTree = ""; }; 42 | 8AB2C70C1E6558530018E74E /* CFMultistageConditionTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFMultistageConditionTableView.h; sourceTree = ""; }; 43 | 8AB2C70D1E6558530018E74E /* CFMultistageConditionTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CFMultistageConditionTableView.m; sourceTree = ""; }; 44 | /* End PBXFileReference section */ 45 | 46 | /* Begin PBXFrameworksBuildPhase section */ 47 | 8AB2C6E31E65175E0018E74E /* Frameworks */ = { 48 | isa = PBXFrameworksBuildPhase; 49 | buildActionMask = 2147483647; 50 | files = ( 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | /* End PBXFrameworksBuildPhase section */ 55 | 56 | /* Begin PBXGroup section */ 57 | 8AB2C6DD1E65175E0018E74E = { 58 | isa = PBXGroup; 59 | children = ( 60 | 8AB2C6E81E65175E0018E74E /* CFMultistageDropdownMenuView */, 61 | 8AB2C6E71E65175E0018E74E /* Products */, 62 | ); 63 | sourceTree = ""; 64 | }; 65 | 8AB2C6E71E65175E0018E74E /* Products */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | 8AB2C6E61E65175E0018E74E /* CFMultistageDropdownMenuView.app */, 69 | ); 70 | name = Products; 71 | sourceTree = ""; 72 | }; 73 | 8AB2C6E81E65175E0018E74E /* CFMultistageDropdownMenuView */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 5F04F3841E7B95C800F872D3 /* ViewController.h */, 77 | 5F04F3851E7B95C800F872D3 /* ViewController.m */, 78 | 8A06ACF01E67B834005E57A5 /* CFMultistageDropdownMenuView.bundle */, 79 | 8AB2C7011E6519150018E74E /* Lib */, 80 | 8AB2C6EC1E65175E0018E74E /* AppDelegate.h */, 81 | 8AB2C6ED1E65175E0018E74E /* AppDelegate.m */, 82 | 8AB2C6F21E65175E0018E74E /* Main.storyboard */, 83 | 8AB2C6F51E65175E0018E74E /* Assets.xcassets */, 84 | 8AB2C6F71E65175E0018E74E /* LaunchScreen.storyboard */, 85 | 8AB2C6FA1E65175E0018E74E /* Info.plist */, 86 | 8AB2C6E91E65175E0018E74E /* Supporting Files */, 87 | ); 88 | path = CFMultistageDropdownMenuView; 89 | sourceTree = ""; 90 | }; 91 | 8AB2C6E91E65175E0018E74E /* Supporting Files */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 8AB2C6EA1E65175E0018E74E /* main.m */, 95 | ); 96 | name = "Supporting Files"; 97 | sourceTree = ""; 98 | }; 99 | 8AB2C7011E6519150018E74E /* Lib */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 8AB2C7021E651A3F0018E74E /* CFMultistageDropdownMenuView.h */, 103 | 8AB2C7031E651A3F0018E74E /* CFMultistageDropdownMenuView.m */, 104 | 8AB2C70C1E6558530018E74E /* CFMultistageConditionTableView.h */, 105 | 8AB2C70D1E6558530018E74E /* CFMultistageConditionTableView.m */, 106 | 8AB2C7051E651BC10018E74E /* CFLabelOnLeftButton.h */, 107 | 8AB2C7061E651BC10018E74E /* CFLabelOnLeftButton.m */, 108 | 8AB2C7071E651BC10018E74E /* CFMacro.h */, 109 | 8AB2C7081E651BC10018E74E /* UIView+CFFrame.h */, 110 | 8AB2C7091E651BC10018E74E /* UIView+CFFrame.m */, 111 | ); 112 | path = Lib; 113 | sourceTree = ""; 114 | }; 115 | /* End PBXGroup section */ 116 | 117 | /* Begin PBXNativeTarget section */ 118 | 8AB2C6E51E65175E0018E74E /* CFMultistageDropdownMenuView */ = { 119 | isa = PBXNativeTarget; 120 | buildConfigurationList = 8AB2C6FD1E65175E0018E74E /* Build configuration list for PBXNativeTarget "CFMultistageDropdownMenuView" */; 121 | buildPhases = ( 122 | 8AB2C6E21E65175E0018E74E /* Sources */, 123 | 8AB2C6E31E65175E0018E74E /* Frameworks */, 124 | 8AB2C6E41E65175E0018E74E /* Resources */, 125 | ); 126 | buildRules = ( 127 | ); 128 | dependencies = ( 129 | ); 130 | name = CFMultistageDropdownMenuView; 131 | productName = CFMultistageDropdownMenuView; 132 | productReference = 8AB2C6E61E65175E0018E74E /* CFMultistageDropdownMenuView.app */; 133 | productType = "com.apple.product-type.application"; 134 | }; 135 | /* End PBXNativeTarget section */ 136 | 137 | /* Begin PBXProject section */ 138 | 8AB2C6DE1E65175E0018E74E /* Project object */ = { 139 | isa = PBXProject; 140 | attributes = { 141 | LastUpgradeCheck = 0820; 142 | ORGANIZATIONNAME = Peak; 143 | TargetAttributes = { 144 | 8AB2C6E51E65175E0018E74E = { 145 | CreatedOnToolsVersion = 8.2.1; 146 | ProvisioningStyle = Automatic; 147 | }; 148 | }; 149 | }; 150 | buildConfigurationList = 8AB2C6E11E65175E0018E74E /* Build configuration list for PBXProject "CFMultistageDropdownMenuView" */; 151 | compatibilityVersion = "Xcode 3.2"; 152 | developmentRegion = English; 153 | hasScannedForEncodings = 0; 154 | knownRegions = ( 155 | en, 156 | Base, 157 | ); 158 | mainGroup = 8AB2C6DD1E65175E0018E74E; 159 | productRefGroup = 8AB2C6E71E65175E0018E74E /* Products */; 160 | projectDirPath = ""; 161 | projectRoot = ""; 162 | targets = ( 163 | 8AB2C6E51E65175E0018E74E /* CFMultistageDropdownMenuView */, 164 | ); 165 | }; 166 | /* End PBXProject section */ 167 | 168 | /* Begin PBXResourcesBuildPhase section */ 169 | 8AB2C6E41E65175E0018E74E /* Resources */ = { 170 | isa = PBXResourcesBuildPhase; 171 | buildActionMask = 2147483647; 172 | files = ( 173 | 8A06ACF11E67B834005E57A5 /* CFMultistageDropdownMenuView.bundle in Resources */, 174 | 8AB2C6F91E65175E0018E74E /* LaunchScreen.storyboard in Resources */, 175 | 8AB2C6F61E65175E0018E74E /* Assets.xcassets in Resources */, 176 | 8AB2C6F41E65175E0018E74E /* Main.storyboard in Resources */, 177 | ); 178 | runOnlyForDeploymentPostprocessing = 0; 179 | }; 180 | /* End PBXResourcesBuildPhase section */ 181 | 182 | /* Begin PBXSourcesBuildPhase section */ 183 | 8AB2C6E21E65175E0018E74E /* Sources */ = { 184 | isa = PBXSourcesBuildPhase; 185 | buildActionMask = 2147483647; 186 | files = ( 187 | 5F04F3861E7B95C800F872D3 /* ViewController.m in Sources */, 188 | 8AB2C70E1E6558530018E74E /* CFMultistageConditionTableView.m in Sources */, 189 | 8AB2C70B1E651BC10018E74E /* UIView+CFFrame.m in Sources */, 190 | 8AB2C6EE1E65175E0018E74E /* AppDelegate.m in Sources */, 191 | 8AB2C7041E651A3F0018E74E /* CFMultistageDropdownMenuView.m in Sources */, 192 | 8AB2C70A1E651BC10018E74E /* CFLabelOnLeftButton.m in Sources */, 193 | 8AB2C6EB1E65175E0018E74E /* main.m in Sources */, 194 | ); 195 | runOnlyForDeploymentPostprocessing = 0; 196 | }; 197 | /* End PBXSourcesBuildPhase section */ 198 | 199 | /* Begin PBXVariantGroup section */ 200 | 8AB2C6F21E65175E0018E74E /* Main.storyboard */ = { 201 | isa = PBXVariantGroup; 202 | children = ( 203 | 8AB2C6F31E65175E0018E74E /* Base */, 204 | ); 205 | name = Main.storyboard; 206 | sourceTree = ""; 207 | }; 208 | 8AB2C6F71E65175E0018E74E /* LaunchScreen.storyboard */ = { 209 | isa = PBXVariantGroup; 210 | children = ( 211 | 8AB2C6F81E65175E0018E74E /* Base */, 212 | ); 213 | name = LaunchScreen.storyboard; 214 | sourceTree = ""; 215 | }; 216 | /* End PBXVariantGroup section */ 217 | 218 | /* Begin XCBuildConfiguration section */ 219 | 8AB2C6FB1E65175E0018E74E /* Debug */ = { 220 | isa = XCBuildConfiguration; 221 | buildSettings = { 222 | ALWAYS_SEARCH_USER_PATHS = NO; 223 | CLANG_ANALYZER_NONNULL = YES; 224 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 225 | CLANG_CXX_LIBRARY = "libc++"; 226 | CLANG_ENABLE_MODULES = YES; 227 | CLANG_ENABLE_OBJC_ARC = YES; 228 | CLANG_WARN_BOOL_CONVERSION = YES; 229 | CLANG_WARN_CONSTANT_CONVERSION = YES; 230 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 231 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 232 | CLANG_WARN_EMPTY_BODY = YES; 233 | CLANG_WARN_ENUM_CONVERSION = YES; 234 | CLANG_WARN_INFINITE_RECURSION = YES; 235 | CLANG_WARN_INT_CONVERSION = YES; 236 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 237 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 238 | CLANG_WARN_UNREACHABLE_CODE = YES; 239 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 240 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 241 | COPY_PHASE_STRIP = NO; 242 | DEBUG_INFORMATION_FORMAT = dwarf; 243 | ENABLE_STRICT_OBJC_MSGSEND = YES; 244 | ENABLE_TESTABILITY = YES; 245 | GCC_C_LANGUAGE_STANDARD = gnu99; 246 | GCC_DYNAMIC_NO_PIC = NO; 247 | GCC_NO_COMMON_BLOCKS = YES; 248 | GCC_OPTIMIZATION_LEVEL = 0; 249 | GCC_PREPROCESSOR_DEFINITIONS = ( 250 | "DEBUG=1", 251 | "$(inherited)", 252 | ); 253 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 254 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 255 | GCC_WARN_UNDECLARED_SELECTOR = YES; 256 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 257 | GCC_WARN_UNUSED_FUNCTION = YES; 258 | GCC_WARN_UNUSED_VARIABLE = YES; 259 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 260 | MTL_ENABLE_DEBUG_INFO = YES; 261 | ONLY_ACTIVE_ARCH = YES; 262 | SDKROOT = iphoneos; 263 | }; 264 | name = Debug; 265 | }; 266 | 8AB2C6FC1E65175E0018E74E /* Release */ = { 267 | isa = XCBuildConfiguration; 268 | buildSettings = { 269 | ALWAYS_SEARCH_USER_PATHS = NO; 270 | CLANG_ANALYZER_NONNULL = YES; 271 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 272 | CLANG_CXX_LIBRARY = "libc++"; 273 | CLANG_ENABLE_MODULES = YES; 274 | CLANG_ENABLE_OBJC_ARC = YES; 275 | CLANG_WARN_BOOL_CONVERSION = YES; 276 | CLANG_WARN_CONSTANT_CONVERSION = YES; 277 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 278 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 279 | CLANG_WARN_EMPTY_BODY = YES; 280 | CLANG_WARN_ENUM_CONVERSION = YES; 281 | CLANG_WARN_INFINITE_RECURSION = YES; 282 | CLANG_WARN_INT_CONVERSION = YES; 283 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 284 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 285 | CLANG_WARN_UNREACHABLE_CODE = YES; 286 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 287 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 288 | COPY_PHASE_STRIP = NO; 289 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 290 | ENABLE_NS_ASSERTIONS = NO; 291 | ENABLE_STRICT_OBJC_MSGSEND = YES; 292 | GCC_C_LANGUAGE_STANDARD = gnu99; 293 | GCC_NO_COMMON_BLOCKS = YES; 294 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 295 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 296 | GCC_WARN_UNDECLARED_SELECTOR = YES; 297 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 298 | GCC_WARN_UNUSED_FUNCTION = YES; 299 | GCC_WARN_UNUSED_VARIABLE = YES; 300 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 301 | MTL_ENABLE_DEBUG_INFO = NO; 302 | SDKROOT = iphoneos; 303 | VALIDATE_PRODUCT = YES; 304 | }; 305 | name = Release; 306 | }; 307 | 8AB2C6FE1E65175E0018E74E /* Debug */ = { 308 | isa = XCBuildConfiguration; 309 | buildSettings = { 310 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 311 | INFOPLIST_FILE = CFMultistageDropdownMenuView/Info.plist; 312 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 313 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 314 | PRODUCT_BUNDLE_IDENTIFIER = com.CoderPeak.CFMultistageDropdownMenuView; 315 | PRODUCT_NAME = "$(TARGET_NAME)"; 316 | }; 317 | name = Debug; 318 | }; 319 | 8AB2C6FF1E65175E0018E74E /* Release */ = { 320 | isa = XCBuildConfiguration; 321 | buildSettings = { 322 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 323 | INFOPLIST_FILE = CFMultistageDropdownMenuView/Info.plist; 324 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 325 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 326 | PRODUCT_BUNDLE_IDENTIFIER = com.CoderPeak.CFMultistageDropdownMenuView; 327 | PRODUCT_NAME = "$(TARGET_NAME)"; 328 | }; 329 | name = Release; 330 | }; 331 | /* End XCBuildConfiguration section */ 332 | 333 | /* Begin XCConfigurationList section */ 334 | 8AB2C6E11E65175E0018E74E /* Build configuration list for PBXProject "CFMultistageDropdownMenuView" */ = { 335 | isa = XCConfigurationList; 336 | buildConfigurations = ( 337 | 8AB2C6FB1E65175E0018E74E /* Debug */, 338 | 8AB2C6FC1E65175E0018E74E /* Release */, 339 | ); 340 | defaultConfigurationIsVisible = 0; 341 | defaultConfigurationName = Release; 342 | }; 343 | 8AB2C6FD1E65175E0018E74E /* Build configuration list for PBXNativeTarget "CFMultistageDropdownMenuView" */ = { 344 | isa = XCConfigurationList; 345 | buildConfigurations = ( 346 | 8AB2C6FE1E65175E0018E74E /* Debug */, 347 | 8AB2C6FF1E65175E0018E74E /* Release */, 348 | ); 349 | defaultConfigurationIsVisible = 0; 350 | defaultConfigurationName = Release; 351 | }; 352 | /* End XCConfigurationList section */ 353 | }; 354 | rootObject = 8AB2C6DE1E65175E0018E74E /* Project object */; 355 | } 356 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // CFMultistageDropdownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // CFMultistageDropdownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // 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. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/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 | } -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Assets.xcassets/测试紫箭头.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "测试紫箭头@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "测试紫箭头@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Assets.xcassets/测试紫箭头.imageset/测试紫箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Assets.xcassets/测试紫箭头.imageset/测试紫箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Assets.xcassets/测试紫箭头.imageset/测试紫箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Assets.xcassets/测试紫箭头.imageset/测试紫箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Assets.xcassets/测试红箭头.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "测试红箭头@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "测试红箭头@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Assets.xcassets/测试红箭头.imageset/测试红箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Assets.xcassets/测试红箭头.imageset/测试红箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Assets.xcassets/测试红箭头.imageset/测试红箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Assets.xcassets/测试红箭头.imageset/测试红箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/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 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/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 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/天蓝箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/天蓝箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/天蓝箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/天蓝箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/橙箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/橙箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/橙箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/橙箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/淡紫箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/淡紫箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/淡紫箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/淡紫箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/深灰箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/深灰箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/深灰箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/深灰箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/深绿箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/深绿箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/深绿箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/深绿箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/深蓝箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/深蓝箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/深蓝箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/深蓝箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/灰箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/灰箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/灰箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/灰箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/白箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/白箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/白箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/白箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/粉箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/粉箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/粉箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/粉箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/紫箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/紫箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/紫箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/紫箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/红箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/红箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/红箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/红箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/绿箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/绿箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/绿箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/绿箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/黄箭头@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/黄箭头@2x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/黄箭头@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/CFMultistageDropdownMenuView.bundle/黄箭头@3x.png -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | CFMultistageDropdownMenuView 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Lib/CFLabelOnLeftButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // CFLabelOnLeftButton.h 3 | // CFDropDownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CFLabelOnLeftButton : UIButton 12 | 13 | + (instancetype)createButtonWithImageName:(NSString *)imgName title:(NSString *)title titleColor:(UIColor *)titleColor frame:(CGRect)btnFrame target:(id)target action:(SEL)action; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Lib/CFLabelOnLeftButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // CFLabelOnLeftButton.m 3 | // CFDropDownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #import "CFLabelOnLeftButton.h" 10 | #import "CFMacro.h" 11 | #import "UIView+CFFrame.h" 12 | 13 | 14 | @implementation CFLabelOnLeftButton 15 | 16 | - (instancetype)initWithFrame:(CGRect)frame 17 | { 18 | if (self = [super initWithFrame:frame]) { 19 | self.titleLabel.textAlignment = NSTextAlignmentCenter; 20 | 21 | // 默认设置 22 | [self setTitleColor:CF_Color_TextBlackColor forState:UIControlStateNormal]; 23 | self.titleLabel.font = CF_Font_15; 24 | 25 | 26 | } 27 | return self; 28 | } 29 | 30 | + (instancetype)createButtonWithImageName:(NSString *)imgName title:(NSString *)title titleColor:(UIColor *)titleColor frame:(CGRect)btnFrame target:(id)target action:(SEL)action 31 | { 32 | CFLabelOnLeftButton *btn = [self buttonWithType:UIButtonTypeCustom]; 33 | 34 | [btn setTitle:title forState:UIControlStateNormal]; 35 | btn.titleLabel.textAlignment = NSTextAlignmentCenter; 36 | 37 | [btn setImage:[UIImage imageNamed:imgName] forState:UIControlStateNormal]; 38 | [btn setTitleColor:titleColor forState:UIControlStateNormal]; 39 | 40 | [btn sizeToFit]; 41 | btn.frame = btnFrame; 42 | [btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; 43 | 44 | return btn; 45 | } 46 | 47 | - (void)layoutSubviews 48 | { 49 | [super layoutSubviews]; 50 | 51 | 52 | CGFloat imageWidth = self.imageView.cf_width+1; 53 | CGFloat labelWidth = self.titleLabel.cf_width+1; 54 | 55 | // 图片 位置(右) 56 | self.imageEdgeInsets = UIEdgeInsetsMake(0, labelWidth, 0, -labelWidth); 57 | 58 | 59 | // 文字 位置(左边) 60 | self.titleEdgeInsets = UIEdgeInsetsMake(0, -imageWidth, 0, imageWidth); 61 | 62 | 63 | } 64 | 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Lib/CFMacro.h: -------------------------------------------------------------------------------- 1 | // 2 | // CFMacro.h 3 | // CFDropDownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #ifndef CFMacro_h 10 | #define CFMacro_h 11 | 12 | /** 13 | * 资源图片路径相关 宏 14 | */ 15 | #define CFMultistageDropdownMenuViewSrcName(file) [@"CFMultistageDropdownMenuView.bundle" stringByAppendingPathComponent:file] 16 | // 当支持cocoapods导入时的图片资源路径 17 | #define CFMultistageDropdownMenuViewFrameworkSrcName(file) [@"Frameworks/CFMultistageDropdownMenuView.framework/CFMultistageDropdownMenuView.bundle" stringByAppendingPathComponent:file] 18 | 19 | /** 20 | * 颜色相关 宏 21 | */ 22 | #define UIColorFromHex(hexValue) [UIColor colorWithRed:((float)((hexValue & 0xFF0000) >> 16))/255.0 green:((float)((hexValue & 0xFF00) >> 8))/255.0 blue:((float)(hexValue & 0xFF))/255.0 alpha:1.0] 23 | 24 | #define CF_Color_TextBlackColor UIColorFromHex(0x333333) 25 | 26 | #define CF_Color_TextDarkGrayColor UIColorFromHex(0x666666) 27 | 28 | #define CF_Color_TextGrayColor UIColorFromHex(0x999999) 29 | 30 | #define CF_Color_SepertLineColor UIColorFromHex(0xdddddd) 31 | #define CF_Color_MainColor UIColorFromHex(0x00A0FF) // 默认的选中颜色-蓝 32 | #define CF_Color_DefalutBackGroundColor UIColorFromHex(0xEFEFF4) //.. 33 | 34 | #define RGBA(r,g,b,a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a] 35 | #define RGB(r,g,b) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:1.0f] 36 | // 随机色 37 | #define CFRandomColor RGBA(arc4random_uniform(255), arc4random_uniform(255), arc4random_uniform(255), 1.0) 38 | 39 | // 分割线颜色 40 | #define CFLineColor UIColorFromHex(0xEFEFF4) 41 | 42 | /** 43 | * 字体相关 宏 44 | */ 45 | #define CF_Font_15 [UIFont systemFontOfSize:15] 46 | #define CF_BOLDFont_15 [UIFont boldSystemFontOfSize:15] 47 | 48 | #define CF_Font_14 [UIFont systemFontOfSize:14] 49 | #define CF_BOLDFont_14 [UIFont boldSystemFontOfSize:14] 50 | 51 | /** 52 | * 尺寸相关 宏 53 | */ 54 | #define CFScreenWidth ([UIScreen mainScreen].bounds.size.width) 55 | #define CFScreenHeight ([UIScreen mainScreen].bounds.size.height) 56 | 57 | #endif /* CFMacro_h */ 58 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Lib/CFMultistageConditionTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CFMultistageConditionTableView.h 3 | // CFMultistageDropdownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol CFMultistageConditionTableViewDelegate 12 | 13 | @required 14 | - (void)selecteWithLeftIndex:(NSInteger)leftIndex right:(NSInteger)rightIndex; 15 | - (void)hideTableView; 16 | @end 17 | 18 | @interface CFMultistageConditionTableView : UIView 19 | 20 | @property (nonatomic, strong) id delegate; 21 | 22 | /** 23 | * 数据源--二维数组 24 | * 一级列表数据源 25 | */ 26 | @property (nonatomic, strong) NSMutableArray *dataSourceLeftArray; 27 | /** 28 | * 数据源--二维数组 29 | * 二级列表数据源 30 | */ 31 | @property (nonatomic, strong) NSMutableArray *dataSourceRightArray; 32 | 33 | /* 最大展示行数 -- 不传-默认6条 */ 34 | @property (nonatomic, assign) NSInteger maxRowCount; 35 | 36 | // 显示下拉菜单 (根据选中的 索引) 37 | - (void)showTableViewWithSelectedTitleIndex:(NSInteger)titleIndex selectedLeftIndex:(NSInteger)leftIndex selectedRightIndex:(NSInteger)rightIndex; 38 | 39 | - (void)hide; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Lib/CFMultistageConditionTableView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CFMultistageConditionTableView.m 3 | // CFMultistageDropdownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #import "CFMultistageConditionTableView.h" 10 | #import "UIView+CFFrame.h" 11 | #import "CFMacro.h" 12 | 13 | @interface CFMultistageConditionTableView () 14 | /* 二级的 左边(一级) 当下拉列表为一级时,没有leftTableView/只有rightTableView */ 15 | @property (nonatomic, strong) UITableView *leftTableView; 16 | // 一维数组 17 | @property (nonatomic, strong) NSMutableArray *leftArray; 18 | 19 | /* 二级的 右边(二级) */ 20 | @property (nonatomic, strong) UITableView *rightTableView; 21 | // 二维数组 22 | @property (nonatomic, strong) NSMutableArray *rightArray; 23 | 24 | // 左边-一级选中的索引 25 | @property (nonatomic, assign) NSInteger leftSelectedIndex; 26 | 27 | /* 上次选中索引 左边 */ 28 | @property (nonatomic, strong) NSIndexPath *leftLastSelectedIndexPath; 29 | /* 上次选中索引 右边 */ 30 | @property (nonatomic, strong) NSIndexPath *rightLastSelectedIndexPath; 31 | 32 | /* 计算tableView完美高度使用 展示 完美行数 */ 33 | @property (nonatomic, assign) NSInteger perfectRowCount; 34 | 35 | /* 两列时 中间分割线 */ 36 | @property (nonatomic, strong) UIView *midLineV; 37 | 38 | 39 | 40 | @end 41 | 42 | static NSString *leftCellId = @"leftCellId"; 43 | static NSString *rightCellId = @"rightCellId"; 44 | #define CELLHEIGHT 44.0 45 | 46 | #define defaultMaxRowCount 6 // 默认最大6行 47 | #define MAXROWCOUNT ((self.maxRowCount)?:defaultMaxRowCount) // 最多行数 48 | 49 | @implementation CFMultistageConditionTableView 50 | 51 | - (instancetype)initWithFrame:(CGRect)frame 52 | { 53 | if (self = [super initWithFrame:frame]) { 54 | 55 | 56 | [self addSubview:self.leftTableView]; 57 | [self addSubview:self.rightTableView]; 58 | 59 | 60 | _midLineV = [[UIView alloc] initWithFrame:CGRectMake(CFScreenWidth/2, 0, 1, CELLHEIGHT*MAXROWCOUNT)]; 61 | _midLineV.backgroundColor = CFLineColor; 62 | [self addSubview:_midLineV]; 63 | 64 | // 要 65 | [self setClipsToBounds:YES]; 66 | } 67 | return self; 68 | } 69 | 70 | #pragma mark - lazy 71 | /* leftTableView */ 72 | - (UITableView *)leftTableView 73 | { 74 | if (!_leftTableView) { 75 | _leftTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.cf_width/2, 1000)]; 76 | _leftTableView.backgroundColor = [UIColor whiteColor]; 77 | _leftTableView.delegate = self; 78 | _leftTableView.dataSource = self; 79 | _leftTableView.separatorInset = UIEdgeInsetsZero; 80 | _leftTableView.separatorColor = CFLineColor; 81 | [_leftTableView setShowsVerticalScrollIndicator:NO]; 82 | 83 | 84 | } 85 | return _leftTableView; 86 | } 87 | 88 | /* rightTableView */ 89 | - (UITableView *)rightTableView 90 | { 91 | if (!_rightTableView) { 92 | _rightTableView = [[UITableView alloc] initWithFrame:CGRectMake(self.cf_width/2, 0, self.cf_width/2, 1000)]; 93 | _rightTableView.backgroundColor = [UIColor whiteColor]; 94 | _rightTableView.delegate = self; 95 | _rightTableView.dataSource = self; 96 | _rightTableView.separatorInset = UIEdgeInsetsZero; 97 | _rightTableView.separatorColor = CFLineColor; 98 | [_rightTableView setShowsVerticalScrollIndicator:NO]; 99 | 100 | 101 | } 102 | return _rightTableView; 103 | } 104 | 105 | #pragma mark - setter 106 | 107 | 108 | - (void)removeSubviewsOfCell:(UITableViewCell*)cell { 109 | NSArray *subviews = [[NSArray alloc] initWithArray:cell.contentView.subviews]; 110 | for (UIView *subview in subviews) { 111 | [subview removeFromSuperview]; 112 | } 113 | } 114 | 115 | #pragma mark - UITableViewDataSource 116 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 117 | { 118 | return 1; 119 | } 120 | 121 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 122 | { 123 | if (tableView == _leftTableView) { 124 | return _leftArray.count; 125 | } else if (tableView == _rightTableView) { 126 | 127 | NSArray *array = [_rightArray objectAtIndex:_leftSelectedIndex]; 128 | return array.count; 129 | 130 | } 131 | return 0; 132 | } 133 | 134 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 135 | { 136 | UITableViewCell *cell = nil; 137 | if (tableView == _leftTableView) { 138 | 139 | cell = [tableView dequeueReusableCellWithIdentifier:leftCellId]; 140 | if (!cell) { 141 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:leftCellId]; 142 | } 143 | [self removeSubviewsOfCell:cell]; 144 | if (_leftArray.count > 0) { 145 | cell.textLabel.text = [_leftArray objectAtIndex:indexPath.row]; 146 | } 147 | 148 | } else if (tableView == _rightTableView){ 149 | 150 | cell = [tableView dequeueReusableCellWithIdentifier:rightCellId]; 151 | if (cell == nil) { 152 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:rightCellId]; 153 | } 154 | [self removeSubviewsOfCell:cell]; 155 | NSArray *array = [_rightArray objectAtIndex:_leftSelectedIndex]; 156 | 157 | cell.textLabel.text = [array objectAtIndex:indexPath.row]; 158 | 159 | cell.textLabel.highlightedTextColor = CF_Color_MainColor; 160 | 161 | } 162 | 163 | 164 | UIView *selectView = [[UIView alloc] initWithFrame:cell.contentView.bounds]; 165 | selectView.backgroundColor = CF_Color_DefalutBackGroundColor; 166 | UIView *lineV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 3, CELLHEIGHT)]; 167 | lineV.backgroundColor = CF_Color_MainColor; 168 | [selectView addSubview:lineV]; 169 | 170 | cell.selectedBackgroundView = selectView; 171 | cell.backgroundColor = [UIColor whiteColor]; 172 | 173 | cell.textLabel.highlightedTextColor = CF_Color_MainColor; 174 | cell.textLabel.font = [UIFont systemFontOfSize:13]; 175 | cell.textLabel.textColor = CF_Color_TextBlackColor; 176 | return cell; 177 | } 178 | 179 | 180 | 181 | #pragma mark - UITableViewDelegate 182 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 183 | { 184 | return CELLHEIGHT; 185 | } 186 | 187 | 188 | 189 | 190 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 191 | { 192 | 193 | UITableViewCell *cell= [tableView cellForRowAtIndexPath:indexPath]; 194 | 195 | if (tableView == _leftTableView && _leftArray.count > 0) { 196 | // 点击 一级菜单 197 | _leftSelectedIndex = indexPath.row; 198 | 199 | // 当前选中加粗 200 | cell.textLabel.font = CF_BOLDFont_14; 201 | 202 | if (self.leftLastSelectedIndexPath) { 203 | UITableViewCell *lastSelectedcell= [tableView cellForRowAtIndexPath:self.leftLastSelectedIndexPath]; 204 | // 上一次选中 加粗效果取消 205 | lastSelectedcell.textLabel.font = CF_Font_14; 206 | } 207 | self.leftLastSelectedIndexPath = indexPath; 208 | 209 | [_rightTableView reloadData]; 210 | 211 | } else { 212 | 213 | cell.textLabel.font = CF_BOLDFont_14; 214 | 215 | if (self.rightLastSelectedIndexPath) { 216 | UITableViewCell *lastSelectedcell= [tableView cellForRowAtIndexPath:self.rightLastSelectedIndexPath]; 217 | lastSelectedcell.textLabel.font = CF_Font_14; 218 | } 219 | self.rightLastSelectedIndexPath = indexPath; 220 | 221 | 222 | // 最终选中条件 223 | [self selectAtIndex:indexPath.row]; 224 | } 225 | } 226 | 227 | 228 | #pragma mark - 处理逻辑 229 | // 最终选中条件 230 | - (void)selectAtIndex:(NSInteger)index 231 | { 232 | if (self.delegate && [self.delegate respondsToSelector:@selector(selecteWithLeftIndex:right:)]) { 233 | NSInteger leftSelectedIndex = _leftSelectedIndex > 0 ? _leftSelectedIndex : 0; 234 | 235 | [self.delegate selecteWithLeftIndex:leftSelectedIndex right:index]; 236 | } 237 | 238 | } 239 | 240 | 241 | // 显示下拉菜单 (根据选中的 索引) 242 | - (void)showTableViewWithSelectedTitleIndex:(NSInteger)titleIndex selectedLeftIndex:(NSInteger)leftIndex selectedRightIndex:(NSInteger)rightIndex 243 | { 244 | // 一维数组 245 | _leftArray = [[NSMutableArray alloc] initWithArray:[_dataSourceLeftArray objectAtIndex:titleIndex]]; 246 | // 二维数组 247 | _rightArray = [[NSMutableArray alloc] initWithArray:[_dataSourceRightArray objectAtIndex:titleIndex]]; 248 | 249 | // 显示 当前title下的 最后一次选中的位置 250 | [self showLastSelectedWithLeftIndex:leftIndex rightIndex:rightIndex]; 251 | 252 | // 计算完美高度 253 | NSInteger maxRightCount = 0; 254 | NSMutableArray *maxLeftCountArr = [NSMutableArray array]; 255 | NSMutableArray *maxRightCountArr = [NSMutableArray array]; 256 | for (NSInteger i = 0; i < _dataSourceRightArray.count; i++) { 257 | NSArray *leftitems = _dataSourceLeftArray[i]; 258 | [maxLeftCountArr addObject:[NSString stringWithFormat:@"%zd", leftitems.count]]; 259 | 260 | NSArray *rightitems = _dataSourceRightArray[i]; 261 | if ([rightitems isKindOfClass:[NSArray class]] && rightitems.count>1) { 262 | for (NSInteger j = 0; j= maxCount || [maxRightCountArr[i] intValue] >= maxCount) { 281 | [countArr addObject:@(maxCount)]; 282 | } else { 283 | [countArr addObject:MAX(maxLeftCountArr[i], maxRightCountArr[i])]; 284 | } 285 | } 286 | // [8,7,6] 287 | NSLog(@"countArr--%@", countArr); 288 | 289 | self.perfectRowCount = [[countArr objectAtIndex:titleIndex] integerValue]; 290 | 291 | NSLog(@"self.perfectRowCount--%zd", self.perfectRowCount); 292 | 293 | 294 | // 展示 295 | [self showConditionTableView]; 296 | [UIView animateWithDuration:0.25 animations:^{ 297 | 298 | self.cf_height = MIN(CELLHEIGHT*MAXROWCOUNT, CELLHEIGHT*self.perfectRowCount); 299 | }]; 300 | 301 | 302 | } 303 | 304 | // 展示 305 | - (void)showConditionTableView 306 | { 307 | CGFloat perfectHeight = MIN(CELLHEIGHT*MAXROWCOUNT, CELLHEIGHT*self.perfectRowCount); 308 | 309 | 310 | if (_leftArray.count == 0) { // 一级菜单 311 | _leftTableView.hidden = YES; 312 | 313 | _rightTableView.frame = CGRectMake( 0, 0, CFScreenWidth, perfectHeight); 314 | self.midLineV.hidden = YES; 315 | 316 | } else { // 二级菜单 317 | _leftTableView.hidden = NO; 318 | _leftTableView.cf_height = perfectHeight; 319 | _rightTableView.frame = CGRectMake(CFScreenWidth / 2, 0, CFScreenWidth / 2, perfectHeight); 320 | self.midLineV.hidden = NO; 321 | } 322 | 323 | } 324 | 325 | // 显示 当前title下的 最后一次选中的位置 326 | - (void)showLastSelectedWithLeftIndex:(NSInteger)leftIndex rightIndex:(NSInteger)rightIndex { 327 | 328 | if (_leftArray.count > 0) { // 二级分类的 329 | [_leftTableView reloadData]; 330 | NSIndexPath *leftSelectedIndexPath = [NSIndexPath indexPathForRow:leftIndex inSection:0]; 331 | [_leftTableView selectRowAtIndexPath:leftSelectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; 332 | 333 | // 上次选中的 行 字体改变(加粗) 334 | UITableViewCell *cell = [_leftTableView cellForRowAtIndexPath:leftSelectedIndexPath]; 335 | cell.textLabel.font = CF_BOLDFont_14; 336 | self.leftLastSelectedIndexPath = leftSelectedIndexPath; 337 | 338 | } 339 | 340 | _leftSelectedIndex = leftIndex; 341 | 342 | [_rightTableView reloadData]; 343 | NSIndexPath *rightSelectedIndexPath = [NSIndexPath indexPathForRow:rightIndex inSection:0]; 344 | 345 | // 上次选中的 行 字体改变(加粗) 346 | UITableViewCell *cell = [_rightTableView cellForRowAtIndexPath:rightSelectedIndexPath]; 347 | cell.textLabel.font = CF_BOLDFont_14; 348 | self.rightLastSelectedIndexPath = rightSelectedIndexPath; 349 | 350 | 351 | [_rightTableView selectRowAtIndexPath:rightSelectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; 352 | } 353 | 354 | // 隐藏 355 | - (void)hide { 356 | [UIView animateWithDuration:0.05 animations:^{ 357 | self.alpha = 0.0; 358 | self.cf_height = 0; 359 | 360 | } completion:^(BOOL finish){ 361 | [self removeFromSuperview]; 362 | }]; 363 | } 364 | 365 | @end 366 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Lib/CFMultistageDropdownMenuView.h: -------------------------------------------------------------------------------- 1 | // 2 | // CFMultistageDropdownMenuView.h 3 | // CFMultistageDropdownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CFMultistageDropdownMenuView; 12 | @protocol CFMultistageDropdownMenuViewDelegate 13 | 14 | @optional 15 | // 能得到 当前选中的是第几个titleButton(即第几个分类下的条件) / 一级菜单 当前选中的索引和内容 / 二级菜单 当前选中的索引和内容 16 | - (void)multistageDropdownMenuView:(CFMultistageDropdownMenuView *)multistageDropdownMenuView selecteTitleButtonIndex:(NSInteger)titleButtonIndex conditionLeftIndex:(NSInteger)leftIndex conditionRightIndex:(NSInteger)rightIndex; 17 | 18 | // 能得到 当前选中的 内容 / 整个titleBar上 所有展示的内容 19 | - (void)multistageDropdownMenuView:(CFMultistageDropdownMenuView *)multistageDropdownMenuView selectTitleButtonWithCurrentTitle:(NSString *)currentTitle currentTitleArray:(NSArray *)currentTitleArray; 20 | 21 | @end 22 | 23 | @interface CFMultistageDropdownMenuView : UIView 24 | 25 | /* 分类按钮 数组 */ 26 | @property (nonatomic, strong) NSMutableArray *titleButtonArray; 27 | 28 | /* 默认显示的 */ 29 | @property (nonatomic, strong) NSArray *defaulTitleArray; 30 | 31 | /* 分类内容 动画起始位置 */ 32 | @property (nonatomic, assign) CGFloat startY; 33 | 34 | /* 刚进来时 默认选中的分类索引 titleBar上按钮的索引 */ 35 | @property (nonatomic, assign) NSInteger defaultSelectedTitleButtonIndex; 36 | 37 | /** 38 | * 数据源--二维数组 39 | * 一级列表数据源 40 | */ 41 | @property (nonatomic, strong) NSMutableArray *dataSourceLeftArray; 42 | /** 43 | * 数据源--二维数组 44 | * 二级列表数据源 45 | */ 46 | @property (nonatomic, strong) NSMutableArray *dataSourceRightArray; 47 | 48 | /** 49 | * 设置数据源 50 | */ 51 | - (void)setupDataSourceLeftArray:(NSArray *)leftArray rightArray:(NSArray *)rightArray; 52 | 53 | 54 | /* 最大展示行数 -- 不传-默认6条 */ 55 | @property (nonatomic, assign) NSInteger maxRowCount; 56 | 57 | /* 选中状态和未选中状态 58 | * 默认 选中状态:天蓝文字,天蓝箭头 59 | * 未选中状态:黑文字,灰箭头 60 | * 使用注意: 参数格式 61 | @{ 62 | @"selected" : @[[UIColor BlueColor], @"蓝箭头"], // 选中状态 63 | @"normal" : @[[UIColor BlackColor], @"黑箭头"] // 未选中状态 64 | }; 65 | 可以不传 / 也可以只传其中一对键值对 / 也可以都传 (key必须为@"selected" @"normal") 66 | */ 67 | @property (nonatomic, strong) NSDictionary *stateConfigDict; 68 | 69 | 70 | /* 代理 */ 71 | @property (nonatomic, weak) id delegate; 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Lib/CFMultistageDropdownMenuView.m: -------------------------------------------------------------------------------- 1 | // 2 | // CFMultistageDropdownMenuView.m 3 | // CFMultistageDropdownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #import "CFMultistageDropdownMenuView.h" 10 | #import "CFMacro.h" 11 | #import "CFLabelOnLeftButton.h" 12 | #import "UIView+CFFrame.h" 13 | #import "CFMultistageConditionTableView.h" 14 | 15 | #define kViewTagAdd 999 // 所有tag都加上这个 防止出现为0的tag 16 | 17 | @interface CFMultistageDropdownMenuView () 18 | 19 | /* 分类 titleBar */ 20 | @property (nonatomic, strong) UIView *titleBar; 21 | 22 | /** 数据源--一维数组 (每一列的条件标题) */ 23 | @property (nonatomic, strong) NSArray *showTitleArray; 24 | 25 | /* 整个屏幕的 背景 半透明View */ 26 | @property (nonatomic, strong) UIView *backgroundView; 27 | 28 | /** 29 | * cell为筛选的条件 - 下拉列表 (包含 一级/二级) 30 | */ 31 | @property (nonatomic, strong) CFMultistageConditionTableView *multistageConditionTableView; 32 | 33 | 34 | /* 最后点击的按钮 */ 35 | @property (nonatomic, strong) UIButton *lastClickedButton; 36 | 37 | /* 38 | * 选中的条件 左 右 索引数组 39 | * @[@"3-0", @"0-0", @"0-0"] 40 | */ 41 | @property (nonatomic, strong) NSMutableArray *selectedConditionIndexArray; 42 | 43 | /* titleBar上 当前选中按钮的 索引 */ 44 | @property (nonatomic, assign) NSInteger currentSelectedTitleButtonIndex; 45 | 46 | @end 47 | 48 | #define titleBarHeight 45 49 | 50 | @implementation CFMultistageDropdownMenuView 51 | 52 | - (instancetype)initWithFrame:(CGRect)frame 53 | { 54 | if (self = [super initWithFrame:frame]) { 55 | self.backgroundColor = [UIColor clearColor]; 56 | [self addSubview:self.titleBar]; 57 | } 58 | return self; 59 | } 60 | 61 | #pragma mark - lazy 62 | /* 分类 classifyView */ 63 | - (UIView *)titleBar 64 | { 65 | if (!_titleBar) { 66 | _titleBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CFScreenWidth, titleBarHeight)]; 67 | _titleBar.backgroundColor = [UIColor whiteColor]; 68 | } 69 | return _titleBar; 70 | } 71 | /* 蒙层view */ 72 | - (UIView *)backgroundView 73 | { 74 | if (!_backgroundView) { 75 | _backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, self.startY?:titleBarHeight, CFScreenWidth, CFScreenHeight)]; 76 | _backgroundView.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.5]; 77 | 78 | 79 | UITapGestureRecognizer *tapGest = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hide)]; 80 | [_backgroundView addGestureRecognizer:tapGest]; 81 | 82 | } 83 | return _backgroundView; 84 | } 85 | 86 | - (CFMultistageConditionTableView *)multistageConditionTableView 87 | { 88 | if (!_multistageConditionTableView) { 89 | _multistageConditionTableView = [[CFMultistageConditionTableView alloc] initWithFrame:CGRectMake(0, self.startY?:titleBarHeight, CFScreenWidth, 0)]; 90 | 91 | 92 | _multistageConditionTableView.delegate = self; 93 | 94 | _multistageConditionTableView.dataSourceLeftArray = self.dataSourceLeftArray; 95 | _multistageConditionTableView.dataSourceRightArray = self.dataSourceRightArray; 96 | 97 | _multistageConditionTableView.maxRowCount = self.maxRowCount; 98 | 99 | } 100 | return _multistageConditionTableView; 101 | } 102 | 103 | #pragma mark - setter 104 | - (void)setDefaultSelectedTitleButtonIndex:(NSInteger)defaultSelectedTitleButtonIndex 105 | { 106 | _defaultSelectedTitleButtonIndex = defaultSelectedTitleButtonIndex; 107 | 108 | _selectedConditionIndexArray[self.defaultSelectedTitleButtonIndex] = [NSString stringWithFormat:@"%zd-0", defaultSelectedTitleButtonIndex]; 109 | } 110 | 111 | - (void)setDefaulTitleArray:(NSArray *)defaulTitleArray 112 | { 113 | _defaulTitleArray = defaulTitleArray; 114 | 115 | [self setupTitleBarWithDefaulTitleArray:defaulTitleArray]; 116 | 117 | } 118 | 119 | - (void)setupDataSourceLeftArray:(NSArray *)leftArray rightArray:(NSArray *)rightArray 120 | { 121 | _dataSourceLeftArray = leftArray.mutableCopy; 122 | _dataSourceRightArray = rightArray.mutableCopy; 123 | 124 | } 125 | 126 | - (void)setupTitleBarWithDefaulTitleArray:(NSArray *)defaulTitleArray 127 | { 128 | self.titleButtonArray = [[NSMutableArray alloc] init]; 129 | 130 | CGFloat btnW = CFScreenWidth/defaulTitleArray.count; // -6 留下左边间距 131 | CGFloat btnH = 45; 132 | 133 | // 选中的条件 左 右 索引数组 134 | self.selectedConditionIndexArray = [NSMutableArray arrayWithCapacity:defaulTitleArray.count]; 135 | 136 | for (NSInteger i=0; i 0) { // 二级菜单 214 | // 二级菜单 一级内容 215 | leftString = [leftStringArray objectAtIndex:leftIndex]; 216 | // 217 | if ([rightString isEqualToString:@"全部"]) { 218 | NSInteger btnTag = _lastClickedButton.tag; 219 | UIButton *button = (UIButton *)[self viewWithTag:btnTag]; 220 | [button setTitle:leftString forState:UIControlStateNormal]; 221 | } 222 | } 223 | 224 | // 走代理 处理选中条件后的业务逻辑 225 | if (self.delegate && [self.delegate respondsToSelector:@selector(multistageDropdownMenuView:selecteTitleButtonIndex:conditionLeftIndex:conditionRightIndex:)]) { 226 | [self.delegate multistageDropdownMenuView:self selecteTitleButtonIndex:clickedButtonIndex conditionLeftIndex:leftIndex conditionRightIndex:rightIndex]; 227 | } 228 | 229 | NSMutableArray *currentTitleArray = [NSMutableArray arrayWithCapacity:self.titleButtonArray.count]; 230 | NSArray *btnArr = self.titleButtonArray; 231 | for (UIButton *btn in btnArr) { 232 | [currentTitleArray addObject:btn.titleLabel.text]; 233 | } 234 | NSString *currentTitle = [currentTitleArray objectAtIndex:clickedButtonIndex]; 235 | // 走代理 处理选中条件后的业务逻辑 236 | if (self.delegate && [self.delegate respondsToSelector:@selector(multistageDropdownMenuView:selectTitleButtonWithCurrentTitle:currentTitleArray:)]) { 237 | [self.delegate multistageDropdownMenuView:self selectTitleButtonWithCurrentTitle:currentTitle currentTitleArray:currentTitleArray]; 238 | } 239 | 240 | } 241 | 242 | // 选中条件后 标题分类改变 243 | - (void)changeButtonTitleWithString:(NSString *)str{ 244 | NSInteger btnTag = _lastClickedButton.tag; 245 | UIButton *button = (UIButton *)[self viewWithTag:btnTag]; 246 | [button setTitle:str forState:UIControlStateNormal]; 247 | button.titleLabel.font = CF_BOLDFont_15; 248 | 249 | 250 | NSString *btnImageName = @""; 251 | UIColor *btnTitleColor = nil; 252 | if (self.stateConfigDict[@"selected"]) { 253 | btnImageName = self.stateConfigDict[@"selected"][1]; 254 | btnTitleColor = self.stateConfigDict[@"selected"][0]; 255 | 256 | btnImageName = [NSString stringWithFormat:@"%@.png", self.stateConfigDict[@"selected"][1]]; 257 | 258 | 259 | } else { 260 | // 使用CFMultistageDropdownMenuView.bundle自带的 261 | btnImageName = CFMultistageDropdownMenuViewSrcName(@"天蓝箭头.png")?:CFMultistageDropdownMenuViewFrameworkSrcName(@"天蓝箭头.png"); 262 | btnTitleColor = CF_Color_MainColor; 263 | } 264 | 265 | [button setTitleColor:btnTitleColor forState:UIControlStateNormal]; 266 | [button setImage:[UIImage imageNamed:btnImageName] forState:UIControlStateNormal]; 267 | 268 | 269 | 270 | } 271 | 272 | #pragma mark - title按钮点击 273 | - (void)titleButtonClicked:(UIButton *)btn 274 | { 275 | _lastClickedButton = btn; 276 | 277 | // 移除子控件 278 | [self removeSubviews]; 279 | 280 | 281 | // 显示下拉 282 | [self showConditionTableViewWhenClickedButton:btn]; 283 | // 按钮箭头动画 284 | [self animationWhenClickTitleButton:btn]; 285 | 286 | // 287 | //[UIView animateWithDuration:0.25 animations:^{ 288 | // _lastClickedButton.imageView.transform = CGAffineTransformMakeRotation(0.01); 289 | //}]; 290 | } 291 | 292 | 293 | 294 | #pragma mark -- 295 | // 点击 title 按钮 后 296 | - (void)showConditionTableViewWhenClickedButton:(UIButton *)btn { 297 | [self.superview insertSubview:self.backgroundView atIndex:0]; 298 | [self.superview addSubview:self.multistageConditionTableView]; 299 | 300 | _currentSelectedTitleButtonIndex = btn.tag - kViewTagAdd; 301 | 302 | // @"3-0"(二级, -左边不一定为0) / @"0-0"(一级, -左边一定为0) / @"0-3" 303 | NSString *currentSelectedIndexStr = [_selectedConditionIndexArray objectAtIndex:_currentSelectedTitleButtonIndex]; 304 | 305 | NSArray *arr = [currentSelectedIndexStr componentsSeparatedByString:@"-"]; 306 | NSInteger leftIndex = [[arr objectAtIndex:0] integerValue]; 307 | NSInteger rightIndex = [[arr objectAtIndex:1] integerValue]; 308 | 309 | // 根据 选中状态 下拉显示tableView 310 | [self.multistageConditionTableView showTableViewWithSelectedTitleIndex:_currentSelectedTitleButtonIndex selectedLeftIndex:leftIndex selectedRightIndex:rightIndex]; 311 | 312 | 313 | 314 | } 315 | // 点击按钮箭头动画 316 | - (void)animationWhenClickTitleButton:(UIButton *)btn 317 | { 318 | 319 | 320 | for (UIButton *subBtn in self.titleButtonArray) { 321 | if (subBtn==btn) { 322 | [UIView animateWithDuration:0.25 animations:^{ 323 | subBtn.imageView.transform = CGAffineTransformMakeRotation(M_PI); 324 | subBtn.userInteractionEnabled = NO; 325 | }]; 326 | 327 | } else { 328 | [UIView animateWithDuration:0.25 animations:^{ 329 | subBtn.imageView.transform = CGAffineTransformMakeRotation(0); 330 | subBtn.userInteractionEnabled = YES; 331 | }]; 332 | } 333 | } 334 | 335 | } 336 | 337 | 338 | - (void)removeSubviews 339 | { 340 | 341 | // 此处 千万不能写作 !self.backgroundView?:[self.backgroundView removeFromSuperview]; 会崩 342 | !_backgroundView?:[_backgroundView removeFromSuperview]; 343 | _backgroundView=nil; 344 | 345 | !_multistageConditionTableView?:[_multistageConditionTableView removeFromSuperview]; 346 | _multistageConditionTableView=nil; 347 | 348 | self.showTitleArray = nil; 349 | 350 | } 351 | 352 | - (void)hide 353 | { 354 | [self.backgroundView removeFromSuperview]; 355 | [self.multistageConditionTableView hide]; 356 | 357 | [UIView animateWithDuration:0.25 animations:^{ 358 | _lastClickedButton.imageView.transform = CGAffineTransformMakeRotation(0); 359 | _lastClickedButton.userInteractionEnabled = YES; 360 | }]; 361 | 362 | 363 | } 364 | 365 | @end 366 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Lib/UIView+CFFrame.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+CFFrame.h 3 | // CFDropDownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (CFFrame) 12 | 13 | @property (nonatomic, assign) CGFloat cf_x; 14 | @property (nonatomic, assign) CGFloat cf_y; 15 | @property (nonatomic, assign) CGFloat cf_centerX; 16 | @property (nonatomic, assign) CGFloat cf_centerY; 17 | @property (nonatomic, assign) CGFloat cf_width; 18 | @property (nonatomic, assign) CGFloat cf_height; 19 | 20 | @property (nonatomic, assign, readonly) CGFloat cf_maxX; 21 | @property (nonatomic, assign, readonly) CGFloat cf_maxY; 22 | 23 | @property (nonatomic, assign) CGPoint cf_origin; 24 | @property (nonatomic, assign) CGSize cf_size; 25 | 26 | + (instancetype)viewWithX:(CGFloat)x y:(CGFloat)y width:(CGFloat)width height:(CGFloat)height; 27 | + (instancetype)viewWithFrame:(CGRect)frame; 28 | + (instancetype)viewWithFrame:(CGRect)frame backgroundColor:(UIColor *)color; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/Lib/UIView+CFFrame.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+CFFrame.m 3 | // CFDropDownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #import "UIView+CFFrame.h" 10 | 11 | @implementation UIView (CFFrame) 12 | 13 | //---------- X ----------// 14 | - (void)setCf_x:(CGFloat)cf_x { 15 | CGRect frame = self.frame; 16 | frame.origin.x = cf_x; 17 | self.frame = frame; 18 | } 19 | 20 | - (CGFloat)cf_x { 21 | return self.frame.origin.x; 22 | } 23 | 24 | //---------- Y ----------// 25 | - (void)setCf_y:(CGFloat)cf_y { 26 | CGRect frame = self.frame; 27 | frame.origin.y = cf_y; 28 | self.frame = frame; 29 | } 30 | 31 | - (CGFloat)cf_y { 32 | return self.frame.origin.y; 33 | } 34 | 35 | //---------- CenterX ----------// 36 | - (void)setCf_centerX:(CGFloat)centerX { 37 | CGPoint center = self.center; 38 | center.x = centerX; 39 | self.center = center; 40 | } 41 | 42 | - (CGFloat)cf_centerX { 43 | return self.center.x; 44 | } 45 | 46 | //---------- CenterY ----------// 47 | - (void)setCf_centerY:(CGFloat)centerY { 48 | CGPoint center = self.center; 49 | center.y = centerY; 50 | self.center = center; 51 | } 52 | 53 | - (CGFloat)cf_centerY { 54 | return self.center.y; 55 | } 56 | 57 | //---------- Width ----------// 58 | - (void)setCf_width:(CGFloat)width { 59 | CGRect frame = self.frame; 60 | frame.size.width = width; 61 | self.frame = frame; 62 | } 63 | 64 | - (CGFloat)cf_width { 65 | return self.frame.size.width; 66 | } 67 | 68 | //---------- Height ----------// 69 | - (void)setCf_height:(CGFloat)height { 70 | CGRect frame = self.frame; 71 | frame.size.height = height; 72 | self.frame = frame; 73 | } 74 | 75 | - (CGFloat)cf_height { 76 | return self.frame.size.height; 77 | } 78 | 79 | //---------- Origin ----------// 80 | - (void)setCf_origin:(CGPoint)origin { 81 | CGRect frame = self.frame; 82 | frame.origin = origin; 83 | self.frame = frame; 84 | } 85 | 86 | - (CGPoint)cf_origin { 87 | return self.frame.origin; 88 | } 89 | 90 | //---------- Size ----------// 91 | - (void)setCf_size:(CGSize)size { 92 | CGRect frame = self.frame; 93 | frame.size = size; 94 | self.frame = frame; 95 | } 96 | 97 | - (CGSize)cf_size { 98 | return self.frame.size; 99 | } 100 | 101 | - (CGFloat)cf_maxX { 102 | return self.frame.size.width + self.frame.origin.x; 103 | } 104 | 105 | - (CGFloat)cf_maxY { 106 | return self.frame.size.height + self.frame.origin.y; 107 | } 108 | 109 | 110 | + (instancetype)viewWithX:(CGFloat)x y:(CGFloat)y width:(CGFloat)width height:(CGFloat)height 111 | { 112 | return [[self alloc] initWithFrame:CGRectMake(x, y, width, height)]; 113 | } 114 | 115 | + (instancetype)viewWithFrame:(CGRect)frame 116 | { 117 | return [[UIView alloc] initWithFrame:frame]; 118 | } 119 | 120 | + (instancetype)viewWithFrame:(CGRect)frame backgroundColor:(UIColor *)color 121 | { 122 | UIView *view = [self viewWithFrame:frame]; 123 | view.backgroundColor = color; 124 | return view; 125 | } 126 | 127 | @end 128 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // CFMultistageDropdownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // CFMultistageDropdownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "CFMacro.h" 11 | #import "CFMultistageDropdownMenuView.h" 12 | 13 | @interface ViewController () 14 | 15 | /* CFMultistageDropdownMenuView */ 16 | @property (nonatomic, strong) CFMultistageDropdownMenuView *multistageDropdownMenuView; 17 | 18 | @end 19 | 20 | @implementation ViewController 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | 25 | self.automaticallyAdjustsScrollViewInsets = NO; 26 | self.view.backgroundColor = [UIColor lightGrayColor]; 27 | 28 | // 配置展示结果talbeview 29 | // [self.view addSubview:self.showTableView]; 30 | 31 | UILabel *titleL = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, CFScreenWidth, 88)]; 32 | titleL.textAlignment = NSTextAlignmentCenter; 33 | titleL.backgroundColor = CFRandomColor; 34 | titleL.numberOfLines = 0; 35 | titleL.text = @"CFMultistageDropdownMenuView 展示demo\n交流QQ 545486205\n 个人github网址 https://github.com/CoderPeak"; 36 | [self.view addSubview:titleL]; 37 | 38 | // 配置CFDropDownMenuView 39 | [self.view addSubview:self.multistageDropdownMenuView]; 40 | 41 | } 42 | 43 | #pragma mark - lazy 44 | /* 配置CFDropDownMenuView */ 45 | - (CFMultistageDropdownMenuView *)multistageDropdownMenuView 46 | { 47 | // DEMO 48 | _multistageDropdownMenuView = [[CFMultistageDropdownMenuView alloc] initWithFrame:CGRectMake(0, 104, CFScreenWidth, 45)]; 49 | 50 | _multistageDropdownMenuView.defaulTitleArray = [NSArray arrayWithObjects:@"行业分类",@"金额", @"排序", nil]; 51 | 52 | // 注: 数据源一般由网络请求 53 | // 格式参照如下 - 一般后台返回的格式如此 54 | NSArray *leftArr = @[ 55 | // 二级菜单 的 一级菜单 56 | @[@"全部分类", @"特色餐饮", @"服装鞋包", @"美容养生", @"饰品玩具", @"家居建材", @"节能环保", @"O2O落地", @"生活服务"], 57 | // 一级菜单 58 | @[], 59 | // 一级菜单 60 | @[] 61 | ]; 62 | NSArray *rightArr = @[ 63 | // 对应dataSourceLeftArray 64 | @[ 65 | // 二级菜单 的 二级菜单 66 | // 全部分类 67 | @[@"全部"], 68 | // 特色餐饮 69 | @[@"全部", @"小吃快餐", @"火锅", @"自助餐", @"江浙菜", @"生日蛋糕", @"茶饮", @"烤鱼", @"川湘菜", @"西餐牛排", @"甜点", @"面馆", @"粤菜"], 70 | // 服装鞋包 71 | @[@"全部", @"单肩包", @"长靴", @"短靴", @"凉鞋"], 72 | // 美容养生 73 | @[@"全部", @"护肤品", @"其他"], 74 | // 饰品玩具 75 | @[@"全部", @"项链吊坠", @"潮流眼镜", @"品质手表", @"卡通公仔"], 76 | // 家居建材 77 | @[@"全部", @"装修设计", @"墙纸", @"卫浴用品"], 78 | // 节能环保 79 | @[@"全部", @"园艺用品", @"其他"], 80 | // O2O落地 81 | @[@"全部", @"网站制作", @"IT技能", @"办公软件", @"会计职称"], 82 | // 生活服务 83 | @[@"全部", @"旅游休闲", @"家庭保洁", @"数码维修", @"商务服务", @"宠物服务", @"汽车服务", @"婚庆服务", @"其他"] 84 | ], 85 | @[ 86 | // 一级菜单 87 | // 金额 88 | @[@"全部", @"一万以下", @"1-5万", @"5-10万", @"10-15万", @"15-20万", @"20万以上"] 89 | ], 90 | @[ 91 | // 一级菜单 92 | // 排序 93 | @[@"全部", @"人气最高", @"最新加入", @"金额从低到高", @"金额从高到低"] 94 | ] 95 | 96 | ]; 97 | 98 | [_multistageDropdownMenuView setupDataSourceLeftArray:leftArr rightArray:rightArr]; 99 | 100 | _multistageDropdownMenuView.delegate = self; 101 | 102 | // 下拉列表 起始y 103 | _multistageDropdownMenuView.startY = CGRectGetMaxY(_multistageDropdownMenuView.frame); 104 | 105 | // _multistageDropdownMenuView.maxRowCount = 3; 106 | _multistageDropdownMenuView.stateConfigDict = @{ 107 | // @"selected" : @[[UIColor purpleColor], @"测试紫箭头"], 108 | // @"normal" : @[[UIColor redColor], @"测试红箭头"] 109 | }; 110 | 111 | 112 | 113 | 114 | return _multistageDropdownMenuView; 115 | 116 | } 117 | 118 | #pragma mark - CFMultistageDropdownMenuViewDelegate 119 | - (void)multistageDropdownMenuView:(CFMultistageDropdownMenuView *)multistageDropdownMenuView selecteTitleButtonIndex:(NSInteger)titleButtonIndex conditionLeftIndex:(NSInteger)leftIndex conditionRightIndex:(NSInteger)rightIndex 120 | { 121 | 122 | 123 | NSString *str = [NSString stringWithFormat:@"(都是从0开始)\n 当前选中是 第%zd个title按钮, 一级条件索引是%zd, 二级条件索引是%zd",titleButtonIndex, leftIndex, rightIndex]; 124 | 125 | NSString *titleStr = [multistageDropdownMenuView.defaulTitleArray objectAtIndex:titleButtonIndex]; 126 | NSArray *leftArr = [multistageDropdownMenuView.dataSourceLeftArray objectAtIndex:titleButtonIndex]; 127 | NSArray *rightArr = [multistageDropdownMenuView.dataSourceRightArray objectAtIndex:titleButtonIndex]; 128 | NSString *leftStr = @""; 129 | NSString *rightStr = @""; 130 | NSString *str2 = @""; 131 | if (leftArr.count>0) { // 二级菜单 132 | leftStr = [leftArr objectAtIndex:leftIndex]; 133 | NSArray *arr = [rightArr objectAtIndex:leftIndex]; 134 | rightStr = [arr objectAtIndex:rightIndex]; 135 | str2 = [NSString stringWithFormat:@"当前选中的是 \"%@\" 分类下的 \"%@\"-\"%@\"", titleStr, leftStr, rightStr]; 136 | } else { 137 | rightStr = [rightArr[0] objectAtIndex:rightIndex]; 138 | str2 = [NSString stringWithFormat:@"当前选中的是 \"%@\" 分类下的 \"%@\"", titleStr, rightStr]; 139 | } 140 | 141 | NSMutableString *mStr22 = [NSMutableString stringWithFormat:@" "]; 142 | NSArray *btnArr = multistageDropdownMenuView.titleButtonArray; 143 | for (UIButton *btn in btnArr) { 144 | [mStr22 appendString:[NSString stringWithFormat:@"\"%@\"", btn.titleLabel.text]]; 145 | [mStr22 appendString:@" "]; 146 | } 147 | NSString *str22 = [NSString stringWithFormat:@"当前展示的所有条件是:\n (%@)", mStr22]; 148 | 149 | 150 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"注: 当下拉菜单选项为一级菜单时, 一级条件索引肯定是0" message:str preferredStyle:UIAlertControllerStyleAlert]; 151 | [self presentViewController:alertController animated:NO completion:^{ 152 | UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 153 | 154 | UIAlertController *alertController2 = [UIAlertController alertControllerWithTitle:str22 message:str2 preferredStyle:UIAlertControllerStyleAlert]; 155 | [self presentViewController:alertController2 animated:NO completion:^{ 156 | UIAlertAction *alertAction2 = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 157 | 158 | }]; 159 | [alertController2 addAction:alertAction2]; 160 | }]; 161 | 162 | }]; 163 | [alertController addAction:alertAction]; 164 | }]; 165 | 166 | 167 | } 168 | 169 | - (void)multistageDropdownMenuView:(CFMultistageDropdownMenuView *)multistageDropdownMenuView selectTitleButtonWithCurrentTitle:(NSString *)currentTitle currentTitleArray:(NSArray *)currentTitleArray 170 | { 171 | NSMutableString *mStr = [NSMutableString stringWithFormat:@" "]; 172 | 173 | for (NSString *str in currentTitleArray) { 174 | [mStr appendString:[NSString stringWithFormat:@"\"%@\"", str]]; 175 | [mStr appendString:@" "]; 176 | } 177 | NSString *str = [NSString stringWithFormat:@"当前选中的是 \"%@\" \n 当前展示的所有条件是:\n (%@)",currentTitle, mStr]; 178 | 179 | 180 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"第二个代理方法" message:str preferredStyle:UIAlertControllerStyleAlert]; 181 | [self presentViewController:alertController animated:NO completion:^{ 182 | UIAlertAction *alertAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 183 | 184 | 185 | }]; 186 | [alertController addAction:alertAction]; 187 | }]; 188 | } 189 | 190 | 191 | - (void)didReceiveMemoryWarning { 192 | [super didReceiveMemoryWarning]; 193 | // Dispose of any resources that can be recreated. 194 | } 195 | 196 | 197 | @end 198 | -------------------------------------------------------------------------------- /CFMultistageDropdownMenuView/CFMultistageDropdownMenuView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CFMultistageDropdownMenuView 4 | // 5 | // Created by Peak on 17/2/28. 6 | // Copyright © 2017年 Peak. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 CoderPeak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CFMultistageDropdownMenuView 2 | 简单好用的, 可自定义选中和非选中状态样式的 (最多支持二级的)下拉列表菜单控件---支持默认选中的条件状态改变 3 | 4 | ##### 因为此需求通常定制性较强, 可自定义丰富的效果---为了迎合不同需求, 建议拖入项目中使用 5 | 6 | ### demo展示 - 由于网络原因, 可能gif效果图会展示的比较卡, 可以下载运行查看demo---简单使用代码 7 | 8 | ### 使用---注: 详细数据源格式 请参考demo 9 | - 创建使用仅需几行代码即可 10 | 11 | ``` 12 | // 添加到当前view 13 | [self.view addSubview:self.multistageDropdownMenuView]; 14 | 15 | 16 | // 创建 17 | _multistageDropdownMenuView = [[CFMultistageDropdownMenuView alloc] initWithFrame:CGRectMake(0, 104, CFScreenWidth, 45)]; 18 | _multistageDropdownMenuView.defaulTitleArray = [NSArray arrayWithObjects:@"行业分类",@"金额", @"排序", nil]; 19 | [_multistageDropdownMenuView setupDataSourceLeftArray:leftArr rightArray:rightArr]; 20 | _multistageDropdownMenuView.delegate = self; 21 | // 下拉列表 起始y 22 | _multistageDropdownMenuView.startY = CGRectGetMaxY(_multistageDropdownMenuView.frame); 23 | // 详细数据源格式 请参考demo 24 | 25 | ``` 26 | 27 | ### 效果图集 28 | 29 | ![](/公司项目实际使用.gif) 30 | ![](/实现第一个代理方法.gif) 31 | ![](/实现第二个代理方法.gif) 32 | -------------------------------------------------------------------------------- /公司项目实际使用.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/公司项目实际使用.gif -------------------------------------------------------------------------------- /实现第一个代理方法.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/实现第一个代理方法.gif -------------------------------------------------------------------------------- /实现第二个代理方法.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderPeak/CFMultistageDropdownMenuView/6924f42d4dcdeb81b334e2acfa741f5b408f5430/实现第二个代理方法.gif --------------------------------------------------------------------------------