├── README.md ├── WSMenuButton.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── dotsquares.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── WSMenuButton.xcscheme │ └── xcschememanagement.plist ├── WSMenuButton ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── ViewController.h ├── ViewController.m ├── WSMenuControl.h ├── WSMenuControl.m └── main.m ├── WSMenuButtonTests ├── Info.plist └── WSMenuButtonTests.m ├── WSMenuButtonUITests ├── Info.plist └── WSMenuButtonUITests.m ├── WSMenuControl_1.png ├── WSMenuControl_2.png ├── WSMenuControl_3.png └── WSMenuControl_4.png /README.md: -------------------------------------------------------------------------------- 1 | # WSMenuButton 2 | Animated menu button. Simply assing the class to button and use. 3 | 4 | ![Alt text](https://github.com/WebsoftProfession/WSMenuButton/blob/master/WSMenuControl_4.png?raw=true "Optional Title") 5 | ![Alt text](https://github.com/WebsoftProfession/WSMenuButton/blob/master/WSMenuControl_3.png?raw=true "Optional Title") 6 | ![Alt text](https://github.com/WebsoftProfession/WSMenuButton/blob/master/WSMenuControl_2.png?raw=true "Optional Title") 7 | ![Alt text](https://github.com/WebsoftProfession/WSMenuButton/blob/master/WSMenuControl_1.png?raw=true "Optional Title") 8 | 9 | 10 | -------------------------------------------------------------------------------- /WSMenuButton.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6059C99C1E939C2900F88A51 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6059C99B1E939C2900F88A51 /* main.m */; }; 11 | 6059C99F1E939C2900F88A51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6059C99E1E939C2900F88A51 /* AppDelegate.m */; }; 12 | 6059C9A21E939C2900F88A51 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6059C9A11E939C2900F88A51 /* ViewController.m */; }; 13 | 6059C9A51E939C2900F88A51 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6059C9A31E939C2900F88A51 /* Main.storyboard */; }; 14 | 6059C9A71E939C2900F88A51 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6059C9A61E939C2900F88A51 /* Assets.xcassets */; }; 15 | 6059C9AA1E939C2900F88A51 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6059C9A81E939C2900F88A51 /* LaunchScreen.storyboard */; }; 16 | 6059C9B51E939C2A00F88A51 /* WSMenuButtonTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6059C9B41E939C2A00F88A51 /* WSMenuButtonTests.m */; }; 17 | 6059C9C01E939C2A00F88A51 /* WSMenuButtonUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6059C9BF1E939C2A00F88A51 /* WSMenuButtonUITests.m */; }; 18 | 6059C9CF1E939C9B00F88A51 /* WSMenuControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 6059C9CE1E939C9B00F88A51 /* WSMenuControl.m */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 6059C9B11E939C2A00F88A51 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 6059C98F1E939C2900F88A51 /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = 6059C9961E939C2900F88A51; 27 | remoteInfo = WSMenuButton; 28 | }; 29 | 6059C9BC1E939C2A00F88A51 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 6059C98F1E939C2900F88A51 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 6059C9961E939C2900F88A51; 34 | remoteInfo = WSMenuButton; 35 | }; 36 | /* End PBXContainerItemProxy section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 6059C9971E939C2900F88A51 /* WSMenuButton.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WSMenuButton.app; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | 6059C99B1E939C2900F88A51 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 41 | 6059C99D1E939C2900F88A51 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 42 | 6059C99E1E939C2900F88A51 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 43 | 6059C9A01E939C2900F88A51 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 44 | 6059C9A11E939C2900F88A51 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 45 | 6059C9A41E939C2900F88A51 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 46 | 6059C9A61E939C2900F88A51 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 47 | 6059C9A91E939C2900F88A51 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 48 | 6059C9AB1E939C2900F88A51 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 49 | 6059C9B01E939C2A00F88A51 /* WSMenuButtonTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WSMenuButtonTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 6059C9B41E939C2A00F88A51 /* WSMenuButtonTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WSMenuButtonTests.m; sourceTree = ""; }; 51 | 6059C9B61E939C2A00F88A51 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | 6059C9BB1E939C2A00F88A51 /* WSMenuButtonUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WSMenuButtonUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 6059C9BF1E939C2A00F88A51 /* WSMenuButtonUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WSMenuButtonUITests.m; sourceTree = ""; }; 54 | 6059C9C11E939C2A00F88A51 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55 | 6059C9CD1E939C9B00F88A51 /* WSMenuControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WSMenuControl.h; sourceTree = ""; }; 56 | 6059C9CE1E939C9B00F88A51 /* WSMenuControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WSMenuControl.m; sourceTree = ""; }; 57 | /* End PBXFileReference section */ 58 | 59 | /* Begin PBXFrameworksBuildPhase section */ 60 | 6059C9941E939C2900F88A51 /* Frameworks */ = { 61 | isa = PBXFrameworksBuildPhase; 62 | buildActionMask = 2147483647; 63 | files = ( 64 | ); 65 | runOnlyForDeploymentPostprocessing = 0; 66 | }; 67 | 6059C9AD1E939C2A00F88A51 /* Frameworks */ = { 68 | isa = PBXFrameworksBuildPhase; 69 | buildActionMask = 2147483647; 70 | files = ( 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | 6059C9B81E939C2A00F88A51 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | /* End PBXFrameworksBuildPhase section */ 82 | 83 | /* Begin PBXGroup section */ 84 | 6059C98E1E939C2900F88A51 = { 85 | isa = PBXGroup; 86 | children = ( 87 | 6059C9991E939C2900F88A51 /* WSMenuButton */, 88 | 6059C9B31E939C2A00F88A51 /* WSMenuButtonTests */, 89 | 6059C9BE1E939C2A00F88A51 /* WSMenuButtonUITests */, 90 | 6059C9981E939C2900F88A51 /* Products */, 91 | ); 92 | sourceTree = ""; 93 | }; 94 | 6059C9981E939C2900F88A51 /* Products */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 6059C9971E939C2900F88A51 /* WSMenuButton.app */, 98 | 6059C9B01E939C2A00F88A51 /* WSMenuButtonTests.xctest */, 99 | 6059C9BB1E939C2A00F88A51 /* WSMenuButtonUITests.xctest */, 100 | ); 101 | name = Products; 102 | sourceTree = ""; 103 | }; 104 | 6059C9991E939C2900F88A51 /* WSMenuButton */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 6059C99D1E939C2900F88A51 /* AppDelegate.h */, 108 | 6059C99E1E939C2900F88A51 /* AppDelegate.m */, 109 | 6059C9A01E939C2900F88A51 /* ViewController.h */, 110 | 6059C9A11E939C2900F88A51 /* ViewController.m */, 111 | 6059C9A31E939C2900F88A51 /* Main.storyboard */, 112 | 6059C9A61E939C2900F88A51 /* Assets.xcassets */, 113 | 6059C9A81E939C2900F88A51 /* LaunchScreen.storyboard */, 114 | 6059C9AB1E939C2900F88A51 /* Info.plist */, 115 | 6059C99A1E939C2900F88A51 /* Supporting Files */, 116 | 6059C9CD1E939C9B00F88A51 /* WSMenuControl.h */, 117 | 6059C9CE1E939C9B00F88A51 /* WSMenuControl.m */, 118 | ); 119 | path = WSMenuButton; 120 | sourceTree = ""; 121 | }; 122 | 6059C99A1E939C2900F88A51 /* Supporting Files */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 6059C99B1E939C2900F88A51 /* main.m */, 126 | ); 127 | name = "Supporting Files"; 128 | sourceTree = ""; 129 | }; 130 | 6059C9B31E939C2A00F88A51 /* WSMenuButtonTests */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 6059C9B41E939C2A00F88A51 /* WSMenuButtonTests.m */, 134 | 6059C9B61E939C2A00F88A51 /* Info.plist */, 135 | ); 136 | path = WSMenuButtonTests; 137 | sourceTree = ""; 138 | }; 139 | 6059C9BE1E939C2A00F88A51 /* WSMenuButtonUITests */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | 6059C9BF1E939C2A00F88A51 /* WSMenuButtonUITests.m */, 143 | 6059C9C11E939C2A00F88A51 /* Info.plist */, 144 | ); 145 | path = WSMenuButtonUITests; 146 | sourceTree = ""; 147 | }; 148 | /* End PBXGroup section */ 149 | 150 | /* Begin PBXNativeTarget section */ 151 | 6059C9961E939C2900F88A51 /* WSMenuButton */ = { 152 | isa = PBXNativeTarget; 153 | buildConfigurationList = 6059C9C41E939C2A00F88A51 /* Build configuration list for PBXNativeTarget "WSMenuButton" */; 154 | buildPhases = ( 155 | 6059C9931E939C2900F88A51 /* Sources */, 156 | 6059C9941E939C2900F88A51 /* Frameworks */, 157 | 6059C9951E939C2900F88A51 /* Resources */, 158 | ); 159 | buildRules = ( 160 | ); 161 | dependencies = ( 162 | ); 163 | name = WSMenuButton; 164 | productName = WSMenuButton; 165 | productReference = 6059C9971E939C2900F88A51 /* WSMenuButton.app */; 166 | productType = "com.apple.product-type.application"; 167 | }; 168 | 6059C9AF1E939C2A00F88A51 /* WSMenuButtonTests */ = { 169 | isa = PBXNativeTarget; 170 | buildConfigurationList = 6059C9C71E939C2A00F88A51 /* Build configuration list for PBXNativeTarget "WSMenuButtonTests" */; 171 | buildPhases = ( 172 | 6059C9AC1E939C2A00F88A51 /* Sources */, 173 | 6059C9AD1E939C2A00F88A51 /* Frameworks */, 174 | 6059C9AE1E939C2A00F88A51 /* Resources */, 175 | ); 176 | buildRules = ( 177 | ); 178 | dependencies = ( 179 | 6059C9B21E939C2A00F88A51 /* PBXTargetDependency */, 180 | ); 181 | name = WSMenuButtonTests; 182 | productName = WSMenuButtonTests; 183 | productReference = 6059C9B01E939C2A00F88A51 /* WSMenuButtonTests.xctest */; 184 | productType = "com.apple.product-type.bundle.unit-test"; 185 | }; 186 | 6059C9BA1E939C2A00F88A51 /* WSMenuButtonUITests */ = { 187 | isa = PBXNativeTarget; 188 | buildConfigurationList = 6059C9CA1E939C2A00F88A51 /* Build configuration list for PBXNativeTarget "WSMenuButtonUITests" */; 189 | buildPhases = ( 190 | 6059C9B71E939C2A00F88A51 /* Sources */, 191 | 6059C9B81E939C2A00F88A51 /* Frameworks */, 192 | 6059C9B91E939C2A00F88A51 /* Resources */, 193 | ); 194 | buildRules = ( 195 | ); 196 | dependencies = ( 197 | 6059C9BD1E939C2A00F88A51 /* PBXTargetDependency */, 198 | ); 199 | name = WSMenuButtonUITests; 200 | productName = WSMenuButtonUITests; 201 | productReference = 6059C9BB1E939C2A00F88A51 /* WSMenuButtonUITests.xctest */; 202 | productType = "com.apple.product-type.bundle.ui-testing"; 203 | }; 204 | /* End PBXNativeTarget section */ 205 | 206 | /* Begin PBXProject section */ 207 | 6059C98F1E939C2900F88A51 /* Project object */ = { 208 | isa = PBXProject; 209 | attributes = { 210 | LastUpgradeCheck = 0820; 211 | ORGANIZATIONNAME = WebsoftProfession; 212 | TargetAttributes = { 213 | 6059C9961E939C2900F88A51 = { 214 | CreatedOnToolsVersion = 8.2.1; 215 | ProvisioningStyle = Automatic; 216 | }; 217 | 6059C9AF1E939C2A00F88A51 = { 218 | CreatedOnToolsVersion = 8.2.1; 219 | ProvisioningStyle = Automatic; 220 | TestTargetID = 6059C9961E939C2900F88A51; 221 | }; 222 | 6059C9BA1E939C2A00F88A51 = { 223 | CreatedOnToolsVersion = 8.2.1; 224 | ProvisioningStyle = Automatic; 225 | TestTargetID = 6059C9961E939C2900F88A51; 226 | }; 227 | }; 228 | }; 229 | buildConfigurationList = 6059C9921E939C2900F88A51 /* Build configuration list for PBXProject "WSMenuButton" */; 230 | compatibilityVersion = "Xcode 3.2"; 231 | developmentRegion = English; 232 | hasScannedForEncodings = 0; 233 | knownRegions = ( 234 | en, 235 | Base, 236 | ); 237 | mainGroup = 6059C98E1E939C2900F88A51; 238 | productRefGroup = 6059C9981E939C2900F88A51 /* Products */; 239 | projectDirPath = ""; 240 | projectRoot = ""; 241 | targets = ( 242 | 6059C9961E939C2900F88A51 /* WSMenuButton */, 243 | 6059C9AF1E939C2A00F88A51 /* WSMenuButtonTests */, 244 | 6059C9BA1E939C2A00F88A51 /* WSMenuButtonUITests */, 245 | ); 246 | }; 247 | /* End PBXProject section */ 248 | 249 | /* Begin PBXResourcesBuildPhase section */ 250 | 6059C9951E939C2900F88A51 /* Resources */ = { 251 | isa = PBXResourcesBuildPhase; 252 | buildActionMask = 2147483647; 253 | files = ( 254 | 6059C9AA1E939C2900F88A51 /* LaunchScreen.storyboard in Resources */, 255 | 6059C9A71E939C2900F88A51 /* Assets.xcassets in Resources */, 256 | 6059C9A51E939C2900F88A51 /* Main.storyboard in Resources */, 257 | ); 258 | runOnlyForDeploymentPostprocessing = 0; 259 | }; 260 | 6059C9AE1E939C2A00F88A51 /* Resources */ = { 261 | isa = PBXResourcesBuildPhase; 262 | buildActionMask = 2147483647; 263 | files = ( 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | }; 267 | 6059C9B91E939C2A00F88A51 /* Resources */ = { 268 | isa = PBXResourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | ); 272 | runOnlyForDeploymentPostprocessing = 0; 273 | }; 274 | /* End PBXResourcesBuildPhase section */ 275 | 276 | /* Begin PBXSourcesBuildPhase section */ 277 | 6059C9931E939C2900F88A51 /* Sources */ = { 278 | isa = PBXSourcesBuildPhase; 279 | buildActionMask = 2147483647; 280 | files = ( 281 | 6059C9A21E939C2900F88A51 /* ViewController.m in Sources */, 282 | 6059C99F1E939C2900F88A51 /* AppDelegate.m in Sources */, 283 | 6059C9CF1E939C9B00F88A51 /* WSMenuControl.m in Sources */, 284 | 6059C99C1E939C2900F88A51 /* main.m in Sources */, 285 | ); 286 | runOnlyForDeploymentPostprocessing = 0; 287 | }; 288 | 6059C9AC1E939C2A00F88A51 /* Sources */ = { 289 | isa = PBXSourcesBuildPhase; 290 | buildActionMask = 2147483647; 291 | files = ( 292 | 6059C9B51E939C2A00F88A51 /* WSMenuButtonTests.m in Sources */, 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | 6059C9B71E939C2A00F88A51 /* Sources */ = { 297 | isa = PBXSourcesBuildPhase; 298 | buildActionMask = 2147483647; 299 | files = ( 300 | 6059C9C01E939C2A00F88A51 /* WSMenuButtonUITests.m in Sources */, 301 | ); 302 | runOnlyForDeploymentPostprocessing = 0; 303 | }; 304 | /* End PBXSourcesBuildPhase section */ 305 | 306 | /* Begin PBXTargetDependency section */ 307 | 6059C9B21E939C2A00F88A51 /* PBXTargetDependency */ = { 308 | isa = PBXTargetDependency; 309 | target = 6059C9961E939C2900F88A51 /* WSMenuButton */; 310 | targetProxy = 6059C9B11E939C2A00F88A51 /* PBXContainerItemProxy */; 311 | }; 312 | 6059C9BD1E939C2A00F88A51 /* PBXTargetDependency */ = { 313 | isa = PBXTargetDependency; 314 | target = 6059C9961E939C2900F88A51 /* WSMenuButton */; 315 | targetProxy = 6059C9BC1E939C2A00F88A51 /* PBXContainerItemProxy */; 316 | }; 317 | /* End PBXTargetDependency section */ 318 | 319 | /* Begin PBXVariantGroup section */ 320 | 6059C9A31E939C2900F88A51 /* Main.storyboard */ = { 321 | isa = PBXVariantGroup; 322 | children = ( 323 | 6059C9A41E939C2900F88A51 /* Base */, 324 | ); 325 | name = Main.storyboard; 326 | sourceTree = ""; 327 | }; 328 | 6059C9A81E939C2900F88A51 /* LaunchScreen.storyboard */ = { 329 | isa = PBXVariantGroup; 330 | children = ( 331 | 6059C9A91E939C2900F88A51 /* Base */, 332 | ); 333 | name = LaunchScreen.storyboard; 334 | sourceTree = ""; 335 | }; 336 | /* End PBXVariantGroup section */ 337 | 338 | /* Begin XCBuildConfiguration section */ 339 | 6059C9C21E939C2A00F88A51 /* Debug */ = { 340 | isa = XCBuildConfiguration; 341 | buildSettings = { 342 | ALWAYS_SEARCH_USER_PATHS = NO; 343 | CLANG_ANALYZER_NONNULL = YES; 344 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 345 | CLANG_CXX_LIBRARY = "libc++"; 346 | CLANG_ENABLE_MODULES = YES; 347 | CLANG_ENABLE_OBJC_ARC = YES; 348 | CLANG_WARN_BOOL_CONVERSION = YES; 349 | CLANG_WARN_CONSTANT_CONVERSION = YES; 350 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 351 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 352 | CLANG_WARN_EMPTY_BODY = YES; 353 | CLANG_WARN_ENUM_CONVERSION = YES; 354 | CLANG_WARN_INFINITE_RECURSION = YES; 355 | CLANG_WARN_INT_CONVERSION = YES; 356 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 357 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 358 | CLANG_WARN_UNREACHABLE_CODE = YES; 359 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 360 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 361 | COPY_PHASE_STRIP = NO; 362 | DEBUG_INFORMATION_FORMAT = dwarf; 363 | ENABLE_STRICT_OBJC_MSGSEND = YES; 364 | ENABLE_TESTABILITY = YES; 365 | GCC_C_LANGUAGE_STANDARD = gnu99; 366 | GCC_DYNAMIC_NO_PIC = NO; 367 | GCC_NO_COMMON_BLOCKS = YES; 368 | GCC_OPTIMIZATION_LEVEL = 0; 369 | GCC_PREPROCESSOR_DEFINITIONS = ( 370 | "DEBUG=1", 371 | "$(inherited)", 372 | ); 373 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 374 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 375 | GCC_WARN_UNDECLARED_SELECTOR = YES; 376 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 377 | GCC_WARN_UNUSED_FUNCTION = YES; 378 | GCC_WARN_UNUSED_VARIABLE = YES; 379 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 380 | MTL_ENABLE_DEBUG_INFO = YES; 381 | ONLY_ACTIVE_ARCH = YES; 382 | SDKROOT = iphoneos; 383 | TARGETED_DEVICE_FAMILY = "1,2"; 384 | }; 385 | name = Debug; 386 | }; 387 | 6059C9C31E939C2A00F88A51 /* Release */ = { 388 | isa = XCBuildConfiguration; 389 | buildSettings = { 390 | ALWAYS_SEARCH_USER_PATHS = NO; 391 | CLANG_ANALYZER_NONNULL = YES; 392 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 393 | CLANG_CXX_LIBRARY = "libc++"; 394 | CLANG_ENABLE_MODULES = YES; 395 | CLANG_ENABLE_OBJC_ARC = YES; 396 | CLANG_WARN_BOOL_CONVERSION = YES; 397 | CLANG_WARN_CONSTANT_CONVERSION = YES; 398 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 399 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 400 | CLANG_WARN_EMPTY_BODY = YES; 401 | CLANG_WARN_ENUM_CONVERSION = YES; 402 | CLANG_WARN_INFINITE_RECURSION = YES; 403 | CLANG_WARN_INT_CONVERSION = YES; 404 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 405 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 406 | CLANG_WARN_UNREACHABLE_CODE = YES; 407 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 408 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 409 | COPY_PHASE_STRIP = NO; 410 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 411 | ENABLE_NS_ASSERTIONS = NO; 412 | ENABLE_STRICT_OBJC_MSGSEND = YES; 413 | GCC_C_LANGUAGE_STANDARD = gnu99; 414 | GCC_NO_COMMON_BLOCKS = YES; 415 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 416 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 417 | GCC_WARN_UNDECLARED_SELECTOR = YES; 418 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 419 | GCC_WARN_UNUSED_FUNCTION = YES; 420 | GCC_WARN_UNUSED_VARIABLE = YES; 421 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 422 | MTL_ENABLE_DEBUG_INFO = NO; 423 | SDKROOT = iphoneos; 424 | TARGETED_DEVICE_FAMILY = "1,2"; 425 | VALIDATE_PRODUCT = YES; 426 | }; 427 | name = Release; 428 | }; 429 | 6059C9C51E939C2A00F88A51 /* Debug */ = { 430 | isa = XCBuildConfiguration; 431 | buildSettings = { 432 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 433 | DEVELOPMENT_TEAM = ""; 434 | INFOPLIST_FILE = WSMenuButton/Info.plist; 435 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 436 | PRODUCT_BUNDLE_IDENTIFIER = TD.WSMenuButton; 437 | PRODUCT_NAME = "$(TARGET_NAME)"; 438 | }; 439 | name = Debug; 440 | }; 441 | 6059C9C61E939C2A00F88A51 /* Release */ = { 442 | isa = XCBuildConfiguration; 443 | buildSettings = { 444 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 445 | DEVELOPMENT_TEAM = ""; 446 | INFOPLIST_FILE = WSMenuButton/Info.plist; 447 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 448 | PRODUCT_BUNDLE_IDENTIFIER = TD.WSMenuButton; 449 | PRODUCT_NAME = "$(TARGET_NAME)"; 450 | }; 451 | name = Release; 452 | }; 453 | 6059C9C81E939C2A00F88A51 /* Debug */ = { 454 | isa = XCBuildConfiguration; 455 | buildSettings = { 456 | BUNDLE_LOADER = "$(TEST_HOST)"; 457 | INFOPLIST_FILE = WSMenuButtonTests/Info.plist; 458 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 459 | PRODUCT_BUNDLE_IDENTIFIER = TD.WSMenuButtonTests; 460 | PRODUCT_NAME = "$(TARGET_NAME)"; 461 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WSMenuButton.app/WSMenuButton"; 462 | }; 463 | name = Debug; 464 | }; 465 | 6059C9C91E939C2A00F88A51 /* Release */ = { 466 | isa = XCBuildConfiguration; 467 | buildSettings = { 468 | BUNDLE_LOADER = "$(TEST_HOST)"; 469 | INFOPLIST_FILE = WSMenuButtonTests/Info.plist; 470 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 471 | PRODUCT_BUNDLE_IDENTIFIER = TD.WSMenuButtonTests; 472 | PRODUCT_NAME = "$(TARGET_NAME)"; 473 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WSMenuButton.app/WSMenuButton"; 474 | }; 475 | name = Release; 476 | }; 477 | 6059C9CB1E939C2A00F88A51 /* Debug */ = { 478 | isa = XCBuildConfiguration; 479 | buildSettings = { 480 | INFOPLIST_FILE = WSMenuButtonUITests/Info.plist; 481 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 482 | PRODUCT_BUNDLE_IDENTIFIER = TD.WSMenuButtonUITests; 483 | PRODUCT_NAME = "$(TARGET_NAME)"; 484 | TEST_TARGET_NAME = WSMenuButton; 485 | }; 486 | name = Debug; 487 | }; 488 | 6059C9CC1E939C2A00F88A51 /* Release */ = { 489 | isa = XCBuildConfiguration; 490 | buildSettings = { 491 | INFOPLIST_FILE = WSMenuButtonUITests/Info.plist; 492 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 493 | PRODUCT_BUNDLE_IDENTIFIER = TD.WSMenuButtonUITests; 494 | PRODUCT_NAME = "$(TARGET_NAME)"; 495 | TEST_TARGET_NAME = WSMenuButton; 496 | }; 497 | name = Release; 498 | }; 499 | /* End XCBuildConfiguration section */ 500 | 501 | /* Begin XCConfigurationList section */ 502 | 6059C9921E939C2900F88A51 /* Build configuration list for PBXProject "WSMenuButton" */ = { 503 | isa = XCConfigurationList; 504 | buildConfigurations = ( 505 | 6059C9C21E939C2A00F88A51 /* Debug */, 506 | 6059C9C31E939C2A00F88A51 /* Release */, 507 | ); 508 | defaultConfigurationIsVisible = 0; 509 | defaultConfigurationName = Release; 510 | }; 511 | 6059C9C41E939C2A00F88A51 /* Build configuration list for PBXNativeTarget "WSMenuButton" */ = { 512 | isa = XCConfigurationList; 513 | buildConfigurations = ( 514 | 6059C9C51E939C2A00F88A51 /* Debug */, 515 | 6059C9C61E939C2A00F88A51 /* Release */, 516 | ); 517 | defaultConfigurationIsVisible = 0; 518 | defaultConfigurationName = Release; 519 | }; 520 | 6059C9C71E939C2A00F88A51 /* Build configuration list for PBXNativeTarget "WSMenuButtonTests" */ = { 521 | isa = XCConfigurationList; 522 | buildConfigurations = ( 523 | 6059C9C81E939C2A00F88A51 /* Debug */, 524 | 6059C9C91E939C2A00F88A51 /* Release */, 525 | ); 526 | defaultConfigurationIsVisible = 0; 527 | defaultConfigurationName = Release; 528 | }; 529 | 6059C9CA1E939C2A00F88A51 /* Build configuration list for PBXNativeTarget "WSMenuButtonUITests" */ = { 530 | isa = XCConfigurationList; 531 | buildConfigurations = ( 532 | 6059C9CB1E939C2A00F88A51 /* Debug */, 533 | 6059C9CC1E939C2A00F88A51 /* Release */, 534 | ); 535 | defaultConfigurationIsVisible = 0; 536 | defaultConfigurationName = Release; 537 | }; 538 | /* End XCConfigurationList section */ 539 | }; 540 | rootObject = 6059C98F1E939C2900F88A51 /* Project object */; 541 | } 542 | -------------------------------------------------------------------------------- /WSMenuButton.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WSMenuButton.xcodeproj/xcuserdata/dotsquares.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 40 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /WSMenuButton.xcodeproj/xcuserdata/dotsquares.xcuserdatad/xcschemes/WSMenuButton.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /WSMenuButton.xcodeproj/xcuserdata/dotsquares.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WSMenuButton.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 6059C9961E939C2900F88A51 16 | 17 | primary 18 | 19 | 20 | 6059C9AF1E939C2A00F88A51 21 | 22 | primary 23 | 24 | 25 | 6059C9BA1E939C2A00F88A51 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /WSMenuButton/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WSMenuButton 4 | // 5 | // Created by Dotsquares on 4/4/17. 6 | // Copyright © 2017 WebsoftProfession. 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 | -------------------------------------------------------------------------------- /WSMenuButton/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WSMenuButton 4 | // 5 | // Created by Dotsquares on 4/4/17. 6 | // Copyright © 2017 WebsoftProfession. 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 | -------------------------------------------------------------------------------- /WSMenuButton/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 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /WSMenuButton/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 | -------------------------------------------------------------------------------- /WSMenuButton/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 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /WSMenuButton/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /WSMenuButton/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // WSMenuButton 4 | // 5 | // Created by Dotsquares on 4/4/17. 6 | // Copyright © 2017 WebsoftProfession. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WSMenuControl.h" 11 | 12 | @interface ViewController : UIViewController 13 | { 14 | __weak IBOutlet WSMenuControl *wsMenuBtn; 15 | 16 | } 17 | - (IBAction)menuButtonAction:(id)sender; 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /WSMenuButton/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // WSMenuButton 4 | // 5 | // Created by Dotsquares on 4/4/17. 6 | // Copyright © 2017 WebsoftProfession. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | wsMenuBtn.menuStyle=WSMenuStyleLine; 20 | // wsMenuBtn.WSMenuControlColor=[UIColor redColor]; 21 | // wsMenuBtn.menuStyle=WSMenuStyleDot; 22 | // Do any additional setup after loading the view, typically from a nib. 23 | } 24 | 25 | 26 | - (void)didReceiveMemoryWarning { 27 | [super didReceiveMemoryWarning]; 28 | // Dispose of any resources that can be recreated. 29 | } 30 | 31 | 32 | - (IBAction)menuButtonAction:(id)sender { 33 | 34 | } 35 | 36 | 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /WSMenuButton/WSMenuControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // WSMenuControl.h 3 | // WSMenuButton 4 | // 5 | // Created by Dotsquares on 4/4/17. 6 | // Copyright © 2017 WebsoftProfession. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef enum{ 12 | WSMenuStyleDot=1, 13 | WSMenuStyleLine, 14 | } AnimationStyle; 15 | 16 | @interface WSMenuControl : UIButton 17 | { 18 | float topVlaue; 19 | float bottomValue; 20 | float leftRightLenght; 21 | NSTimer *timer; 22 | BOOL isRunning; 23 | 24 | } 25 | @property (assign) BOOL isOpen; 26 | @property (assign) int menuStyle; 27 | @property (nonatomic,strong) UIColor *WSMenuControlColor; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /WSMenuButton/WSMenuControl.m: -------------------------------------------------------------------------------- 1 | // 2 | // WSMenuControl.m 3 | // WSMenuButton 4 | // 5 | // Created by Dotsquares on 4/4/17. 6 | // Copyright © 2017 WebsoftProfession. All rights reserved. 7 | // 8 | 9 | #import "WSMenuControl.h" 10 | 11 | @implementation WSMenuControl 12 | 13 | /* 14 | // Only override drawRect: if you perform custom drawing. 15 | // An empty implementation adversely affects performance during animation.*/ 16 | - (void)drawRect:(CGRect)rect { 17 | // Drawing code 18 | 19 | if (!self.isOpen && topVlaue==0 && bottomValue==0) { 20 | topVlaue=8; 21 | bottomValue=8; 22 | if (self.menuStyle==WSMenuStyleDot) { 23 | leftRightLenght=10; 24 | } 25 | else{ 26 | leftRightLenght=10; 27 | } 28 | } 29 | 30 | if (!self.WSMenuControlColor) { 31 | self.WSMenuControlColor=[UIColor purpleColor]; 32 | } 33 | 34 | if (self.menuStyle==WSMenuStyleDot) { 35 | leftRightLenght=10; 36 | } 37 | 38 | CGPoint centerPoint=CGPointMake(rect.size.width/2, rect.size.height/2); 39 | CGPoint leftPointCenter=CGPointMake(rect.size.width/2-leftRightLenght, rect.size.height/2); 40 | CGPoint rightCenterPoint=CGPointMake(rect.size.width/2+leftRightLenght, rect.size.height/2); 41 | 42 | CGPoint topCenterPoint=CGPointMake(rect.size.width/2, rect.size.height/2-topVlaue); 43 | CGPoint topLeftPoint=CGPointMake(rect.size.width/2-leftRightLenght, rect.size.height/2-topVlaue); 44 | CGPoint topRightPoint=CGPointMake(rect.size.width/2+leftRightLenght, rect.size.height/2-topVlaue); 45 | 46 | CGPoint bottomCenterPoint=CGPointMake(rect.size.width/2, rect.size.height/2+bottomValue); 47 | CGPoint bottomLeftPoint=CGPointMake(rect.size.width/2-leftRightLenght, rect.size.height/2+bottomValue); 48 | CGPoint bottomRightPoint=CGPointMake(rect.size.width/2+leftRightLenght, rect.size.height/2+bottomValue); 49 | 50 | 51 | if (self.menuStyle==WSMenuStyleDot) { 52 | // center line 53 | UIBezierPath *centerDot=[UIBezierPath bezierPath]; 54 | [centerDot addArcWithCenter:centerPoint radius:3 startAngle:0 endAngle:M_PI*2 clockwise:YES]; 55 | [self.WSMenuControlColor setFill]; 56 | [centerDot fill]; 57 | 58 | UIBezierPath *leftDot=[UIBezierPath bezierPath]; 59 | [leftDot addArcWithCenter:leftPointCenter radius:3 startAngle:0 endAngle:M_PI*2 clockwise:YES]; 60 | [leftDot fill]; 61 | 62 | UIBezierPath *rightDot=[UIBezierPath bezierPath]; 63 | [rightDot addArcWithCenter:rightCenterPoint radius:3 startAngle:0 endAngle:M_PI*2 clockwise:YES]; 64 | [rightDot fill]; 65 | 66 | 67 | // top line 68 | UIBezierPath *topCenterDot=[UIBezierPath bezierPath]; 69 | [topCenterDot addArcWithCenter:topCenterPoint radius:3 startAngle:0 endAngle:M_PI*2 clockwise:YES]; 70 | [topCenterDot fill]; 71 | 72 | UIBezierPath *topLeftDot=[UIBezierPath bezierPath]; 73 | [topLeftDot addArcWithCenter:topLeftPoint radius:3 startAngle:0 endAngle:M_PI*2 clockwise:YES]; 74 | [topLeftDot fill]; 75 | 76 | UIBezierPath *topRightDot=[UIBezierPath bezierPath]; 77 | [topRightDot addArcWithCenter:topRightPoint radius:3 startAngle:0 endAngle:M_PI*2 clockwise:YES]; 78 | [topRightDot fill]; 79 | 80 | 81 | // bottom line 82 | 83 | UIBezierPath *bottomCenterDot=[UIBezierPath bezierPath]; 84 | [bottomCenterDot addArcWithCenter:bottomCenterPoint radius:3 startAngle:0 endAngle:M_PI*2 clockwise:YES]; 85 | [bottomCenterDot fill]; 86 | 87 | UIBezierPath *bottomLeftDot=[UIBezierPath bezierPath]; 88 | [bottomLeftDot addArcWithCenter:bottomLeftPoint radius:3 startAngle:0 endAngle:M_PI*2 clockwise:YES]; 89 | [bottomLeftDot fill]; 90 | 91 | UIBezierPath *bottomRightDot=[UIBezierPath bezierPath]; 92 | [bottomRightDot addArcWithCenter:bottomRightPoint radius:3 startAngle:0 endAngle:M_PI*2 clockwise:YES]; 93 | [bottomRightDot fill]; 94 | } 95 | else{ 96 | // center line 97 | CGFloat red, green, blue, alpha; 98 | UIColor *lineColor=self.WSMenuControlColor; 99 | [lineColor getRed: &red 100 | green: &green 101 | blue: &blue 102 | alpha: &alpha]; 103 | 104 | UIColor *centerColor=[UIColor colorWithRed:red green:green blue:blue alpha:topVlaue/5]; 105 | // if (self.isOpen) { 106 | // NSLog(@""); 107 | // centerColor=[UIColor colorWithRed:128 green:0 blue:128 alpha:0.0]; 108 | // } 109 | // else{ 110 | // 111 | // } 112 | 113 | 114 | UIBezierPath *centerLine=[UIBezierPath bezierPath]; 115 | [centerLine moveToPoint:leftPointCenter]; 116 | [centerLine addLineToPoint:CGPointMake(rect.size.width/2+10, rect.size.height/2)]; 117 | [centerColor setStroke]; 118 | [centerLine setLineWidth:3.0]; 119 | centerLine.lineCapStyle=kCGLineCapRound; 120 | [centerLine stroke]; 121 | 122 | 123 | // UIBezierPath *centerDot=[UIBezierPath bezierPath]; 124 | // [centerDot moveToPoint:centerPoint]; 125 | // [centerDot addLineToPoint:rightCenterPoint]; 126 | // [centerDot setLineWidth:2.0]; 127 | // [centerDot stroke]; 128 | // 129 | // 130 | // 131 | // UIBezierPath *rightDot=[UIBezierPath bezierPath]; 132 | // [rightDot moveToPoint:rightCenterPoint]; 133 | // [rightDot addLineToPoint:rightCenterPoint]; 134 | // [rightDot setLineWidth:2.0]; 135 | // [rightDot stroke]; 136 | 137 | 138 | // top line 139 | UIBezierPath *topLine=[UIBezierPath bezierPath]; 140 | // CGPointMake(rect.size.width/2+leftRightLenght, rect.size.height/2); 141 | [topLine moveToPoint:topLeftPoint]; 142 | //if (self.isOpen) { 143 | [topLine addLineToPoint:CGPointMake(rect.size.width/2+10, rect.size.height/2-8)]; 144 | // } 145 | // else{ 146 | // [topLine addLineToPoint:CGPointMake(rect.size.width/2+leftRightLenght, rect.size.height/2-5)]; 147 | // } 148 | 149 | 150 | [self.WSMenuControlColor setStroke]; 151 | [topLine setLineWidth:3.0]; 152 | topLine.lineCapStyle=kCGLineCapRound; 153 | [topLine stroke]; 154 | 155 | // UIBezierPath *topCenterDot=[UIBezierPath bezierPath]; 156 | // [topCenterDot moveToPoint:topCenterPoint]; 157 | // [topCenterDot addLineToPoint:topRightPoint]; 158 | // [topCenterDot setLineWidth:2.0]; 159 | // [topCenterDot stroke]; 160 | // 161 | // UIBezierPath *topRightDot=[UIBezierPath bezierPath]; 162 | // [topRightDot moveToPoint:topRightPoint]; 163 | // [topRightDot addLineToPoint:topRightPoint]; 164 | // [topRightDot setLineWidth:2.0]; 165 | // [topRightDot stroke]; 166 | 167 | 168 | // bottom line 169 | 170 | UIBezierPath *bottomLine=[UIBezierPath bezierPath]; 171 | 172 | [bottomLine moveToPoint:bottomLeftPoint]; 173 | //if (self.isOpen) { 174 | [bottomLine addLineToPoint:CGPointMake(rect.size.width/2+10, rect.size.height/2+8)]; 175 | // } 176 | // else{ 177 | // [bottomLine addLineToPoint:CGPointMake(rect.size.width/2+leftRightLenght, rect.size.height/2+5)]; 178 | // } 179 | 180 | [self.WSMenuControlColor setStroke]; 181 | [bottomLine setLineWidth:3.0]; 182 | bottomLine.lineCapStyle=kCGLineCapRound; 183 | [bottomLine stroke]; 184 | 185 | // UIBezierPath *bottomCenterDot=[UIBezierPath bezierPath]; 186 | // [bottomCenterDot moveToPoint:bottomCenterPoint]; 187 | // [bottomCenterDot addLineToPoint:bottomRightPoint]; 188 | // [bottomCenterDot setLineWidth:2.0]; 189 | // [bottomCenterDot stroke]; 190 | // 191 | // 192 | // 193 | // UIBezierPath *bottomRightDot=[UIBezierPath bezierPath]; 194 | // [bottomRightDot moveToPoint:bottomRightPoint]; 195 | // [bottomRightDot addLineToPoint:bottomRightPoint]; 196 | // [bottomRightDot setLineWidth:2.0]; 197 | // [bottomRightDot stroke]; 198 | } 199 | 200 | [self addTarget:self action:@selector(tapAction:) forControlEvents:UIControlEventTouchUpInside]; 201 | 202 | } 203 | 204 | -(void)tapAction:(UIButton *)btn{ 205 | NSLog(@"from class"); 206 | if (!isRunning) { 207 | isRunning=YES; 208 | if (!self.isOpen) { 209 | bottomValue=8; 210 | topVlaue=8; 211 | if (self.menuStyle==WSMenuStyleDot) { 212 | leftRightLenght=8; 213 | } 214 | else{ 215 | leftRightLenght=8; 216 | } 217 | self.isOpen=YES; 218 | 219 | timer=[NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(startAnimation:) userInfo:nil repeats:YES]; 220 | } 221 | else{ 222 | bottomValue=0; 223 | topVlaue=0; 224 | self.isOpen=NO; 225 | timer=[NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(startAnimation:) userInfo:nil repeats:YES]; 226 | } 227 | } 228 | 229 | } 230 | 231 | 232 | -(void)startAnimation:(NSTimer *)tm{ 233 | if (self.isOpen) { 234 | topVlaue-=0.5; 235 | bottomValue-=0.5; 236 | leftRightLenght-=0.5; 237 | 238 | if (topVlaue<=0) { 239 | isRunning=NO; 240 | [timer invalidate]; 241 | timer=nil; 242 | } 243 | } 244 | else{ 245 | topVlaue+=0.5; 246 | bottomValue+=0.5; 247 | leftRightLenght+=0.5; 248 | if (topVlaue>=8) { 249 | isRunning=NO; 250 | [timer invalidate]; 251 | timer=nil; 252 | } 253 | } 254 | [self setNeedsDisplay]; 255 | } 256 | 257 | @end 258 | -------------------------------------------------------------------------------- /WSMenuButton/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WSMenuButton 4 | // 5 | // Created by Dotsquares on 4/4/17. 6 | // Copyright © 2017 WebsoftProfession. 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 | -------------------------------------------------------------------------------- /WSMenuButtonTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /WSMenuButtonTests/WSMenuButtonTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WSMenuButtonTests.m 3 | // WSMenuButtonTests 4 | // 5 | // Created by Dotsquares on 4/4/17. 6 | // Copyright © 2017 WebsoftProfession. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WSMenuButtonTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation WSMenuButtonTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /WSMenuButtonUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /WSMenuButtonUITests/WSMenuButtonUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WSMenuButtonUITests.m 3 | // WSMenuButtonUITests 4 | // 5 | // Created by Dotsquares on 4/4/17. 6 | // Copyright © 2017 WebsoftProfession. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WSMenuButtonUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation WSMenuButtonUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /WSMenuControl_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebsoftProfession/WSMenuButton/748b9b2b9cb01d8e2ea784c5070ac781aea2edbf/WSMenuControl_1.png -------------------------------------------------------------------------------- /WSMenuControl_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebsoftProfession/WSMenuButton/748b9b2b9cb01d8e2ea784c5070ac781aea2edbf/WSMenuControl_2.png -------------------------------------------------------------------------------- /WSMenuControl_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebsoftProfession/WSMenuButton/748b9b2b9cb01d8e2ea784c5070ac781aea2edbf/WSMenuControl_3.png -------------------------------------------------------------------------------- /WSMenuControl_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebsoftProfession/WSMenuButton/748b9b2b9cb01d8e2ea784c5070ac781aea2edbf/WSMenuControl_4.png --------------------------------------------------------------------------------