├── .gitignore ├── .travis.yml ├── Example ├── FCVerticalMenu.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── FCVerticalMenu.xcscheme ├── FCVerticalMenu │ ├── Base.lproj │ │ └── Main_iPhone.storyboard │ ├── FCAppDelegate.h │ ├── FCAppDelegate.m │ ├── FCFirstViewController.h │ ├── FCFirstViewController.m │ ├── FCNavigationViewController.h │ ├── FCNavigationViewController.m │ ├── FCSecondViewController.h │ ├── FCSecondViewController.m │ ├── FCThirdViewController.h │ ├── FCThirdViewController.m │ ├── FCVerticalMenu-Info.plist │ ├── FCVerticalMenu-Prefix.pch │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── background.png │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── main.m │ ├── settings-icon.png │ └── settings-icon@2x.png ├── Podfile └── Tests │ ├── Tests-Info.plist │ ├── Tests-Prefix.pch │ ├── Tests.m │ └── en.lproj │ └── InfoPlist.strings ├── FCVerticalMenu.podspec ├── FCVerticalMenuDemo.gif ├── FCVerticalMenu_demo.png ├── LICENSE ├── Pod ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ ├── FCVerticalMenu.h │ ├── FCVerticalMenu.m │ ├── FCVerticalMenuItem.h │ ├── FCVerticalMenuItem.m │ ├── FCVerticalMenuItemCollectionViewCell.h │ └── FCVerticalMenuItemCollectionViewCell.m └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # We recommend against adding the Pods directory to your .gitignore. However 26 | # you should judge for yourself, the pros and cons are mentioned at: 27 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 28 | # 29 | # Note: if you ignore the Pods directory, make sure to uncomment 30 | # `pod install` in .travis.yml 31 | # 32 | # Pods/ 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # reference: http://www.objc.io/issue-6/travis-ci.html 2 | 3 | language: objective-c 4 | # before_install: cd Example && pod install && cd - 5 | script: 6 | - xctool test -workspace Example/FCVerticalMenu.xcworkspace -scheme FCVerticalMenu -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO 7 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; 11 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; }; 12 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 13 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F596195388D20070C39A /* InfoPlist.strings */; }; 14 | 6003F59A195388D20070C39A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F599195388D20070C39A /* main.m */; }; 15 | 6003F59E195388D20070C39A /* FCAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F59D195388D20070C39A /* FCAppDelegate.m */; }; 16 | 6003F5A1195388D20070C39A /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6003F59F195388D20070C39A /* Main_iPhone.storyboard */; }; 17 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5A8195388D20070C39A /* Images.xcassets */; }; 18 | 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F5AF195388D20070C39A /* XCTest.framework */; }; 19 | 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; 20 | 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 21 | 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; }; 22 | 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; }; 23 | 714840E271DAD4E88C372365 /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 02CA3C07B4C8BFA7562A8EC5 /* libPods-Tests.a */; }; 24 | 8189BE417A54079E721B0C5A /* libPods-FCVerticalMenu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F519950AD78FAF1020DFD14 /* libPods-FCVerticalMenu.a */; }; 25 | 8B3CB8C7D0C7A5C64AA132FE /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A741F5E9901F1E3CBD4DC15E /* libPods.a */; }; 26 | D9FF93A219FAD1E400E798D1 /* background.png in Resources */ = {isa = PBXBuildFile; fileRef = D9FF939F19FAD1E400E798D1 /* background.png */; }; 27 | D9FF93A319FAD1E400E798D1 /* settings-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = D9FF93A019FAD1E400E798D1 /* settings-icon.png */; }; 28 | D9FF93A419FAD1E400E798D1 /* settings-icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D9FF93A119FAD1E400E798D1 /* settings-icon@2x.png */; }; 29 | D9FF93AE19FAD21500E798D1 /* FCFirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D9FF93A719FAD21500E798D1 /* FCFirstViewController.m */; }; 30 | D9FF93AF19FAD21500E798D1 /* FCNavigationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D9FF93A919FAD21500E798D1 /* FCNavigationViewController.m */; }; 31 | D9FF93B019FAD21500E798D1 /* FCSecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D9FF93AB19FAD21500E798D1 /* FCSecondViewController.m */; }; 32 | D9FF93B119FAD21500E798D1 /* FCThirdViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D9FF93AD19FAD21500E798D1 /* FCThirdViewController.m */; }; 33 | /* End PBXBuildFile section */ 34 | 35 | /* Begin PBXContainerItemProxy section */ 36 | 6003F5B3195388D20070C39A /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 6003F582195388D10070C39A /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 6003F589195388D20070C39A; 41 | remoteInfo = FCVerticalMenu; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 02CA3C07B4C8BFA7562A8EC5 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 133560CDBFB0526A850E5F7D /* Pods-FCVerticalMenu.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FCVerticalMenu.release.xcconfig"; path = "Pods/Target Support Files/Pods-FCVerticalMenu/Pods-FCVerticalMenu.release.xcconfig"; sourceTree = ""; }; 48 | 1F519950AD78FAF1020DFD14 /* libPods-FCVerticalMenu.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FCVerticalMenu.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 3D343A8E7E5364D77B15BAEA /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = ""; }; 50 | 441C338D191F4A3FCF6AF04D /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 51 | 48CABA03A5F085124B4E2C49 /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = ""; }; 52 | 6003F58A195388D20070C39A /* FCVerticalMenu.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FCVerticalMenu.app; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 54 | 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 55 | 6003F591195388D20070C39A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 56 | 6003F595195388D20070C39A /* FCVerticalMenu-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "FCVerticalMenu-Info.plist"; sourceTree = ""; }; 57 | 6003F597195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 58 | 6003F599195388D20070C39A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 59 | 6003F59B195388D20070C39A /* FCVerticalMenu-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FCVerticalMenu-Prefix.pch"; sourceTree = ""; }; 60 | 6003F59C195388D20070C39A /* FCAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FCAppDelegate.h; sourceTree = ""; }; 61 | 6003F59D195388D20070C39A /* FCAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FCAppDelegate.m; sourceTree = ""; }; 62 | 6003F5A0195388D20070C39A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPhone.storyboard; sourceTree = ""; }; 63 | 6003F5A8195388D20070C39A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 64 | 6003F5AE195388D20070C39A /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | 6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 66 | 6003F5B7195388D20070C39A /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = ""; }; 67 | 6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 68 | 6003F5BB195388D20070C39A /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = ""; }; 69 | 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = ""; }; 70 | 79D29DB391A7F7A8BD678CD5 /* Pods-FCVerticalMenu.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FCVerticalMenu.debug.xcconfig"; path = "Pods/Target Support Files/Pods-FCVerticalMenu/Pods-FCVerticalMenu.debug.xcconfig"; sourceTree = ""; }; 71 | 8D7DF7693D0A8885F78BB282 /* FCVerticalMenu.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = FCVerticalMenu.podspec; path = ../FCVerticalMenu.podspec; sourceTree = ""; }; 72 | A741F5E9901F1E3CBD4DC15E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 73 | D9FF939F19FAD1E400E798D1 /* background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = background.png; sourceTree = ""; }; 74 | D9FF93A019FAD1E400E798D1 /* settings-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "settings-icon.png"; sourceTree = ""; }; 75 | D9FF93A119FAD1E400E798D1 /* settings-icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "settings-icon@2x.png"; sourceTree = ""; }; 76 | D9FF93A619FAD21500E798D1 /* FCFirstViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FCFirstViewController.h; sourceTree = ""; }; 77 | D9FF93A719FAD21500E798D1 /* FCFirstViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FCFirstViewController.m; sourceTree = ""; }; 78 | D9FF93A819FAD21500E798D1 /* FCNavigationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FCNavigationViewController.h; sourceTree = ""; }; 79 | D9FF93A919FAD21500E798D1 /* FCNavigationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FCNavigationViewController.m; sourceTree = ""; }; 80 | D9FF93AA19FAD21500E798D1 /* FCSecondViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FCSecondViewController.h; sourceTree = ""; }; 81 | D9FF93AB19FAD21500E798D1 /* FCSecondViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FCSecondViewController.m; sourceTree = ""; }; 82 | D9FF93AC19FAD21500E798D1 /* FCThirdViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FCThirdViewController.h; sourceTree = ""; }; 83 | D9FF93AD19FAD21500E798D1 /* FCThirdViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FCThirdViewController.m; sourceTree = ""; }; 84 | FD71D10D05262DA142C90B58 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 85 | /* End PBXFileReference section */ 86 | 87 | /* Begin PBXFrameworksBuildPhase section */ 88 | 6003F587195388D20070C39A /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */, 93 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */, 94 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */, 95 | 8189BE417A54079E721B0C5A /* libPods-FCVerticalMenu.a in Frameworks */, 96 | 8B3CB8C7D0C7A5C64AA132FE /* libPods.a in Frameworks */, 97 | ); 98 | runOnlyForDeploymentPostprocessing = 0; 99 | }; 100 | 6003F5AB195388D20070C39A /* Frameworks */ = { 101 | isa = PBXFrameworksBuildPhase; 102 | buildActionMask = 2147483647; 103 | files = ( 104 | 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */, 105 | 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */, 106 | 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */, 107 | 714840E271DAD4E88C372365 /* libPods-Tests.a in Frameworks */, 108 | ); 109 | runOnlyForDeploymentPostprocessing = 0; 110 | }; 111 | /* End PBXFrameworksBuildPhase section */ 112 | 113 | /* Begin PBXGroup section */ 114 | 6003F581195388D10070C39A = { 115 | isa = PBXGroup; 116 | children = ( 117 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */, 118 | 6003F593195388D20070C39A /* FCVerticalMenu */, 119 | 6003F5B5195388D20070C39A /* Tests */, 120 | 6003F58C195388D20070C39A /* Frameworks */, 121 | 6003F58B195388D20070C39A /* Products */, 122 | E922B37EC6C5D38F996FFCEA /* Pods */, 123 | ); 124 | sourceTree = ""; 125 | }; 126 | 6003F58B195388D20070C39A /* Products */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 6003F58A195388D20070C39A /* FCVerticalMenu.app */, 130 | 6003F5AE195388D20070C39A /* Tests.xctest */, 131 | ); 132 | name = Products; 133 | sourceTree = ""; 134 | }; 135 | 6003F58C195388D20070C39A /* Frameworks */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 6003F58D195388D20070C39A /* Foundation.framework */, 139 | 6003F58F195388D20070C39A /* CoreGraphics.framework */, 140 | 6003F591195388D20070C39A /* UIKit.framework */, 141 | 6003F5AF195388D20070C39A /* XCTest.framework */, 142 | 1F519950AD78FAF1020DFD14 /* libPods-FCVerticalMenu.a */, 143 | 02CA3C07B4C8BFA7562A8EC5 /* libPods-Tests.a */, 144 | A741F5E9901F1E3CBD4DC15E /* libPods.a */, 145 | ); 146 | name = Frameworks; 147 | sourceTree = ""; 148 | }; 149 | 6003F593195388D20070C39A /* FCVerticalMenu */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | D9FF93A519FAD20700E798D1 /* Controller */, 153 | D9FF939E19FAD1C100E798D1 /* Assets */, 154 | 6003F59C195388D20070C39A /* FCAppDelegate.h */, 155 | 6003F59D195388D20070C39A /* FCAppDelegate.m */, 156 | 6003F59F195388D20070C39A /* Main_iPhone.storyboard */, 157 | 6003F5A8195388D20070C39A /* Images.xcassets */, 158 | 6003F594195388D20070C39A /* Supporting Files */, 159 | ); 160 | path = FCVerticalMenu; 161 | sourceTree = ""; 162 | }; 163 | 6003F594195388D20070C39A /* Supporting Files */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | 6003F595195388D20070C39A /* FCVerticalMenu-Info.plist */, 167 | 6003F596195388D20070C39A /* InfoPlist.strings */, 168 | 6003F599195388D20070C39A /* main.m */, 169 | 6003F59B195388D20070C39A /* FCVerticalMenu-Prefix.pch */, 170 | ); 171 | name = "Supporting Files"; 172 | sourceTree = ""; 173 | }; 174 | 6003F5B5195388D20070C39A /* Tests */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 6003F5BB195388D20070C39A /* Tests.m */, 178 | 6003F5B6195388D20070C39A /* Supporting Files */, 179 | ); 180 | path = Tests; 181 | sourceTree = ""; 182 | }; 183 | 6003F5B6195388D20070C39A /* Supporting Files */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | 6003F5B7195388D20070C39A /* Tests-Info.plist */, 187 | 6003F5B8195388D20070C39A /* InfoPlist.strings */, 188 | 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */, 189 | ); 190 | name = "Supporting Files"; 191 | sourceTree = ""; 192 | }; 193 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = { 194 | isa = PBXGroup; 195 | children = ( 196 | 8D7DF7693D0A8885F78BB282 /* FCVerticalMenu.podspec */, 197 | FD71D10D05262DA142C90B58 /* README.md */, 198 | 441C338D191F4A3FCF6AF04D /* LICENSE */, 199 | ); 200 | name = "Podspec Metadata"; 201 | sourceTree = ""; 202 | }; 203 | D9FF939E19FAD1C100E798D1 /* Assets */ = { 204 | isa = PBXGroup; 205 | children = ( 206 | D9FF939F19FAD1E400E798D1 /* background.png */, 207 | D9FF93A019FAD1E400E798D1 /* settings-icon.png */, 208 | D9FF93A119FAD1E400E798D1 /* settings-icon@2x.png */, 209 | ); 210 | name = Assets; 211 | sourceTree = ""; 212 | }; 213 | D9FF93A519FAD20700E798D1 /* Controller */ = { 214 | isa = PBXGroup; 215 | children = ( 216 | D9FF93A819FAD21500E798D1 /* FCNavigationViewController.h */, 217 | D9FF93A919FAD21500E798D1 /* FCNavigationViewController.m */, 218 | D9FF93B219FAD22000E798D1 /* Example Controllers */, 219 | ); 220 | name = Controller; 221 | sourceTree = ""; 222 | }; 223 | D9FF93B219FAD22000E798D1 /* Example Controllers */ = { 224 | isa = PBXGroup; 225 | children = ( 226 | D9FF93A619FAD21500E798D1 /* FCFirstViewController.h */, 227 | D9FF93A719FAD21500E798D1 /* FCFirstViewController.m */, 228 | D9FF93AA19FAD21500E798D1 /* FCSecondViewController.h */, 229 | D9FF93AB19FAD21500E798D1 /* FCSecondViewController.m */, 230 | D9FF93AC19FAD21500E798D1 /* FCThirdViewController.h */, 231 | D9FF93AD19FAD21500E798D1 /* FCThirdViewController.m */, 232 | ); 233 | name = "Example Controllers"; 234 | sourceTree = ""; 235 | }; 236 | E922B37EC6C5D38F996FFCEA /* Pods */ = { 237 | isa = PBXGroup; 238 | children = ( 239 | 79D29DB391A7F7A8BD678CD5 /* Pods-FCVerticalMenu.debug.xcconfig */, 240 | 133560CDBFB0526A850E5F7D /* Pods-FCVerticalMenu.release.xcconfig */, 241 | 48CABA03A5F085124B4E2C49 /* Pods-Tests.debug.xcconfig */, 242 | 3D343A8E7E5364D77B15BAEA /* Pods-Tests.release.xcconfig */, 243 | ); 244 | name = Pods; 245 | sourceTree = ""; 246 | }; 247 | /* End PBXGroup section */ 248 | 249 | /* Begin PBXNativeTarget section */ 250 | 6003F589195388D20070C39A /* FCVerticalMenu */ = { 251 | isa = PBXNativeTarget; 252 | buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "FCVerticalMenu" */; 253 | buildPhases = ( 254 | D3829E17B5F7BCBAD684FD21 /* Check Pods Manifest.lock */, 255 | 6003F586195388D20070C39A /* Sources */, 256 | 6003F587195388D20070C39A /* Frameworks */, 257 | 6003F588195388D20070C39A /* Resources */, 258 | DC73DFDF5413C2729E1C3DFA /* Copy Pods Resources */, 259 | ); 260 | buildRules = ( 261 | ); 262 | dependencies = ( 263 | ); 264 | name = FCVerticalMenu; 265 | productName = FCVerticalMenu; 266 | productReference = 6003F58A195388D20070C39A /* FCVerticalMenu.app */; 267 | productType = "com.apple.product-type.application"; 268 | }; 269 | 6003F5AD195388D20070C39A /* Tests */ = { 270 | isa = PBXNativeTarget; 271 | buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "Tests" */; 272 | buildPhases = ( 273 | 0E81451EDC3DE23093F689CA /* Check Pods Manifest.lock */, 274 | 6003F5AA195388D20070C39A /* Sources */, 275 | 6003F5AB195388D20070C39A /* Frameworks */, 276 | 6003F5AC195388D20070C39A /* Resources */, 277 | E68B063605C6DBF190858DF2 /* Copy Pods Resources */, 278 | ); 279 | buildRules = ( 280 | ); 281 | dependencies = ( 282 | 6003F5B4195388D20070C39A /* PBXTargetDependency */, 283 | ); 284 | name = Tests; 285 | productName = FCVerticalMenuTests; 286 | productReference = 6003F5AE195388D20070C39A /* Tests.xctest */; 287 | productType = "com.apple.product-type.bundle.unit-test"; 288 | }; 289 | /* End PBXNativeTarget section */ 290 | 291 | /* Begin PBXProject section */ 292 | 6003F582195388D10070C39A /* Project object */ = { 293 | isa = PBXProject; 294 | attributes = { 295 | CLASSPREFIX = FC; 296 | LastUpgradeCheck = 0510; 297 | ORGANIZATIONNAME = "Filippo Camillo"; 298 | TargetAttributes = { 299 | 6003F5AD195388D20070C39A = { 300 | TestTargetID = 6003F589195388D20070C39A; 301 | }; 302 | }; 303 | }; 304 | buildConfigurationList = 6003F585195388D10070C39A /* Build configuration list for PBXProject "FCVerticalMenu" */; 305 | compatibilityVersion = "Xcode 3.2"; 306 | developmentRegion = English; 307 | hasScannedForEncodings = 0; 308 | knownRegions = ( 309 | en, 310 | Base, 311 | ); 312 | mainGroup = 6003F581195388D10070C39A; 313 | productRefGroup = 6003F58B195388D20070C39A /* Products */; 314 | projectDirPath = ""; 315 | projectRoot = ""; 316 | targets = ( 317 | 6003F589195388D20070C39A /* FCVerticalMenu */, 318 | 6003F5AD195388D20070C39A /* Tests */, 319 | ); 320 | }; 321 | /* End PBXProject section */ 322 | 323 | /* Begin PBXResourcesBuildPhase section */ 324 | 6003F588195388D20070C39A /* Resources */ = { 325 | isa = PBXResourcesBuildPhase; 326 | buildActionMask = 2147483647; 327 | files = ( 328 | D9FF93A319FAD1E400E798D1 /* settings-icon.png in Resources */, 329 | D9FF93A419FAD1E400E798D1 /* settings-icon@2x.png in Resources */, 330 | D9FF93A219FAD1E400E798D1 /* background.png in Resources */, 331 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */, 332 | 6003F5A1195388D20070C39A /* Main_iPhone.storyboard in Resources */, 333 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */, 334 | ); 335 | runOnlyForDeploymentPostprocessing = 0; 336 | }; 337 | 6003F5AC195388D20070C39A /* Resources */ = { 338 | isa = PBXResourcesBuildPhase; 339 | buildActionMask = 2147483647; 340 | files = ( 341 | 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */, 342 | ); 343 | runOnlyForDeploymentPostprocessing = 0; 344 | }; 345 | /* End PBXResourcesBuildPhase section */ 346 | 347 | /* Begin PBXShellScriptBuildPhase section */ 348 | 0E81451EDC3DE23093F689CA /* Check Pods Manifest.lock */ = { 349 | isa = PBXShellScriptBuildPhase; 350 | buildActionMask = 2147483647; 351 | files = ( 352 | ); 353 | inputPaths = ( 354 | ); 355 | name = "Check Pods Manifest.lock"; 356 | outputPaths = ( 357 | ); 358 | runOnlyForDeploymentPostprocessing = 0; 359 | shellPath = /bin/sh; 360 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 361 | showEnvVarsInLog = 0; 362 | }; 363 | D3829E17B5F7BCBAD684FD21 /* Check Pods Manifest.lock */ = { 364 | isa = PBXShellScriptBuildPhase; 365 | buildActionMask = 2147483647; 366 | files = ( 367 | ); 368 | inputPaths = ( 369 | ); 370 | name = "Check Pods Manifest.lock"; 371 | outputPaths = ( 372 | ); 373 | runOnlyForDeploymentPostprocessing = 0; 374 | shellPath = /bin/sh; 375 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 376 | showEnvVarsInLog = 0; 377 | }; 378 | DC73DFDF5413C2729E1C3DFA /* Copy Pods Resources */ = { 379 | isa = PBXShellScriptBuildPhase; 380 | buildActionMask = 2147483647; 381 | files = ( 382 | ); 383 | inputPaths = ( 384 | ); 385 | name = "Copy Pods Resources"; 386 | outputPaths = ( 387 | ); 388 | runOnlyForDeploymentPostprocessing = 0; 389 | shellPath = /bin/sh; 390 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-FCVerticalMenu/Pods-FCVerticalMenu-resources.sh\"\n"; 391 | showEnvVarsInLog = 0; 392 | }; 393 | E68B063605C6DBF190858DF2 /* Copy Pods Resources */ = { 394 | isa = PBXShellScriptBuildPhase; 395 | buildActionMask = 2147483647; 396 | files = ( 397 | ); 398 | inputPaths = ( 399 | ); 400 | name = "Copy Pods Resources"; 401 | outputPaths = ( 402 | ); 403 | runOnlyForDeploymentPostprocessing = 0; 404 | shellPath = /bin/sh; 405 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-resources.sh\"\n"; 406 | showEnvVarsInLog = 0; 407 | }; 408 | /* End PBXShellScriptBuildPhase section */ 409 | 410 | /* Begin PBXSourcesBuildPhase section */ 411 | 6003F586195388D20070C39A /* Sources */ = { 412 | isa = PBXSourcesBuildPhase; 413 | buildActionMask = 2147483647; 414 | files = ( 415 | D9FF93AF19FAD21500E798D1 /* FCNavigationViewController.m in Sources */, 416 | D9FF93B119FAD21500E798D1 /* FCThirdViewController.m in Sources */, 417 | 6003F59E195388D20070C39A /* FCAppDelegate.m in Sources */, 418 | D9FF93AE19FAD21500E798D1 /* FCFirstViewController.m in Sources */, 419 | 6003F59A195388D20070C39A /* main.m in Sources */, 420 | D9FF93B019FAD21500E798D1 /* FCSecondViewController.m in Sources */, 421 | ); 422 | runOnlyForDeploymentPostprocessing = 0; 423 | }; 424 | 6003F5AA195388D20070C39A /* Sources */ = { 425 | isa = PBXSourcesBuildPhase; 426 | buildActionMask = 2147483647; 427 | files = ( 428 | 6003F5BC195388D20070C39A /* Tests.m in Sources */, 429 | ); 430 | runOnlyForDeploymentPostprocessing = 0; 431 | }; 432 | /* End PBXSourcesBuildPhase section */ 433 | 434 | /* Begin PBXTargetDependency section */ 435 | 6003F5B4195388D20070C39A /* PBXTargetDependency */ = { 436 | isa = PBXTargetDependency; 437 | target = 6003F589195388D20070C39A /* FCVerticalMenu */; 438 | targetProxy = 6003F5B3195388D20070C39A /* PBXContainerItemProxy */; 439 | }; 440 | /* End PBXTargetDependency section */ 441 | 442 | /* Begin PBXVariantGroup section */ 443 | 6003F596195388D20070C39A /* InfoPlist.strings */ = { 444 | isa = PBXVariantGroup; 445 | children = ( 446 | 6003F597195388D20070C39A /* en */, 447 | ); 448 | name = InfoPlist.strings; 449 | sourceTree = ""; 450 | }; 451 | 6003F59F195388D20070C39A /* Main_iPhone.storyboard */ = { 452 | isa = PBXVariantGroup; 453 | children = ( 454 | 6003F5A0195388D20070C39A /* Base */, 455 | ); 456 | name = Main_iPhone.storyboard; 457 | sourceTree = ""; 458 | }; 459 | 6003F5B8195388D20070C39A /* InfoPlist.strings */ = { 460 | isa = PBXVariantGroup; 461 | children = ( 462 | 6003F5B9195388D20070C39A /* en */, 463 | ); 464 | name = InfoPlist.strings; 465 | sourceTree = ""; 466 | }; 467 | /* End PBXVariantGroup section */ 468 | 469 | /* Begin XCBuildConfiguration section */ 470 | 6003F5BD195388D20070C39A /* Debug */ = { 471 | isa = XCBuildConfiguration; 472 | buildSettings = { 473 | ALWAYS_SEARCH_USER_PATHS = NO; 474 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 475 | CLANG_CXX_LIBRARY = "libc++"; 476 | CLANG_ENABLE_MODULES = YES; 477 | CLANG_ENABLE_OBJC_ARC = YES; 478 | CLANG_WARN_BOOL_CONVERSION = YES; 479 | CLANG_WARN_CONSTANT_CONVERSION = YES; 480 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 481 | CLANG_WARN_EMPTY_BODY = YES; 482 | CLANG_WARN_ENUM_CONVERSION = YES; 483 | CLANG_WARN_INT_CONVERSION = YES; 484 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 485 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 486 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 487 | COPY_PHASE_STRIP = NO; 488 | GCC_C_LANGUAGE_STANDARD = gnu99; 489 | GCC_DYNAMIC_NO_PIC = NO; 490 | GCC_OPTIMIZATION_LEVEL = 0; 491 | GCC_PREPROCESSOR_DEFINITIONS = ( 492 | "DEBUG=1", 493 | "$(inherited)", 494 | ); 495 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 496 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 497 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 498 | GCC_WARN_UNDECLARED_SELECTOR = YES; 499 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 500 | GCC_WARN_UNUSED_FUNCTION = YES; 501 | GCC_WARN_UNUSED_VARIABLE = YES; 502 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 503 | ONLY_ACTIVE_ARCH = YES; 504 | SDKROOT = iphoneos; 505 | TARGETED_DEVICE_FAMILY = "1,2"; 506 | }; 507 | name = Debug; 508 | }; 509 | 6003F5BE195388D20070C39A /* Release */ = { 510 | isa = XCBuildConfiguration; 511 | buildSettings = { 512 | ALWAYS_SEARCH_USER_PATHS = NO; 513 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 514 | CLANG_CXX_LIBRARY = "libc++"; 515 | CLANG_ENABLE_MODULES = YES; 516 | CLANG_ENABLE_OBJC_ARC = YES; 517 | CLANG_WARN_BOOL_CONVERSION = YES; 518 | CLANG_WARN_CONSTANT_CONVERSION = YES; 519 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 520 | CLANG_WARN_EMPTY_BODY = YES; 521 | CLANG_WARN_ENUM_CONVERSION = YES; 522 | CLANG_WARN_INT_CONVERSION = YES; 523 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 524 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 525 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 526 | COPY_PHASE_STRIP = YES; 527 | ENABLE_NS_ASSERTIONS = NO; 528 | GCC_C_LANGUAGE_STANDARD = gnu99; 529 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 530 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 531 | GCC_WARN_UNDECLARED_SELECTOR = YES; 532 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 533 | GCC_WARN_UNUSED_FUNCTION = YES; 534 | GCC_WARN_UNUSED_VARIABLE = YES; 535 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 536 | SDKROOT = iphoneos; 537 | TARGETED_DEVICE_FAMILY = "1,2"; 538 | VALIDATE_PRODUCT = YES; 539 | }; 540 | name = Release; 541 | }; 542 | 6003F5C0195388D20070C39A /* Debug */ = { 543 | isa = XCBuildConfiguration; 544 | baseConfigurationReference = 79D29DB391A7F7A8BD678CD5 /* Pods-FCVerticalMenu.debug.xcconfig */; 545 | buildSettings = { 546 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 547 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 548 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 549 | GCC_PREFIX_HEADER = "FCVerticalMenu/FCVerticalMenu-Prefix.pch"; 550 | INFOPLIST_FILE = "FCVerticalMenu/FCVerticalMenu-Info.plist"; 551 | PRODUCT_NAME = "$(TARGET_NAME)"; 552 | TARGETED_DEVICE_FAMILY = 1; 553 | WRAPPER_EXTENSION = app; 554 | }; 555 | name = Debug; 556 | }; 557 | 6003F5C1195388D20070C39A /* Release */ = { 558 | isa = XCBuildConfiguration; 559 | baseConfigurationReference = 133560CDBFB0526A850E5F7D /* Pods-FCVerticalMenu.release.xcconfig */; 560 | buildSettings = { 561 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 562 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 563 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 564 | GCC_PREFIX_HEADER = "FCVerticalMenu/FCVerticalMenu-Prefix.pch"; 565 | INFOPLIST_FILE = "FCVerticalMenu/FCVerticalMenu-Info.plist"; 566 | PRODUCT_NAME = "$(TARGET_NAME)"; 567 | TARGETED_DEVICE_FAMILY = 1; 568 | WRAPPER_EXTENSION = app; 569 | }; 570 | name = Release; 571 | }; 572 | 6003F5C3195388D20070C39A /* Debug */ = { 573 | isa = XCBuildConfiguration; 574 | baseConfigurationReference = 48CABA03A5F085124B4E2C49 /* Pods-Tests.debug.xcconfig */; 575 | buildSettings = { 576 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/FCVerticalMenu.app/FCVerticalMenu"; 577 | FRAMEWORK_SEARCH_PATHS = ( 578 | "$(SDKROOT)/Developer/Library/Frameworks", 579 | "$(inherited)", 580 | "$(DEVELOPER_FRAMEWORKS_DIR)", 581 | ); 582 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 583 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; 584 | GCC_PREPROCESSOR_DEFINITIONS = ( 585 | "DEBUG=1", 586 | "$(inherited)", 587 | ); 588 | INFOPLIST_FILE = "Tests/Tests-Info.plist"; 589 | PRODUCT_NAME = "$(TARGET_NAME)"; 590 | TEST_HOST = "$(BUNDLE_LOADER)"; 591 | WRAPPER_EXTENSION = xctest; 592 | }; 593 | name = Debug; 594 | }; 595 | 6003F5C4195388D20070C39A /* Release */ = { 596 | isa = XCBuildConfiguration; 597 | baseConfigurationReference = 3D343A8E7E5364D77B15BAEA /* Pods-Tests.release.xcconfig */; 598 | buildSettings = { 599 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/FCVerticalMenu.app/FCVerticalMenu"; 600 | FRAMEWORK_SEARCH_PATHS = ( 601 | "$(SDKROOT)/Developer/Library/Frameworks", 602 | "$(inherited)", 603 | "$(DEVELOPER_FRAMEWORKS_DIR)", 604 | ); 605 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 606 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; 607 | INFOPLIST_FILE = "Tests/Tests-Info.plist"; 608 | PRODUCT_NAME = "$(TARGET_NAME)"; 609 | TEST_HOST = "$(BUNDLE_LOADER)"; 610 | WRAPPER_EXTENSION = xctest; 611 | }; 612 | name = Release; 613 | }; 614 | /* End XCBuildConfiguration section */ 615 | 616 | /* Begin XCConfigurationList section */ 617 | 6003F585195388D10070C39A /* Build configuration list for PBXProject "FCVerticalMenu" */ = { 618 | isa = XCConfigurationList; 619 | buildConfigurations = ( 620 | 6003F5BD195388D20070C39A /* Debug */, 621 | 6003F5BE195388D20070C39A /* Release */, 622 | ); 623 | defaultConfigurationIsVisible = 0; 624 | defaultConfigurationName = Release; 625 | }; 626 | 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "FCVerticalMenu" */ = { 627 | isa = XCConfigurationList; 628 | buildConfigurations = ( 629 | 6003F5C0195388D20070C39A /* Debug */, 630 | 6003F5C1195388D20070C39A /* Release */, 631 | ); 632 | defaultConfigurationIsVisible = 0; 633 | defaultConfigurationName = Release; 634 | }; 635 | 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "Tests" */ = { 636 | isa = XCConfigurationList; 637 | buildConfigurations = ( 638 | 6003F5C3195388D20070C39A /* Debug */, 639 | 6003F5C4195388D20070C39A /* Release */, 640 | ); 641 | defaultConfigurationIsVisible = 0; 642 | defaultConfigurationName = Release; 643 | }; 644 | /* End XCConfigurationList section */ 645 | }; 646 | rootObject = 6003F582195388D10070C39A /* Project object */; 647 | } 648 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu.xcodeproj/xcshareddata/xcschemes/FCVerticalMenu.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/Base.lproj/Main_iPhone.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 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/FCAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // FCAppDelegate.h 3 | // FCVerticalMenu 4 | // 5 | // Created by CocoaPods on 10/24/2014. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FCAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/FCAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // FCAppDelegate.m 3 | // FCVerticalMenu 4 | // 5 | // Created by CocoaPods on 10/24/2014. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import "FCAppDelegate.h" 10 | 11 | @implementation FCAppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // 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. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/FCFirstViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FCFirstViewController.h 3 | // FCVerticalMenu 4 | // 5 | // Created by Filippo Camillo on 23/10/14. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FCFirstViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/FCFirstViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FCFirstViewController.m 3 | // FCVerticalMenu 4 | // 5 | // Created by Filippo Camillo on 23/10/14. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import "FCFirstViewController.h" 10 | #import "FCNavigationViewController.h" 11 | 12 | @implementation FCFirstViewController 13 | 14 | 15 | -(void)viewDidLoad 16 | { 17 | [super viewDidLoad]; 18 | self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Menu" style:UIBarButtonItemStyleBordered target:self.navigationController action:@selector(openVerticalMenu:)]; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/FCNavigationViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FCViewController.h 3 | // FCVerticalMenu 4 | // 5 | // Created by Filippo Camillo on 10/23/2014. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | @interface FCNavigationViewController : UINavigationController 14 | 15 | @property (strong, readonly, nonatomic) FCVerticalMenu *verticalMenu; 16 | 17 | -(IBAction)openVerticalMenu:(id)sender; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/FCNavigationViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FCViewController.m 3 | // FCVerticalMenu 4 | // 5 | // Created by Filippo Camillo on 10/23/2014. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import "FCNavigationViewController.h" 10 | #import "FCFirstViewController.h" 11 | #import "FCSecondViewController.h" 12 | 13 | @interface FCNavigationViewController () 14 | 15 | @end 16 | 17 | @implementation FCNavigationViewController 18 | 19 | - (void)viewDidLoad 20 | { 21 | [super viewDidLoad]; 22 | [self configureVerticalMenu]; 23 | self.verticalMenu.delegate = self; 24 | 25 | self.navigationBar.barStyle = UIBarStyleBlack; 26 | self.verticalMenu.liveBlurBackgroundStyle = self.navigationBar.barStyle; 27 | self.navigationBar.tintColor = [UIColor whiteColor]; 28 | } 29 | 30 | - (void)didReceiveMemoryWarning 31 | { 32 | [super didReceiveMemoryWarning]; 33 | // Dispose of any resources that can be recreated. 34 | } 35 | 36 | 37 | #pragma mark - FCVerticalMenu Configuration 38 | - (void)configureVerticalMenu 39 | { 40 | FCVerticalMenuItem *item1 = [[FCVerticalMenuItem alloc] initWithTitle:@"First Menu" 41 | andIconImage:[UIImage imageNamed:@"settings-icon"]]; 42 | 43 | FCVerticalMenuItem *item2 = [[FCVerticalMenuItem alloc] initWithTitle:@"Second Menu" 44 | andIconImage:nil]; 45 | 46 | FCVerticalMenuItem *item3 = [[FCVerticalMenuItem alloc] initWithTitle:@"Third Menu" 47 | andIconImage:nil]; 48 | 49 | FCVerticalMenuItem *item4 = [[FCVerticalMenuItem alloc] initWithTitle:@"Fourth Menu" 50 | andIconImage:nil]; 51 | 52 | FCVerticalMenuItem *item5 = [[FCVerticalMenuItem alloc] initWithTitle:@"Fifth Menu" 53 | andIconImage:nil]; 54 | 55 | FCVerticalMenuItem *item6 = [[FCVerticalMenuItem alloc] initWithTitle:@"Sixth Menu" 56 | andIconImage:nil]; 57 | 58 | item1.actionBlock = ^{ 59 | NSLog(@"test element 1"); 60 | FCFirstViewController *vc = [[UIStoryboard storyboardWithName:@"Main_iPhone" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"FirstViewController"]; 61 | if ([self.viewControllers[0] isEqual:vc]) 62 | return; 63 | 64 | [self setViewControllers:@[vc] animated:NO]; 65 | }; 66 | item2.actionBlock = ^{ 67 | NSLog(@"test element 2"); 68 | FCSecondViewController *vc = [[UIStoryboard storyboardWithName:@"Main_iPhone" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"SecondViewController"]; 69 | 70 | if ([self.viewControllers[0] isEqual:vc]) 71 | return; 72 | 73 | [self setViewControllers:@[vc] animated:NO]; 74 | 75 | }; 76 | item3.actionBlock = ^{ 77 | NSLog(@"test element 3"); 78 | 79 | if ([self.viewControllers[0] isKindOfClass:[FCSecondViewController class]]) { 80 | [self.viewControllers[0] doSomething]; 81 | return; 82 | } 83 | 84 | FCSecondViewController *vc = [[UIStoryboard storyboardWithName:@"Main_iPhone" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"SecondViewController"]; 85 | 86 | [self setViewControllers:@[vc] animated:NO]; 87 | [vc doSomething]; 88 | 89 | }; 90 | item4.actionBlock = ^{ 91 | NSLog(@"test element 4"); 92 | FCSecondViewController *vc = [[UIStoryboard storyboardWithName:@"Main_iPhone" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"ThirdViewController"]; 93 | 94 | if ([self.viewControllers[0] isEqual:vc]) 95 | return; 96 | 97 | [self setViewControllers:@[vc] animated:NO]; 98 | 99 | }; 100 | item5.actionBlock = ^{ 101 | NSLog(@"test element 5"); 102 | }; 103 | item6.actionBlock = ^{ 104 | NSLog(@"test element 6"); 105 | }; 106 | 107 | 108 | _verticalMenu = [[FCVerticalMenu alloc] initWithItems:@[item1, item2, item3, item4, item5, item6]]; 109 | _verticalMenu.appearsBehindNavigationBar = YES; 110 | 111 | } 112 | 113 | -(IBAction)openVerticalMenu:(id)sender 114 | { 115 | if (_verticalMenu.isOpen) 116 | return [_verticalMenu dismissWithCompletionBlock:nil]; 117 | 118 | [_verticalMenu showFromNavigationBar:self.navigationBar inView:self.view]; 119 | } 120 | 121 | 122 | #pragma mark - FCVerticalMenu Delegate Methods 123 | 124 | -(void)menuWillOpen:(FCVerticalMenu *)menu 125 | { 126 | NSLog(@"menuWillOpen hook"); 127 | } 128 | 129 | -(void)menuDidOpen:(FCVerticalMenu *)menu 130 | { 131 | NSLog(@"menuDidOpen hook"); 132 | } 133 | 134 | -(void)menuWillClose:(FCVerticalMenu *)menu 135 | { 136 | NSLog(@"menuWillClose hook"); 137 | } 138 | 139 | -(void)menuDidClose:(FCVerticalMenu *)menu 140 | { 141 | NSLog(@"menuDidClose hook"); 142 | } 143 | 144 | @end 145 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/FCSecondViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FCSecondViewController.h 3 | // FCVerticalMenu 4 | // 5 | // Created by Filippo Camillo on 23/10/14. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FCSecondViewController : UIViewController 12 | 13 | 14 | -(void)doSomething; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/FCSecondViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FCSecondViewController.m 3 | // FCVerticalMenu 4 | // 5 | // Created by Filippo Camillo on 23/10/14. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import "FCSecondViewController.h" 10 | #import "FCNavigationViewController.h" 11 | 12 | @implementation FCSecondViewController 13 | 14 | -(void)viewDidLoad 15 | { 16 | [super viewDidLoad]; 17 | self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Menu" style:UIBarButtonItemStyleBordered target:self.navigationController action:@selector(openVerticalMenu:)]; 18 | } 19 | 20 | -(void)doSomething 21 | { 22 | self.view.backgroundColor = [UIColor redColor]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/FCThirdViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FCThirdViewController.h 3 | // FCVerticalMenu 4 | // 5 | // Created by Filippo Camillo on 24/10/14. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FCThirdViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/FCThirdViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FCThirdViewController.m 3 | // FCVerticalMenu 4 | // 5 | // Created by Filippo Camillo on 24/10/14. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import "FCThirdViewController.h" 10 | #import "FCNavigationViewController.h" 11 | 12 | @implementation FCThirdViewController 13 | 14 | -(void)viewDidLoad 15 | { 16 | [super viewDidLoad]; 17 | self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Menu" style:UIBarButtonItemStyleBordered target:self.navigationController action:@selector(openVerticalMenu:)]; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/FCVerticalMenu-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | Main_iPhone 29 | UIMainStoryboardFile~ipad 30 | Main_iPad 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/FCVerticalMenu-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filippocamillo/FCVerticalMenu/92eedcc3837936be36217631a120ee5a0201bed3/Example/FCVerticalMenu/background.png -------------------------------------------------------------------------------- /Example/FCVerticalMenu/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // FCVerticalMenu 4 | // 5 | // Created by Filippo Camillo on 10/24/2014. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "FCAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([FCAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/FCVerticalMenu/settings-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filippocamillo/FCVerticalMenu/92eedcc3837936be36217631a120ee5a0201bed3/Example/FCVerticalMenu/settings-icon.png -------------------------------------------------------------------------------- /Example/FCVerticalMenu/settings-icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filippocamillo/FCVerticalMenu/92eedcc3837936be36217631a120ee5a0201bed3/Example/FCVerticalMenu/settings-icon@2x.png -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | 3 | target 'FCVerticalMenu', :exclusive => true do 4 | pod "FCVerticalMenu", :path => "../" 5 | end 6 | 7 | target 'Tests', :exclusive => true do 8 | pod "FCVerticalMenu", :path => "../" 9 | 10 | 11 | end 12 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every test case source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | 9 | 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /Example/Tests/Tests.m: -------------------------------------------------------------------------------- 1 | // 2 | // FCVerticalMenuTests.m 3 | // FCVerticalMenuTests 4 | // 5 | // Created by Filippo Camillo on 10/24/2014. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | ${TEST_EXAMPLE} 10 | -------------------------------------------------------------------------------- /Example/Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /FCVerticalMenu.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint FCVerticalMenu.podspec' to ensure this is a 3 | # valid spec and remove all comments before submitting the spec. 4 | # 5 | # Any lines starting with a # are optional, but encouraged 6 | # 7 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 8 | # 9 | 10 | Pod::Spec.new do |s| 11 | s.name = "FCVerticalMenu" 12 | s.version = "0.1.2" 13 | s.summary = "A dropdown menu completely customizable" 14 | s.homepage = "https://github.com/filippocamillo/FCVerticalMenu" 15 | s.screenshots = "https://github.com/filippocamillo/FCVerticalMenu/raw/master/FCVerticalMenu_demo.png", "https://github.com/filippocamillo/FCVerticalMenu/raw/master/FCVerticalMenuDemo.gif" 16 | s.license = 'MIT' 17 | s.author = { "Filippo Camillo" => "hello@filippocamillo.com" } 18 | s.source = { :git => "https://github.com/filippocamillo/FCVerticalMenu.git", :tag => s.version.to_s } 19 | s.social_media_url = 'https://twitter.com/filippocamillo' 20 | 21 | s.platform = :ios, '7.0' 22 | s.requires_arc = true 23 | 24 | s.source_files = 'Pod/Classes' 25 | s.resource_bundles = { 26 | 'FCVerticalMenu' => ['Pod/Assets/*.png'] 27 | } 28 | 29 | # s.public_header_files = 'Pod/Classes/**/*.h' 30 | s.frameworks = 'UIKit', 'QuartzCore' 31 | 32 | end 33 | -------------------------------------------------------------------------------- /FCVerticalMenuDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filippocamillo/FCVerticalMenu/92eedcc3837936be36217631a120ee5a0201bed3/FCVerticalMenuDemo.gif -------------------------------------------------------------------------------- /FCVerticalMenu_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filippocamillo/FCVerticalMenu/92eedcc3837936be36217631a120ee5a0201bed3/FCVerticalMenu_demo.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Filippo Camillo 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Pod/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filippocamillo/FCVerticalMenu/92eedcc3837936be36217631a120ee5a0201bed3/Pod/Assets/.gitkeep -------------------------------------------------------------------------------- /Pod/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/filippocamillo/FCVerticalMenu/92eedcc3837936be36217631a120ee5a0201bed3/Pod/Classes/.gitkeep -------------------------------------------------------------------------------- /Pod/Classes/FCVerticalMenu.h: -------------------------------------------------------------------------------- 1 | // 2 | // FCVerticalMenu.h 3 | // VerticalSideMenu 4 | // 5 | // Created by Filippo Camillo on 14/10/14. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "FCVerticalMenuItem.h" 12 | 13 | @class FCVerticalMenu; 14 | 15 | @protocol FCVerticalMenuDelegate 16 | @optional 17 | -(void)menuWillOpen:(FCVerticalMenu *)menu; 18 | -(void)menuDidOpen:(FCVerticalMenu *)menu; 19 | -(void)menuWillClose:(FCVerticalMenu *)menu; 20 | -(void)menuDidClose:(FCVerticalMenu *)menu; 21 | @end 22 | 23 | 24 | @interface FCVerticalMenu : NSObject 25 | 26 | // Properties 27 | // 28 | @property (strong, readwrite, nonatomic) NSArray *items; 29 | @property (assign, readonly, nonatomic) BOOL isOpen; 30 | @property (assign, readonly, nonatomic) BOOL isAnimating; 31 | @property (assign, readwrite, nonatomic) BOOL closeOnSelection; 32 | @property (weak, readwrite, nonatomic) id delegate; 33 | 34 | @property (strong, nonatomic) UICollectionView *menuCollection; 35 | 36 | 37 | 38 | // Style properties 39 | // 40 | 41 | @property (strong, readwrite, nonatomic) UICollectionViewFlowLayout *menuLayout; 42 | 43 | @property (strong, readwrite, nonatomic) UIColor *shadowColor; 44 | @property (assign, readwrite, nonatomic) CGSize shadowOffset; 45 | @property (assign, readwrite, nonatomic) CGFloat shadowOpacity; 46 | @property (assign, readwrite, nonatomic) CGFloat shadowRadius; 47 | @property (assign, readwrite, nonatomic) CGFloat backgroundAlpha; 48 | @property (strong, readwrite, nonatomic) UIColor *backgroundColor; 49 | 50 | 51 | @property (strong, readwrite, nonatomic) UIFont *font; 52 | @property (strong, readwrite, nonatomic) UIColor *textColor; 53 | @property (strong, readwrite, nonatomic) UIColor *textShadowColor; 54 | @property (strong, readwrite, nonatomic) UIColor *imageTintColor; 55 | @property (strong, readwrite, nonatomic) UIColor *highlightedBackgroundColor; 56 | @property (strong, readwrite, nonatomic) UIColor *highlightedTextColor; 57 | @property (strong, readwrite, nonatomic) UIColor *highlightedTextShadowColor; 58 | @property (strong, readwrite, nonatomic) UIColor *highlightedImageTintColor; 59 | @property (assign, readwrite, nonatomic) CGFloat borderWidth; 60 | @property (strong, readwrite, nonatomic) UIColor *borderColor; 61 | @property (assign, readwrite, nonatomic) NSTextAlignment textAlignment; 62 | 63 | 64 | @property (assign, readwrite, nonatomic) NSTimeInterval animationDuration; 65 | @property (assign, readwrite, nonatomic) NSTimeInterval closeAnimationDuration; 66 | @property (assign, readwrite, nonatomic) NSTimeInterval bounceAnimationDuration; 67 | @property (assign, readwrite, nonatomic) BOOL appearsBehindNavigationBar; 68 | @property (assign, readwrite, nonatomic) BOOL bounce; 69 | 70 | // only iOS 7+ 71 | // liveBlur is automatically activated 72 | // 73 | @property (assign, readwrite, nonatomic) BOOL liveBlur; 74 | @property (strong, readwrite, nonatomic) UIColor *liveBlurTintColor; 75 | @property (assign, readwrite, nonatomic) UIBarStyle liveBlurBackgroundStyle; 76 | 77 | 78 | 79 | 80 | //Methods 81 | // 82 | - (id)initWithItems:(NSArray*)itemsList; 83 | - (void)showFromNavigationBar:(UINavigationBar*)navigationBar inView:(UIView *)view; 84 | - (void)showFromRect:(CGRect)rect inView:(UIView *)view; 85 | - (void)dismissWithCompletionBlock:(void (^)(void))completion; 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /Pod/Classes/FCVerticalMenu.m: -------------------------------------------------------------------------------- 1 | // 2 | // FCVerticalMenu.m 3 | // VerticalSideMenu 4 | // 5 | // Created by Filippo Camillo on 14/10/14. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import "FCVerticalMenu.h" 10 | #import "FCVerticalMenuItem.h" 11 | #import "FCVerticalMenuItemCollectionViewCell.h" 12 | 13 | @interface FCVerticalMenu () 14 | @property (assign, readwrite, nonatomic) BOOL isOpen; 15 | @property (assign, readwrite, nonatomic) BOOL isAnimating; 16 | @property (strong, readwrite, nonatomic) UIView *containerView; 17 | @property (strong, readwrite, nonatomic) UIView *menuView; 18 | @property (strong, readwrite, nonatomic) UIToolbar *toolbar; 19 | 20 | - (CGFloat)navigationBarOffset; 21 | @end 22 | 23 | @implementation FCVerticalMenu 24 | 25 | 26 | - (id)init 27 | { 28 | self = [super init]; 29 | if (self) { 30 | 31 | // Setting default appeareance and settings 32 | // 33 | _closeOnSelection = YES; 34 | 35 | _font = [UIFont fontWithName:@"Helvetica-Light" size:14]; 36 | _textColor = [UIColor whiteColor]; 37 | _textShadowColor = [UIColor blackColor]; 38 | _textAlignment = NSTextAlignmentCenter; 39 | 40 | _imageTintColor = [UIColor whiteColor]; 41 | _highlightedImageTintColor = _imageTintColor; 42 | 43 | _highlightedBackgroundColor = [UIColor colorWithRed:155.0/255.0 green:155.0/255.0 blue:155.0/255.0 alpha:1.0]; 44 | _highlightedTextColor = [UIColor colorWithRed:128/255.0 green:126/255.0 blue:124/255.0 alpha:1.0]; 45 | _highlightedTextShadowColor = [UIColor blackColor]; 46 | 47 | _borderWidth = 0.5; 48 | _borderColor = [UIColor whiteColor]; 49 | 50 | _backgroundAlpha = 0.95; 51 | _backgroundColor = [UIColor colorWithRed:53/255.0 green:53/255.0 blue:52/255.0 alpha:1.0]; 52 | _liveBlurTintColor = nil; 53 | _liveBlur = YES; 54 | 55 | _animationDuration = 0.3; 56 | _closeAnimationDuration = 0.2; 57 | _bounce = YES; 58 | _bounceAnimationDuration = 0.2; 59 | 60 | 61 | _menuLayout = [[UICollectionViewFlowLayout alloc] init]; 62 | // setting cell attributes globally via layout properties /////////////// 63 | 64 | _menuLayout.itemSize = CGSizeMake(80, 100); 65 | _menuLayout.minimumInteritemSpacing = 15; 66 | _menuLayout.minimumLineSpacing = 15; 67 | _menuLayout.scrollDirection = UICollectionViewScrollDirectionVertical; 68 | _menuLayout.sectionInset = UIEdgeInsetsMake(25, 25, 25, 25); 69 | 70 | _menuCollection = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:_menuLayout]; 71 | [_menuCollection registerClass:[FCVerticalMenuItemCollectionViewCell class] forCellWithReuseIdentifier:@"menuItem"]; 72 | _menuCollection.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 73 | 74 | 75 | _menuCollection.backgroundColor = [UIColor clearColor]; 76 | _menuCollection.delegate = self; 77 | _menuCollection.dataSource = self; 78 | 79 | 80 | } 81 | return self; 82 | } 83 | 84 | 85 | 86 | /** 87 | * Init the menu with an array of FCVerticalMenuItem 88 | * 89 | * @param itemsList an array of object FCVerticalMenuItem 90 | * 91 | */ 92 | - (id)initWithItems:(NSArray*)itemsList 93 | { 94 | self = [self init]; 95 | if (self) { 96 | self.items = itemsList; 97 | for (FCVerticalMenuItem *anItem in self.items) { 98 | //do something with the item 99 | NSInteger index = [self.items indexOfObject:anItem]; 100 | 101 | anItem.index = index; 102 | 103 | anItem.font = _font; 104 | anItem.textColor = _textColor; 105 | anItem.textShadowColor = _textShadowColor; 106 | anItem.textAlignment = _textAlignment; 107 | anItem.highlightedBackgroundColor = _highlightedBackgroundColor; 108 | anItem.highlightedTextColor = _highlightedTextColor; 109 | anItem.highlightedTextShadowColor = _highlightedTextShadowColor; 110 | anItem.borderWidth = _borderWidth; 111 | anItem.borderColor = _borderColor; 112 | anItem.imageTintColor = _imageTintColor; 113 | anItem.highlightedImageTintColor = _highlightedImageTintColor; 114 | 115 | } 116 | } 117 | 118 | return self; 119 | } 120 | 121 | /** 122 | * Setup and add gesture recognizer 123 | */ 124 | -(void)setupGesture { 125 | UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureAction:)]; 126 | panGestureRecognizer.maximumNumberOfTouches = 1; 127 | panGestureRecognizer.minimumNumberOfTouches = 1; 128 | [self.containerView addGestureRecognizer:panGestureRecognizer]; 129 | } 130 | 131 | 132 | /** 133 | * show the menu from the navigationBar and bring the navbar to front 134 | * 135 | * @param navigationBar the navigationBar 136 | * @param view the view container 137 | */ 138 | - (void)showFromNavigationBar:(UINavigationBar*)navigationBar inView:(UIView *)view 139 | { 140 | [self showFromRect:navigationBar.frame inView:view]; 141 | 142 | if (self.appearsBehindNavigationBar) { 143 | [view bringSubviewToFront:navigationBar]; 144 | } 145 | } 146 | 147 | /** 148 | * show the menu from the rect 149 | * 150 | * @param rect a CGrect from where the rect is showed 151 | * @param view an UIView where the menu is showed 152 | */ 153 | - (void)showFromRect:(CGRect)rect inView:(UIView *)view 154 | { 155 | if (self.isAnimating) { 156 | return; 157 | } 158 | 159 | self.isOpen = YES; 160 | self.isAnimating = YES; 161 | 162 | // Create views 163 | // 164 | self.containerView = ({ 165 | UIView *view = [[UIView alloc] init]; 166 | view.autoresizingMask = UIViewAutoresizingFlexibleWidth; 167 | if (!self.liveBlur) { 168 | view.layer.opacity = self.backgroundAlpha; 169 | view.backgroundColor = self.backgroundColor; 170 | view.layer.shadowColor = self.shadowColor.CGColor; 171 | view.layer.shadowOffset = self.shadowOffset; 172 | view.layer.shadowOpacity = self.shadowOpacity; 173 | view.layer.shadowRadius = self.shadowRadius; 174 | view.layer.shouldRasterize = YES; 175 | view.layer.rasterizationScale = [UIScreen mainScreen].scale; 176 | } 177 | view; 178 | }); 179 | 180 | if (self.liveBlur) { 181 | self.toolbar = ({ 182 | UIToolbar *toolbar = [[UIToolbar alloc] init]; 183 | toolbar.barStyle = self.liveBlurBackgroundStyle; 184 | if ([toolbar respondsToSelector:@selector(setBarTintColor:)]) 185 | [toolbar performSelector:@selector(setBarTintColor:) withObject:self.liveBlurTintColor]; 186 | toolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth; 187 | toolbar.layer.masksToBounds = YES; 188 | toolbar; 189 | }); 190 | } 191 | 192 | self.menuView = ({ 193 | UIView *view = [[UIView alloc] init]; 194 | view.layer.masksToBounds = YES; 195 | view.layer.shouldRasterize = YES; 196 | view.layer.rasterizationScale = [UIScreen mainScreen].scale; 197 | view.autoresizingMask = UIViewAutoresizingFlexibleWidth; 198 | 199 | 200 | view; 201 | }); 202 | 203 | // Set up frames 204 | // 205 | 206 | // Adding the collectionview with temporary frame 207 | // 208 | [self.menuCollection setFrame:rect]; 209 | [self.menuView addSubview:self.menuCollection]; 210 | 211 | //initial container position 212 | self.containerView.frame = CGRectMake(0, -[self totalHeight], rect.size.width, [self totalHeight]); 213 | 214 | //menu frame 215 | self.menuView.frame = CGRectMake(0, 40 + [self navigationBarOffset], rect.size.width, self.containerView.bounds.size.height-40); 216 | 217 | 218 | if (self.toolbar && self.liveBlur) { 219 | self.toolbar.frame = self.containerView.bounds; 220 | [self.containerView addSubview:self.toolbar]; 221 | } 222 | 223 | 224 | // Add subviews 225 | // 226 | [self.containerView addSubview:self.menuView]; 227 | [view addSubview:self.containerView]; 228 | 229 | // Changing the MenuCollectionView frame with the real one 230 | // 231 | self.menuCollection.frame = self.menuView.bounds; 232 | 233 | if ([self.delegate respondsToSelector:@selector(menuWillOpen:)]) { 234 | [self.delegate menuWillOpen:self]; 235 | } 236 | 237 | 238 | // Set up gestures 239 | // 240 | [self setupGesture]; 241 | 242 | 243 | // Animate presentation 244 | // 245 | if (self.bounce) { 246 | self.isAnimating = YES; 247 | if ([UIView respondsToSelector:@selector(animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:)]) { 248 | [UIView animateWithDuration:self.animationDuration+self.bounceAnimationDuration 249 | delay:0.0 250 | usingSpringWithDamping:0.6 251 | initialSpringVelocity:4.0 252 | options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseInOut 253 | animations:^{ 254 | CGRect frame = self.containerView.frame; 255 | frame.origin.y = -40.0; 256 | self.containerView.frame = frame; 257 | } completion:^(BOOL finished) { 258 | self.isAnimating = NO; 259 | if ([self.delegate respondsToSelector:@selector(menuDidOpen:)]) { 260 | [self.delegate menuDidOpen:self]; 261 | } 262 | }]; 263 | } else { 264 | [UIView animateWithDuration:self.animationDuration 265 | delay:0.0 266 | options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseInOut 267 | animations:^{ 268 | CGRect frame = self.containerView.frame; 269 | frame.origin.y = -40.0; 270 | self.containerView.frame = frame; 271 | } completion:^(BOOL finished) { 272 | self.isAnimating = NO; 273 | if ([self.delegate respondsToSelector:@selector(menuDidOpen:)]) { 274 | [self.delegate menuDidOpen:self]; 275 | } 276 | }]; 277 | 278 | } 279 | } else { 280 | [UIView animateWithDuration:self.animationDuration 281 | delay:0.0 282 | options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseInOut 283 | animations:^{ 284 | CGRect frame = self.containerView.frame; 285 | frame.origin.y = -40.0; 286 | self.containerView.frame = frame; 287 | } completion:^(BOOL finished) { 288 | self.isAnimating = NO; 289 | if ([self.delegate respondsToSelector:@selector(menuDidOpen:)]) { 290 | [self.delegate menuDidOpen:self]; 291 | } 292 | }]; 293 | } 294 | } 295 | 296 | 297 | 298 | #pragma mark - Frame utils 299 | 300 | /** 301 | * Calculate the actual height of the vertical menu 302 | * 303 | * @return return the height as CGfloat 304 | */ 305 | - (CGFloat)totalHeight 306 | { 307 | CGFloat navigationBarOffset = [self navigationBarOffset]; 308 | return _menuCollection.collectionViewLayout.collectionViewContentSize.height + navigationBarOffset + 60; 309 | } 310 | 311 | 312 | - (CGFloat)navigationBarOffset 313 | { 314 | return self.appearsBehindNavigationBar? 64.0f : 0.0f; 315 | } 316 | 317 | 318 | /** 319 | * Present the menu 320 | * 321 | * @param completion a completion block 322 | */ 323 | - (void)presentWithCompletionBlock:(void (^)(void))completion 324 | { 325 | if (self.isAnimating) return; 326 | 327 | self.isAnimating = YES; 328 | [UIView animateWithDuration:self.animationDuration 329 | delay:0.0 330 | options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseOut 331 | animations:^{ 332 | CGRect frame = self.containerView.frame; 333 | frame.origin.y = -40.0; 334 | self.containerView.frame = frame; 335 | } completion:^(BOOL finished) { 336 | self.isAnimating = NO; 337 | //this is the parameter completion block 338 | if (completion) { 339 | completion(); 340 | } 341 | }]; 342 | } 343 | 344 | /** 345 | * Dismiss the menu 346 | * 347 | * @param completion a completion block 348 | */ 349 | - (void)dismissWithCompletionBlock:(void (^)(void))completion 350 | { 351 | if (self.isAnimating) return; 352 | 353 | self.isAnimating = YES; 354 | 355 | //animation block 356 | void (^closeMenu)(void) = ^{ 357 | [UIView animateWithDuration:self.closeAnimationDuration 358 | delay:0.0 359 | options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseInOut 360 | animations:^ { 361 | CGRect frame = self.containerView.frame; 362 | frame.origin.y = - [self totalHeight]; 363 | self.containerView.frame = frame; 364 | } completion:^(BOOL finished) { 365 | self.isOpen = NO; 366 | self.isAnimating = NO; 367 | 368 | [self.menuView removeFromSuperview]; 369 | [self.containerView removeFromSuperview]; 370 | 371 | //this is the parameter completion block 372 | if (completion) { 373 | completion(); 374 | } 375 | 376 | if ([self.delegate respondsToSelector:@selector(menuDidClose:)]) { 377 | [self.delegate menuDidClose:self]; 378 | } 379 | }]; 380 | 381 | }; 382 | 383 | if ([self.delegate respondsToSelector:@selector(menuWillClose:)]) { 384 | [self.delegate menuWillClose:self]; 385 | } 386 | 387 | if (self.bounce) { 388 | [UIView animateWithDuration:self.bounceAnimationDuration animations:^{ 389 | CGRect frame = self.containerView.frame; 390 | frame.origin.y = -20.0; 391 | self.containerView.frame = frame; 392 | } completion:^(BOOL finished) { 393 | closeMenu(); 394 | }]; 395 | } else { 396 | closeMenu(); 397 | } 398 | } 399 | 400 | 401 | 402 | 403 | #pragma mark - CollectionView DataSource protocol 404 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 405 | { 406 | return [self.items count]; 407 | } 408 | 409 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 410 | { 411 | FCVerticalMenuItemCollectionViewCell *cell = (FCVerticalMenuItemCollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:@"menuItem" forIndexPath:indexPath]; 412 | 413 | cell.theMenuItem = self.items[indexPath.row]; 414 | 415 | return cell; 416 | } 417 | 418 | 419 | #pragma mark - CollectionView Delegate protocol 420 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 421 | { 422 | FCVerticalMenuItemCollectionViewCell *cell = (FCVerticalMenuItemCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath]; 423 | 424 | if (cell.theMenuItem.actionBlock) { 425 | cell.theMenuItem.actionBlock(); 426 | } 427 | 428 | if (_closeOnSelection) { 429 | self.bounce = NO; 430 | [self dismissWithCompletionBlock:^{ 431 | self.bounce = YES; 432 | }]; 433 | } 434 | 435 | } 436 | 437 | - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath 438 | { 439 | FCVerticalMenuItemCollectionViewCell *cell = (FCVerticalMenuItemCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath]; 440 | 441 | [cell setHighlighted:NO]; 442 | 443 | } 444 | 445 | 446 | #pragma mark - Gesture Recognizer 447 | - (void)panGestureAction:(UIPanGestureRecognizer *)recognizer 448 | { 449 | 450 | if( ([recognizer state] == UIGestureRecognizerStateBegan) || 451 | ([recognizer state] == UIGestureRecognizerStateChanged) ) 452 | { 453 | CGPoint translation = [recognizer translationInView:self.containerView]; 454 | CGRect old_rect = self.containerView.frame; 455 | 456 | 457 | if (translation.y+recognizer.view.frame.origin.y>-40) { 458 | return; 459 | } 460 | 461 | old_rect.origin.y = old_rect.origin.y + translation.y; 462 | 463 | self.containerView.frame = old_rect; 464 | 465 | [recognizer setTranslation:CGPointZero inView:self.containerView]; 466 | } 467 | else if(recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled) 468 | { 469 | CGFloat halfPoint = (self.containerView.frame.size.height) * -0.20; 470 | if(self.containerView.frame.origin.y <= halfPoint) 471 | { 472 | self.bounce = NO; 473 | [self dismissWithCompletionBlock:^{ 474 | self.bounce = YES; 475 | }]; 476 | } 477 | else 478 | { 479 | [self presentWithCompletionBlock:nil]; 480 | } 481 | } 482 | 483 | } 484 | 485 | @end 486 | -------------------------------------------------------------------------------- /Pod/Classes/FCVerticalMenuItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // FCVerticalMenuItem.h 3 | // VerticalSideMenu 4 | // 5 | // Created by Filippo Camillo on 14/10/14. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef void (^ActionBlock)(); 13 | 14 | @interface FCVerticalMenuItem : NSObject 15 | 16 | @property (nonatomic, readonly, assign) CGFloat calculatedHeight; 17 | @property (nonatomic, readonly, assign) CGFloat calculatedWidth; 18 | @property (nonatomic, assign) NSInteger index; 19 | @property (nonatomic, strong) NSString *title; 20 | @property (nonatomic, strong) UIImage *icon; 21 | @property(readwrite, copy) ActionBlock actionBlock; 22 | 23 | 24 | //style 25 | @property (strong, readwrite, nonatomic) UIFont *font; 26 | @property (strong, readwrite, nonatomic) UIColor *textColor; 27 | @property (strong, readwrite, nonatomic) UIColor *textShadowColor; 28 | @property (strong, readwrite, nonatomic) UIColor *imageTintColor; 29 | @property (strong, readwrite, nonatomic) UIColor *highlightedBackgroundColor; 30 | @property (strong, readwrite, nonatomic) UIColor *highlightedTextColor; 31 | @property (strong, readwrite, nonatomic) UIColor *highlightedTextShadowColor; 32 | @property (strong, readwrite, nonatomic) UIColor *highlightedImageTintColor; 33 | @property (assign, readwrite, nonatomic) CGFloat borderWidth; 34 | @property (strong, readwrite, nonatomic) UIColor *borderColor; 35 | @property (assign, readwrite, nonatomic) NSTextAlignment textAlignment; 36 | 37 | 38 | 39 | - (id)initWithTitle:(NSString*)theTitle andIconImage:(UIImage*)theIcon; 40 | 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Pod/Classes/FCVerticalMenuItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // FCVerticalMenuItem.m 3 | // VerticalSideMenu 4 | // 5 | // Created by Filippo Camillo on 14/10/14. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import "FCVerticalMenuItem.h" 10 | 11 | 12 | @interface FCVerticalMenuItem () 13 | 14 | @end 15 | 16 | @implementation FCVerticalMenuItem 17 | 18 | 19 | 20 | - (id)init 21 | { 22 | self = [super init]; 23 | if (self) { 24 | } 25 | return self; 26 | } 27 | 28 | 29 | - (id)initWithTitle:(NSString*)theTitle andIconImage:(UIImage*)theIcon 30 | { 31 | self = [self init]; 32 | if (self) { 33 | _title = theTitle; 34 | _icon = theIcon; 35 | } 36 | return self; 37 | 38 | } 39 | 40 | - (CGFloat)calculatedHeight 41 | { 42 | //TODO: calculate height with label and icon 43 | return 100.0; 44 | } 45 | 46 | - (CGFloat)calculatedWidth 47 | { 48 | //TODO: calculate width 49 | return 100.0; 50 | } 51 | 52 | 53 | 54 | 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Pod/Classes/FCVerticalMenuItemCollectionViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // FCVerticalMenuItemCollectionViewCell.h 3 | // VerticalSideMenu 4 | // 5 | // Created by Filippo Camillo on 16/10/14. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FCVerticalMenuItem; 12 | 13 | @interface FCVerticalMenuItemCollectionViewCell : UICollectionViewCell 14 | 15 | @property (nonatomic, strong) FCVerticalMenuItem *theMenuItem; 16 | @property (nonatomic, strong) UIImageView *imageView; 17 | @property (nonatomic, strong) UILabel *titleLabel; 18 | @property (nonatomic, strong) UILabel *placeholderLabel; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Pod/Classes/FCVerticalMenuItemCollectionViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // FCVerticalMenuItemCollectionViewCell.m 3 | // VerticalSideMenu 4 | // 5 | // Created by Filippo Camillo on 16/10/14. 6 | // Copyright (c) 2014 Filippo Camillo. All rights reserved. 7 | // 8 | 9 | #import "FCVerticalMenuItemCollectionViewCell.h" 10 | #import "FCVerticalMenuItem.h" 11 | 12 | @interface FCVerticalMenuItemCollectionViewCell() 13 | -(UIImage *)image:(UIImage *)img withColor:(UIColor *)color; 14 | @end 15 | 16 | @implementation FCVerticalMenuItemCollectionViewCell 17 | 18 | //TODO: implement these properties 19 | // UIColor *textShadowColor; 20 | // UIColor *highlightedTextColor; 21 | // UIColor *highlightedTextShadowColor; 22 | 23 | - (id)initWithFrame:(CGRect)frame 24 | { 25 | self = [super initWithFrame:frame]; 26 | if (self) 27 | { 28 | _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(25, 25, frame.size.width-50, frame.size.height-70)]; 29 | [self addSubview:_imageView]; 30 | _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, frame.size.height-20, frame.size.width, 40)]; 31 | [self addSubview:_titleLabel]; 32 | _placeholderLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height-20)]; 33 | 34 | 35 | } 36 | return self; 37 | } 38 | 39 | - (void)drawRect:(CGRect)rect { 40 | [super drawRect:rect]; 41 | 42 | CGContextRef ctx = UIGraphicsGetCurrentContext(); 43 | 44 | CGContextSetLineWidth(ctx, _theMenuItem.borderWidth); 45 | CGRect newRect = CGRectMake(rect.origin.x+5, rect.origin.y+5, rect.size.width-10, rect.size.height-30); 46 | 47 | if (self.highlighted) { 48 | CGContextSetFillColor(ctx, CGColorGetComponents([_theMenuItem.highlightedBackgroundColor CGColor])); 49 | CGContextSetStrokeColorWithColor(ctx, [_theMenuItem.borderColor CGColor]); 50 | CGContextFillEllipseInRect(ctx, newRect); 51 | } else { 52 | CGContextSetStrokeColorWithColor(ctx, [_theMenuItem.borderColor CGColor]); 53 | CGContextStrokeEllipseInRect (ctx, newRect); 54 | } 55 | 56 | // CGContextClosePath(ctx); 57 | 58 | if (_theMenuItem.icon) { 59 | [_placeholderLabel removeFromSuperview]; 60 | 61 | UIColor *tintColor = _theMenuItem.imageTintColor; 62 | 63 | if (self.highlighted) { 64 | tintColor = _theMenuItem.highlightedImageTintColor; 65 | } 66 | 67 | if (tintColor) 68 | _imageView.image = [self image:_theMenuItem.icon withColor:tintColor]; 69 | else 70 | _imageView.image = _theMenuItem.icon; 71 | 72 | _imageView.contentMode = UIViewContentModeScaleAspectFit; 73 | 74 | 75 | } else { 76 | UIColor *tintColor = _theMenuItem.imageTintColor; 77 | 78 | if (self.highlighted) 79 | tintColor = _theMenuItem.highlightedImageTintColor; 80 | 81 | // CGContextRef ctx = UIGraphicsGetCurrentContext(); 82 | CGContextSetFillColorWithColor(ctx, [tintColor CGColor]); 83 | CGContextFillEllipseInRect(ctx, CGRectMake(30, 30, rect.size.width-60, rect.size.height-80)); 84 | // CGContextClosePath(ctx); 85 | 86 | } 87 | 88 | _titleLabel.backgroundColor = [UIColor clearColor]; 89 | _titleLabel.textColor = _theMenuItem.textColor; 90 | _titleLabel.font = _theMenuItem.font; 91 | _titleLabel.textAlignment = _theMenuItem.textAlignment; 92 | _titleLabel.numberOfLines = 2; 93 | [_titleLabel setText:_theMenuItem.title]; 94 | [_titleLabel sizeToFit]; 95 | 96 | CGRect newFrame = _titleLabel.frame; 97 | newFrame = CGRectMake(newFrame.origin.x, newFrame.origin.y, rect.size.width, newFrame.size.height); 98 | _titleLabel.frame = newFrame; 99 | 100 | } 101 | 102 | - (void)layoutSubviews 103 | { 104 | self.backgroundColor = [UIColor clearColor]; 105 | } 106 | 107 | 108 | - (void)configureForItem:(FCVerticalMenuItem*)menuItem 109 | { 110 | [self setNeedsDisplay]; 111 | } 112 | 113 | -(void)setTheMenuItem:(FCVerticalMenuItem *)theMenuItem 114 | { 115 | _theMenuItem = theMenuItem; 116 | [self setNeedsDisplay]; 117 | } 118 | 119 | 120 | -(void)setHighlighted:(BOOL)highlighted { 121 | [super setHighlighted:highlighted]; 122 | [self setNeedsDisplay]; 123 | } 124 | 125 | 126 | /** 127 | * Create and return an image tinted with a color 128 | * 129 | * @param img the source image 130 | * @param color the tint color 131 | * 132 | * @return new UIImage 133 | */ 134 | -(UIImage *)image:(UIImage *)img withColor:(UIColor *)color { 135 | if (color) { 136 | // Construct new image the same size as this one. 137 | UIImage *image; 138 | UIGraphicsBeginImageContextWithOptions([img size], NO, 0.0); // 0.0 for scale means "scale for device's main screen". 139 | CGRect rect = CGRectZero; 140 | rect.size = [img size]; 141 | 142 | // tint the image 143 | [img drawInRect:rect]; 144 | [color set]; 145 | UIRectFillUsingBlendMode(rect, kCGBlendModeMultiply); 146 | 147 | // restore alpha channel 148 | [img drawInRect:rect blendMode:kCGBlendModeDestinationIn alpha:1.0f]; 149 | 150 | image = UIGraphicsGetImageFromCurrentImageContext(); 151 | UIGraphicsEndImageContext(); 152 | 153 | return image; 154 | } 155 | 156 | return img; 157 | } 158 | 159 | 160 | @end 161 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FCVerticalMenu 2 | 3 | A vertical menu animated and fully customizable. 4 | 5 | FCVerticalMenu Screenshot FCVerticalMenu Demo 6 | ## Requirements 7 | 8 | Xcode 6 or higher 9 | Apple LLVM compiler 10 | iOS 7.0 or higher 11 | ARC 12 | 13 | 14 | ## Demo 15 | 16 | Build the demo project with Xcode 6+. Take a look at the FCNavigatorViewController in which everything is configured. 17 | 18 | ## Installation 19 | 20 | FCVerticalMenu is available through [CocoaPods](http://cocoapods.org). 21 | 22 | 23 | Install CocoaPods if you don't: 24 | 25 | ``` bash 26 | $ [sudo] gem install cocoapods 27 | $ pod setup 28 | ``` 29 | 30 | Change to the directory of your Xcode project: 31 | 32 | ``` bash 33 | $ cd /path/to/YourProject 34 | $ touch Podfile 35 | $ edit Podfile 36 | ``` 37 | 38 | To install FCVerticalMenu, simply add the following line to your Podfile: 39 | 40 | ``` bash 41 | source 'https://github.com/CocoaPods/Specs.git' 42 | 43 | platform :ios, '7.0' 44 | pod "FCVerticalMenu" 45 | ``` 46 | 47 | 48 | Install for your project as usual: 49 | 50 | ``` bash 51 | $ pod install 52 | ``` 53 | 54 | Finally start working with the .xcworkspace file instead of .xcproject as usual 55 | 56 | ``` bash 57 | $ open YourProject.xcworkspace 58 | ``` 59 | 60 | 61 | 62 | ## Example Usage 63 | 64 | ``` objective-c 65 | FCVerticalMenuItem *item1 = [[FCVerticalMenuItem alloc] initWithTitle:@"First Menu" andIconImage:[UIImage imageNamed:@"settings-icon"]]; 66 | 67 | item1.actionBlock = ^{ 68 | NSLog(@"test element 1"); 69 | }; 70 | 71 | 72 | self.verticalMenu = [[FCVerticalMenu alloc] initWithItems:@[item1]]; 73 | self.verticalMenu.appearsBehindNavigationBar = YES; 74 | 75 | [self.verticalMenu showFromNavigationBar:self.navigationBar inView:self.view]; 76 | 77 | ``` 78 | 79 | 80 | ## Fully customizable 81 | 82 | You can customize the appearance of the menu: 83 | 84 | ``` objective-c 85 | 86 | @property (strong, readwrite, nonatomic) UICollectionViewFlowLayout *menuLayout; 87 | 88 | @property (strong, readwrite, nonatomic) UIColor *shadowColor; 89 | @property (assign, readwrite, nonatomic) CGSize shadowOffset; 90 | @property (assign, readwrite, nonatomic) CGFloat shadowOpacity; 91 | @property (assign, readwrite, nonatomic) CGFloat shadowRadius; 92 | @property (assign, readwrite, nonatomic) CGFloat backgroundAlpha; 93 | @property (strong, readwrite, nonatomic) UIColor *backgroundColor; 94 | 95 | @property (strong, readwrite, nonatomic) UIFont *font; 96 | @property (strong, readwrite, nonatomic) UIColor *textColor; 97 | @property (strong, readwrite, nonatomic) UIColor *textShadowColor; 98 | @property (strong, readwrite, nonatomic) UIColor *imageTintColor; 99 | @property (strong, readwrite, nonatomic) UIColor *highlightedBackgroundColor; 100 | @property (strong, readwrite, nonatomic) UIColor *highlightedTextColor; 101 | @property (strong, readwrite, nonatomic) UIColor *highlightedTextShadowColor; 102 | @property (strong, readwrite, nonatomic) UIColor *highlightedImageTintColor; 103 | @property (assign, readwrite, nonatomic) CGFloat borderWidth; 104 | @property (strong, readwrite, nonatomic) UIColor *borderColor; 105 | @property (assign, readwrite, nonatomic) NSTextAlignment textAlignment; 106 | 107 | @property (assign, readwrite, nonatomic) NSTimeInterval animationDuration; 108 | @property (assign, readwrite, nonatomic) NSTimeInterval closeAnimationDuration; 109 | @property (assign, readwrite, nonatomic) NSTimeInterval bounceAnimationDuration; 110 | @property (assign, readwrite, nonatomic) BOOL appearsBehindNavigationBar; 111 | @property (assign, readwrite, nonatomic) BOOL bounce; 112 | 113 | // only iOS 7+ 114 | // liveBlur is automatically activated 115 | // 116 | @property (assign, readwrite, nonatomic) BOOL liveBlur; 117 | @property (strong, readwrite, nonatomic) UIColor *liveBlurTintColor; 118 | @property (assign, readwrite, nonatomic) UIBarStyle liveBlurBackgroundStyle; 119 | ``` 120 | 121 | ## Delegate Methods 122 | 123 | You can also take advantage of the delegate methods just implementing it. 124 | 125 | Remember to adopt the delegate in your controller and set the delegate with self.verticalMenu.delegate = self; 126 | 127 | ``` objective-c 128 | @protocol FCVerticalMenuDelegate 129 | @optional 130 | -(void)menuWillOpen:(FCVerticalMenu *)menu; 131 | -(void)menuDidOpen:(FCVerticalMenu *)menu; 132 | -(void)menuWillClose:(FCVerticalMenu *)menu; 133 | -(void)menuDidClose:(FCVerticalMenu *)menu; 134 | @end 135 | ``` 136 | 137 | ## Author 138 | 139 | Filippo Camillo 140 | 141 | - http://www.filippocamillo.com 142 | - hello@filippocamillo.com 143 | 144 | 145 | ## License 146 | 147 | FCVerticalMenu is available under the MIT license. See the LICENSE file for more info. 148 | 149 | [![Version](https://img.shields.io/cocoapods/v/FCVerticalMenu.svg?style=flat)](http://cocoadocs.org/docsets/FCVerticalMenu) 150 | [![License](https://img.shields.io/cocoapods/l/FCVerticalMenu.svg?style=flat)](http://cocoadocs.org/docsets/FCVerticalMenu) 151 | [![Platform](https://img.shields.io/cocoapods/p/FCVerticalMenu.svg?style=flat)](http://cocoadocs.org/docsets/FCVerticalMenu) 152 | 153 | --------------------------------------------------------------------------------