├── .gitignore ├── LeftSlide.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── huangzhenyu.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── huangzhenyu.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── LeftSlide.xcscheme │ └── xcschememanagement.plist ├── LeftSlide ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ └── LaunchScreen.xib ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── leftbackiamge.imageset │ │ ├── Contents.json │ │ └── leftbackiamge.png │ └── menu.imageset │ │ ├── Contents.json │ │ └── menu@2x.png ├── Info.plist ├── LeftSlideViewController │ ├── LeftSlideViewController.h │ ├── LeftSlideViewController.m │ ├── UIView_extra.h │ └── UIView_extra.m ├── LeftSortsViewController.h ├── LeftSortsViewController.m ├── MainPageViewController.h ├── MainPageViewController.m ├── main.m ├── otherViewController.h └── otherViewController.m ├── LeftSlideTests ├── Info.plist └── LeftSlideTests.m ├── LeftSlideViewController ├── LeftSlideViewController.h ├── LeftSlideViewController.m ├── UIView_extra.h └── UIView_extra.m ├── README.md └── leftSlideMenu.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | build/ 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | xcuserdata 12 | *.xccheckout 13 | *.moved-aside 14 | DerivedData 15 | *.hmap 16 | *.ipa 17 | *.xcuserstate 18 | libDBPlayer.release.a 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | #Pods/ 27 | -------------------------------------------------------------------------------- /LeftSlide.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | EEA1808E1B328F1500A3186D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = EEA1808D1B328F1500A3186D /* main.m */; }; 11 | EEA180911B328F1500A3186D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EEA180901B328F1500A3186D /* AppDelegate.m */; }; 12 | EEA180991B328F1600A3186D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EEA180981B328F1500A3186D /* Images.xcassets */; }; 13 | EEA1809C1B328F1600A3186D /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = EEA1809A1B328F1600A3186D /* LaunchScreen.xib */; }; 14 | EEA180A81B328F1600A3186D /* LeftSlideTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EEA180A71B328F1600A3186D /* LeftSlideTests.m */; }; 15 | EEA180B61B32907700A3186D /* LeftSlideViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EEA180B31B32907700A3186D /* LeftSlideViewController.m */; }; 16 | EEA180B71B32907700A3186D /* UIView_extra.m in Sources */ = {isa = PBXBuildFile; fileRef = EEA180B51B32907700A3186D /* UIView_extra.m */; }; 17 | EEA180BA1B3292A900A3186D /* MainPageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EEA180B91B3292A900A3186D /* MainPageViewController.m */; }; 18 | EEA180BD1B3292CB00A3186D /* LeftSortsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EEA180BC1B3292CB00A3186D /* LeftSortsViewController.m */; }; 19 | EEA180C01B32930100A3186D /* otherViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EEA180BF1B32930100A3186D /* otherViewController.m */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | EEA180A21B328F1600A3186D /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = EEA180801B328F1500A3186D /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = EEA180871B328F1500A3186D; 28 | remoteInfo = LeftSlide; 29 | }; 30 | /* End PBXContainerItemProxy section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | EEA180881B328F1500A3186D /* LeftSlide.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LeftSlide.app; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | EEA1808C1B328F1500A3186D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 35 | EEA1808D1B328F1500A3186D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 36 | EEA1808F1B328F1500A3186D /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 37 | EEA180901B328F1500A3186D /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 38 | EEA180981B328F1500A3186D /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 39 | EEA1809B1B328F1600A3186D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 40 | EEA180A11B328F1600A3186D /* LeftSlideTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LeftSlideTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | EEA180A61B328F1600A3186D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 42 | EEA180A71B328F1600A3186D /* LeftSlideTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LeftSlideTests.m; sourceTree = ""; }; 43 | EEA180B21B32907700A3186D /* LeftSlideViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LeftSlideViewController.h; sourceTree = ""; }; 44 | EEA180B31B32907700A3186D /* LeftSlideViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LeftSlideViewController.m; sourceTree = ""; }; 45 | EEA180B41B32907700A3186D /* UIView_extra.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIView_extra.h; sourceTree = ""; }; 46 | EEA180B51B32907700A3186D /* UIView_extra.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIView_extra.m; sourceTree = ""; }; 47 | EEA180B81B3292A900A3186D /* MainPageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainPageViewController.h; sourceTree = ""; }; 48 | EEA180B91B3292A900A3186D /* MainPageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainPageViewController.m; sourceTree = ""; }; 49 | EEA180BB1B3292CB00A3186D /* LeftSortsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LeftSortsViewController.h; sourceTree = ""; }; 50 | EEA180BC1B3292CB00A3186D /* LeftSortsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LeftSortsViewController.m; sourceTree = ""; }; 51 | EEA180BE1B32930100A3186D /* otherViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = otherViewController.h; sourceTree = ""; }; 52 | EEA180BF1B32930100A3186D /* otherViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = otherViewController.m; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | EEA180851B328F1500A3186D /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | EEA1809E1B328F1600A3186D /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | /* End PBXFrameworksBuildPhase section */ 71 | 72 | /* Begin PBXGroup section */ 73 | EEA1807F1B328F1500A3186D = { 74 | isa = PBXGroup; 75 | children = ( 76 | EEA1808A1B328F1500A3186D /* LeftSlide */, 77 | EEA180A41B328F1600A3186D /* LeftSlideTests */, 78 | EEA180891B328F1500A3186D /* Products */, 79 | ); 80 | sourceTree = ""; 81 | }; 82 | EEA180891B328F1500A3186D /* Products */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | EEA180881B328F1500A3186D /* LeftSlide.app */, 86 | EEA180A11B328F1600A3186D /* LeftSlideTests.xctest */, 87 | ); 88 | name = Products; 89 | sourceTree = ""; 90 | }; 91 | EEA1808A1B328F1500A3186D /* LeftSlide */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | EEA180B11B32907700A3186D /* LeftSlideViewController */, 95 | EEA1808F1B328F1500A3186D /* AppDelegate.h */, 96 | EEA180901B328F1500A3186D /* AppDelegate.m */, 97 | EEA180BE1B32930100A3186D /* otherViewController.h */, 98 | EEA180BF1B32930100A3186D /* otherViewController.m */, 99 | EEA180BB1B3292CB00A3186D /* LeftSortsViewController.h */, 100 | EEA180BC1B3292CB00A3186D /* LeftSortsViewController.m */, 101 | EEA180B81B3292A900A3186D /* MainPageViewController.h */, 102 | EEA180B91B3292A900A3186D /* MainPageViewController.m */, 103 | EEA180981B328F1500A3186D /* Images.xcassets */, 104 | EEA1809A1B328F1600A3186D /* LaunchScreen.xib */, 105 | EEA1808B1B328F1500A3186D /* Supporting Files */, 106 | ); 107 | path = LeftSlide; 108 | sourceTree = ""; 109 | }; 110 | EEA1808B1B328F1500A3186D /* Supporting Files */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | EEA1808C1B328F1500A3186D /* Info.plist */, 114 | EEA1808D1B328F1500A3186D /* main.m */, 115 | ); 116 | name = "Supporting Files"; 117 | sourceTree = ""; 118 | }; 119 | EEA180A41B328F1600A3186D /* LeftSlideTests */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | EEA180A71B328F1600A3186D /* LeftSlideTests.m */, 123 | EEA180A51B328F1600A3186D /* Supporting Files */, 124 | ); 125 | path = LeftSlideTests; 126 | sourceTree = ""; 127 | }; 128 | EEA180A51B328F1600A3186D /* Supporting Files */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | EEA180A61B328F1600A3186D /* Info.plist */, 132 | ); 133 | name = "Supporting Files"; 134 | sourceTree = ""; 135 | }; 136 | EEA180B11B32907700A3186D /* LeftSlideViewController */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | EEA180B21B32907700A3186D /* LeftSlideViewController.h */, 140 | EEA180B31B32907700A3186D /* LeftSlideViewController.m */, 141 | EEA180B41B32907700A3186D /* UIView_extra.h */, 142 | EEA180B51B32907700A3186D /* UIView_extra.m */, 143 | ); 144 | path = LeftSlideViewController; 145 | sourceTree = ""; 146 | }; 147 | /* End PBXGroup section */ 148 | 149 | /* Begin PBXNativeTarget section */ 150 | EEA180871B328F1500A3186D /* LeftSlide */ = { 151 | isa = PBXNativeTarget; 152 | buildConfigurationList = EEA180AB1B328F1600A3186D /* Build configuration list for PBXNativeTarget "LeftSlide" */; 153 | buildPhases = ( 154 | EEA180841B328F1500A3186D /* Sources */, 155 | EEA180851B328F1500A3186D /* Frameworks */, 156 | EEA180861B328F1500A3186D /* Resources */, 157 | ); 158 | buildRules = ( 159 | ); 160 | dependencies = ( 161 | ); 162 | name = LeftSlide; 163 | productName = LeftSlide; 164 | productReference = EEA180881B328F1500A3186D /* LeftSlide.app */; 165 | productType = "com.apple.product-type.application"; 166 | }; 167 | EEA180A01B328F1600A3186D /* LeftSlideTests */ = { 168 | isa = PBXNativeTarget; 169 | buildConfigurationList = EEA180AE1B328F1600A3186D /* Build configuration list for PBXNativeTarget "LeftSlideTests" */; 170 | buildPhases = ( 171 | EEA1809D1B328F1600A3186D /* Sources */, 172 | EEA1809E1B328F1600A3186D /* Frameworks */, 173 | EEA1809F1B328F1600A3186D /* Resources */, 174 | ); 175 | buildRules = ( 176 | ); 177 | dependencies = ( 178 | EEA180A31B328F1600A3186D /* PBXTargetDependency */, 179 | ); 180 | name = LeftSlideTests; 181 | productName = LeftSlideTests; 182 | productReference = EEA180A11B328F1600A3186D /* LeftSlideTests.xctest */; 183 | productType = "com.apple.product-type.bundle.unit-test"; 184 | }; 185 | /* End PBXNativeTarget section */ 186 | 187 | /* Begin PBXProject section */ 188 | EEA180801B328F1500A3186D /* Project object */ = { 189 | isa = PBXProject; 190 | attributes = { 191 | LastUpgradeCheck = 0630; 192 | ORGANIZATIONNAME = eamon; 193 | TargetAttributes = { 194 | EEA180871B328F1500A3186D = { 195 | CreatedOnToolsVersion = 6.3; 196 | }; 197 | EEA180A01B328F1600A3186D = { 198 | CreatedOnToolsVersion = 6.3; 199 | TestTargetID = EEA180871B328F1500A3186D; 200 | }; 201 | }; 202 | }; 203 | buildConfigurationList = EEA180831B328F1500A3186D /* Build configuration list for PBXProject "LeftSlide" */; 204 | compatibilityVersion = "Xcode 3.2"; 205 | developmentRegion = English; 206 | hasScannedForEncodings = 0; 207 | knownRegions = ( 208 | en, 209 | Base, 210 | ); 211 | mainGroup = EEA1807F1B328F1500A3186D; 212 | productRefGroup = EEA180891B328F1500A3186D /* Products */; 213 | projectDirPath = ""; 214 | projectRoot = ""; 215 | targets = ( 216 | EEA180871B328F1500A3186D /* LeftSlide */, 217 | EEA180A01B328F1600A3186D /* LeftSlideTests */, 218 | ); 219 | }; 220 | /* End PBXProject section */ 221 | 222 | /* Begin PBXResourcesBuildPhase section */ 223 | EEA180861B328F1500A3186D /* Resources */ = { 224 | isa = PBXResourcesBuildPhase; 225 | buildActionMask = 2147483647; 226 | files = ( 227 | EEA1809C1B328F1600A3186D /* LaunchScreen.xib in Resources */, 228 | EEA180991B328F1600A3186D /* Images.xcassets in Resources */, 229 | ); 230 | runOnlyForDeploymentPostprocessing = 0; 231 | }; 232 | EEA1809F1B328F1600A3186D /* Resources */ = { 233 | isa = PBXResourcesBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | ); 237 | runOnlyForDeploymentPostprocessing = 0; 238 | }; 239 | /* End PBXResourcesBuildPhase section */ 240 | 241 | /* Begin PBXSourcesBuildPhase section */ 242 | EEA180841B328F1500A3186D /* Sources */ = { 243 | isa = PBXSourcesBuildPhase; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | EEA180BA1B3292A900A3186D /* MainPageViewController.m in Sources */, 247 | EEA180BD1B3292CB00A3186D /* LeftSortsViewController.m in Sources */, 248 | EEA180911B328F1500A3186D /* AppDelegate.m in Sources */, 249 | EEA180B71B32907700A3186D /* UIView_extra.m in Sources */, 250 | EEA180C01B32930100A3186D /* otherViewController.m in Sources */, 251 | EEA1808E1B328F1500A3186D /* main.m in Sources */, 252 | EEA180B61B32907700A3186D /* LeftSlideViewController.m in Sources */, 253 | ); 254 | runOnlyForDeploymentPostprocessing = 0; 255 | }; 256 | EEA1809D1B328F1600A3186D /* Sources */ = { 257 | isa = PBXSourcesBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | EEA180A81B328F1600A3186D /* LeftSlideTests.m in Sources */, 261 | ); 262 | runOnlyForDeploymentPostprocessing = 0; 263 | }; 264 | /* End PBXSourcesBuildPhase section */ 265 | 266 | /* Begin PBXTargetDependency section */ 267 | EEA180A31B328F1600A3186D /* PBXTargetDependency */ = { 268 | isa = PBXTargetDependency; 269 | target = EEA180871B328F1500A3186D /* LeftSlide */; 270 | targetProxy = EEA180A21B328F1600A3186D /* PBXContainerItemProxy */; 271 | }; 272 | /* End PBXTargetDependency section */ 273 | 274 | /* Begin PBXVariantGroup section */ 275 | EEA1809A1B328F1600A3186D /* LaunchScreen.xib */ = { 276 | isa = PBXVariantGroup; 277 | children = ( 278 | EEA1809B1B328F1600A3186D /* Base */, 279 | ); 280 | name = LaunchScreen.xib; 281 | sourceTree = ""; 282 | }; 283 | /* End PBXVariantGroup section */ 284 | 285 | /* Begin XCBuildConfiguration section */ 286 | EEA180A91B328F1600A3186D /* Debug */ = { 287 | isa = XCBuildConfiguration; 288 | buildSettings = { 289 | ALWAYS_SEARCH_USER_PATHS = NO; 290 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 291 | CLANG_CXX_LIBRARY = "libc++"; 292 | CLANG_ENABLE_MODULES = YES; 293 | CLANG_ENABLE_OBJC_ARC = YES; 294 | CLANG_WARN_BOOL_CONVERSION = YES; 295 | CLANG_WARN_CONSTANT_CONVERSION = YES; 296 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 297 | CLANG_WARN_EMPTY_BODY = YES; 298 | CLANG_WARN_ENUM_CONVERSION = YES; 299 | CLANG_WARN_INT_CONVERSION = YES; 300 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 301 | CLANG_WARN_UNREACHABLE_CODE = YES; 302 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 303 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 304 | COPY_PHASE_STRIP = NO; 305 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 306 | ENABLE_STRICT_OBJC_MSGSEND = YES; 307 | GCC_C_LANGUAGE_STANDARD = gnu99; 308 | GCC_DYNAMIC_NO_PIC = NO; 309 | GCC_NO_COMMON_BLOCKS = YES; 310 | GCC_OPTIMIZATION_LEVEL = 0; 311 | GCC_PREPROCESSOR_DEFINITIONS = ( 312 | "DEBUG=1", 313 | "$(inherited)", 314 | ); 315 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 316 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 317 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 318 | GCC_WARN_UNDECLARED_SELECTOR = YES; 319 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 320 | GCC_WARN_UNUSED_FUNCTION = YES; 321 | GCC_WARN_UNUSED_VARIABLE = YES; 322 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 323 | MTL_ENABLE_DEBUG_INFO = YES; 324 | ONLY_ACTIVE_ARCH = YES; 325 | SDKROOT = iphoneos; 326 | }; 327 | name = Debug; 328 | }; 329 | EEA180AA1B328F1600A3186D /* Release */ = { 330 | isa = XCBuildConfiguration; 331 | buildSettings = { 332 | ALWAYS_SEARCH_USER_PATHS = NO; 333 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 334 | CLANG_CXX_LIBRARY = "libc++"; 335 | CLANG_ENABLE_MODULES = YES; 336 | CLANG_ENABLE_OBJC_ARC = YES; 337 | CLANG_WARN_BOOL_CONVERSION = YES; 338 | CLANG_WARN_CONSTANT_CONVERSION = YES; 339 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 340 | CLANG_WARN_EMPTY_BODY = YES; 341 | CLANG_WARN_ENUM_CONVERSION = YES; 342 | CLANG_WARN_INT_CONVERSION = YES; 343 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 344 | CLANG_WARN_UNREACHABLE_CODE = YES; 345 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 346 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 347 | COPY_PHASE_STRIP = NO; 348 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 349 | ENABLE_NS_ASSERTIONS = NO; 350 | ENABLE_STRICT_OBJC_MSGSEND = YES; 351 | GCC_C_LANGUAGE_STANDARD = gnu99; 352 | GCC_NO_COMMON_BLOCKS = YES; 353 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 354 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 355 | GCC_WARN_UNDECLARED_SELECTOR = YES; 356 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 357 | GCC_WARN_UNUSED_FUNCTION = YES; 358 | GCC_WARN_UNUSED_VARIABLE = YES; 359 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 360 | MTL_ENABLE_DEBUG_INFO = NO; 361 | SDKROOT = iphoneos; 362 | VALIDATE_PRODUCT = YES; 363 | }; 364 | name = Release; 365 | }; 366 | EEA180AC1B328F1600A3186D /* Debug */ = { 367 | isa = XCBuildConfiguration; 368 | buildSettings = { 369 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 370 | INFOPLIST_FILE = LeftSlide/Info.plist; 371 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 372 | PRODUCT_NAME = "$(TARGET_NAME)"; 373 | }; 374 | name = Debug; 375 | }; 376 | EEA180AD1B328F1600A3186D /* Release */ = { 377 | isa = XCBuildConfiguration; 378 | buildSettings = { 379 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 380 | INFOPLIST_FILE = LeftSlide/Info.plist; 381 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 382 | PRODUCT_NAME = "$(TARGET_NAME)"; 383 | }; 384 | name = Release; 385 | }; 386 | EEA180AF1B328F1600A3186D /* Debug */ = { 387 | isa = XCBuildConfiguration; 388 | buildSettings = { 389 | BUNDLE_LOADER = "$(TEST_HOST)"; 390 | FRAMEWORK_SEARCH_PATHS = ( 391 | "$(SDKROOT)/Developer/Library/Frameworks", 392 | "$(inherited)", 393 | ); 394 | GCC_PREPROCESSOR_DEFINITIONS = ( 395 | "DEBUG=1", 396 | "$(inherited)", 397 | ); 398 | INFOPLIST_FILE = LeftSlideTests/Info.plist; 399 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 400 | PRODUCT_NAME = "$(TARGET_NAME)"; 401 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LeftSlide.app/LeftSlide"; 402 | }; 403 | name = Debug; 404 | }; 405 | EEA180B01B328F1600A3186D /* Release */ = { 406 | isa = XCBuildConfiguration; 407 | buildSettings = { 408 | BUNDLE_LOADER = "$(TEST_HOST)"; 409 | FRAMEWORK_SEARCH_PATHS = ( 410 | "$(SDKROOT)/Developer/Library/Frameworks", 411 | "$(inherited)", 412 | ); 413 | INFOPLIST_FILE = LeftSlideTests/Info.plist; 414 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 415 | PRODUCT_NAME = "$(TARGET_NAME)"; 416 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LeftSlide.app/LeftSlide"; 417 | }; 418 | name = Release; 419 | }; 420 | /* End XCBuildConfiguration section */ 421 | 422 | /* Begin XCConfigurationList section */ 423 | EEA180831B328F1500A3186D /* Build configuration list for PBXProject "LeftSlide" */ = { 424 | isa = XCConfigurationList; 425 | buildConfigurations = ( 426 | EEA180A91B328F1600A3186D /* Debug */, 427 | EEA180AA1B328F1600A3186D /* Release */, 428 | ); 429 | defaultConfigurationIsVisible = 0; 430 | defaultConfigurationName = Release; 431 | }; 432 | EEA180AB1B328F1600A3186D /* Build configuration list for PBXNativeTarget "LeftSlide" */ = { 433 | isa = XCConfigurationList; 434 | buildConfigurations = ( 435 | EEA180AC1B328F1600A3186D /* Debug */, 436 | EEA180AD1B328F1600A3186D /* Release */, 437 | ); 438 | defaultConfigurationIsVisible = 0; 439 | }; 440 | EEA180AE1B328F1600A3186D /* Build configuration list for PBXNativeTarget "LeftSlideTests" */ = { 441 | isa = XCConfigurationList; 442 | buildConfigurations = ( 443 | EEA180AF1B328F1600A3186D /* Debug */, 444 | EEA180B01B328F1600A3186D /* Release */, 445 | ); 446 | defaultConfigurationIsVisible = 0; 447 | }; 448 | /* End XCConfigurationList section */ 449 | }; 450 | rootObject = EEA180801B328F1500A3186D /* Project object */; 451 | } 452 | -------------------------------------------------------------------------------- /LeftSlide.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LeftSlide.xcodeproj/project.xcworkspace/xcuserdata/huangzhenyu.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chennyhuang/LeftSlide/8c7aa31f77a7078579fe70cf902e9fe4ffccde16/LeftSlide.xcodeproj/project.xcworkspace/xcuserdata/huangzhenyu.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /LeftSlide.xcodeproj/xcuserdata/huangzhenyu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /LeftSlide.xcodeproj/xcuserdata/huangzhenyu.xcuserdatad/xcschemes/LeftSlide.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /LeftSlide.xcodeproj/xcuserdata/huangzhenyu.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LeftSlide.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | EEA180871B328F1500A3186D 16 | 17 | primary 18 | 19 | 20 | EEA180A01B328F1600A3186D 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /LeftSlide/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // LeftSlide 4 | // 5 | // Created by huangzhenyu on 15/6/18. 6 | // Copyright (c) 2015年 eamon. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "LeftSlideViewController.h" 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | 16 | @property (strong, nonatomic) LeftSlideViewController *LeftSlideVC; 17 | @property (strong, nonatomic) UINavigationController *mainNavigationController; 18 | 19 | @end 20 | 21 | -------------------------------------------------------------------------------- /LeftSlide/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // LeftSlide 4 | // 5 | // Created by huangzhenyu on 15/6/18. 6 | // Copyright (c) 2015年 eamon. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "MainPageViewController.h" 11 | #import "LeftSortsViewController.h" 12 | 13 | @interface AppDelegate () 14 | 15 | @end 16 | 17 | @implementation AppDelegate 18 | 19 | 20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 21 | 22 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 23 | self.window.backgroundColor = [UIColor whiteColor]; //设置通用背景颜色 24 | [self.window makeKeyAndVisible]; 25 | 26 | MainPageViewController *mainVC = [[MainPageViewController alloc] init]; 27 | self.mainNavigationController = [[UINavigationController alloc] initWithRootViewController:mainVC]; 28 | LeftSortsViewController *leftVC = [[LeftSortsViewController alloc] init]; 29 | self.LeftSlideVC = [[LeftSlideViewController alloc] initWithLeftView:leftVC andMainView:self.mainNavigationController]; 30 | self.window.rootViewController = self.LeftSlideVC; 31 | 32 | [[UINavigationBar appearance] setBarTintColor:[UIColor purpleColor]]; 33 | return YES; 34 | } 35 | 36 | - (void)applicationWillResignActive:(UIApplication *)application { 37 | // 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. 38 | // 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. 39 | } 40 | 41 | - (void)applicationDidEnterBackground:(UIApplication *)application { 42 | // 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. 43 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 44 | } 45 | 46 | - (void)applicationWillEnterForeground:(UIApplication *)application { 47 | // 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. 48 | } 49 | 50 | - (void)applicationDidBecomeActive:(UIApplication *)application { 51 | // 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. 52 | } 53 | 54 | - (void)applicationWillTerminate:(UIApplication *)application { 55 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /LeftSlide/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /LeftSlide/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" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /LeftSlide/Images.xcassets/leftbackiamge.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "leftbackiamge.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LeftSlide/Images.xcassets/leftbackiamge.imageset/leftbackiamge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chennyhuang/LeftSlide/8c7aa31f77a7078579fe70cf902e9fe4ffccde16/LeftSlide/Images.xcassets/leftbackiamge.imageset/leftbackiamge.png -------------------------------------------------------------------------------- /LeftSlide/Images.xcassets/menu.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "menu@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LeftSlide/Images.xcassets/menu.imageset/menu@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chennyhuang/LeftSlide/8c7aa31f77a7078579fe70cf902e9fe4ffccde16/LeftSlide/Images.xcassets/menu.imageset/menu@2x.png -------------------------------------------------------------------------------- /LeftSlide/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.eamon.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /LeftSlide/LeftSlideViewController/LeftSlideViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LeftSlideViewController.h 3 | // LeftSlideViewController 4 | // 5 | // Created by huangzhenyu on 15/06/18. 6 | // Copyright (c) 2015年 huangzhenyu. All rights reserved. 7 | 8 | #define kScreenSize [[UIScreen mainScreen] bounds].size 9 | #define kScreenWidth [[UIScreen mainScreen] bounds].size.width 10 | #define kScreenHeight [[UIScreen mainScreen] bounds].size.height 11 | 12 | #define kMainPageDistance 100 //打开左侧窗时,中视图(右视图)露出的宽度 13 | #define kMainPageScale 0.8 //打开左侧窗时,中视图(右视图)缩放比例 14 | #define kMainPageCenter CGPointMake(kScreenWidth + kScreenWidth * kMainPageScale / 2.0 - kMainPageDistance, kScreenHeight / 2) //打开左侧窗时,中视图中心点 15 | 16 | #define vCouldChangeDeckStateDistance (kScreenWidth - kMainPageDistance) / 2.0 - 40 //滑动距离大于此数时,状态改变(关--》开,或者开--》关) 17 | #define vSpeedFloat 0.7 //滑动速度 18 | 19 | #define kLeftAlpha 0.9 //左侧蒙版的最大值 20 | #define kLeftCenterX 30 //左侧初始偏移量 21 | #define kLeftScale 0.7 //左侧初始缩放比例 22 | 23 | #define vDeckCanNotPanViewTag 987654 // 不响应此侧滑的View的tag 24 | 25 | #import 26 | #import "UIView_extra.h" 27 | 28 | @interface LeftSlideViewController : UIViewController 29 | 30 | //滑动速度系数-建议在0.5-1之间。默认为0.5 31 | @property (nonatomic, assign) CGFloat speedf; 32 | 33 | //左侧窗控制器 34 | @property (nonatomic, strong) UIViewController *leftVC; 35 | 36 | @property (nonatomic,strong) UIViewController *mainVC; 37 | //点击手势控制器,是否允许点击视图恢复视图位置。默认为yes 38 | @property (nonatomic, strong) UITapGestureRecognizer *sideslipTapGes; 39 | 40 | //滑动手势控制器 41 | @property (nonatomic, strong) UIPanGestureRecognizer *pan; 42 | 43 | //侧滑窗是否关闭(关闭时显示为主页) 44 | @property (nonatomic, assign) BOOL closed; 45 | 46 | 47 | /** 48 | @brief 初始化侧滑控制器 49 | @param leftVC 右视图控制器 50 | mainVC 中间视图控制器 51 | @result instancetype 初始化生成的对象 52 | */ 53 | - (instancetype)initWithLeftView:(UIViewController *)leftVC 54 | andMainView:(UIViewController *)mainVC; 55 | 56 | /** 57 | @brief 关闭左视图 58 | */ 59 | - (void)closeLeftView; 60 | 61 | 62 | /** 63 | @brief 打开左视图 64 | */ 65 | - (void)openLeftView; 66 | 67 | /** 68 | * 设置滑动开关是否开启 69 | * 70 | * @param enabled YES:支持滑动手势,NO:不支持滑动手势 71 | */ 72 | - (void)setPanEnabled: (BOOL) enabled; 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /LeftSlide/LeftSlideViewController/LeftSlideViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // LeftSlideViewController.m 3 | // LeftSlideViewController 4 | // 5 | // Created by huangzhenyu on 15/06/18. 6 | // Copyright (c) 2015年 huangzhenyu. All rights reserved. 7 | 8 | #import "LeftSlideViewController.h" 9 | 10 | 11 | @interface LeftSlideViewController () 12 | { 13 | CGFloat _scalef; //实时横向位移 14 | } 15 | 16 | @property (nonatomic,strong) UITableView *leftTableview; 17 | @property (nonatomic,assign) CGFloat leftTableviewW; 18 | @property (nonatomic,strong) UIView *contentView; 19 | @end 20 | 21 | 22 | @implementation LeftSlideViewController 23 | 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | // Do any additional setup after loading the view. 27 | } 28 | 29 | /** 30 | @brief 初始化侧滑控制器 31 | @param leftVC 左视图控制器 32 | mainVC 中间视图控制器 33 | @result instancetype 初始化生成的对象 34 | */ 35 | - (instancetype)initWithLeftView:(UIViewController *)leftVC 36 | andMainView:(UIViewController *)mainVC 37 | { 38 | if(self = [super init]){ 39 | self.speedf = vSpeedFloat; 40 | self.leftVC = leftVC; 41 | self.mainVC = mainVC; 42 | [self addChildViewController:self.leftVC]; 43 | [self addChildViewController:self.mainVC]; 44 | //滑动手势 45 | self.pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)]; 46 | [self.mainVC.view addGestureRecognizer:self.pan]; 47 | 48 | [self.pan setCancelsTouchesInView:YES]; 49 | self.pan.delegate = self; 50 | 51 | self.leftVC.view.hidden = YES; 52 | 53 | [self.view addSubview:self.leftVC.view]; 54 | 55 | //蒙版 56 | UIView *view = [[UIView alloc] init]; 57 | view.frame = self.leftVC.view.bounds; 58 | view.backgroundColor = [UIColor blackColor]; 59 | view.alpha = 0.5; 60 | self.contentView = view; 61 | [self.leftVC.view addSubview:view]; 62 | 63 | //获取左侧tableview 64 | for (UIView *obj in self.leftVC.view.subviews) { 65 | if ([obj isKindOfClass:[UITableView class]]) { 66 | self.leftTableview = (UITableView *)obj; 67 | } 68 | } 69 | self.leftTableview.backgroundColor = [UIColor clearColor]; 70 | self.leftTableview.frame = CGRectMake(0, 0, kScreenWidth - kMainPageDistance, kScreenHeight); 71 | //设置左侧tableview的初始位置和缩放系数 72 | self.leftTableview.transform = CGAffineTransformMakeScale(kLeftScale, kLeftScale); 73 | self.leftTableview.center = CGPointMake(kLeftCenterX, kScreenHeight * 0.5); 74 | 75 | [self.view addSubview:self.mainVC.view]; 76 | self.closed = YES;//初始时侧滑窗关闭 77 | 78 | } 79 | return self; 80 | } 81 | 82 | - (void) viewWillAppear:(BOOL)animated 83 | { 84 | [super viewWillAppear:animated]; 85 | self.leftVC.view.hidden = NO; 86 | } 87 | 88 | #pragma mark - 滑动手势 89 | 90 | //滑动手势 91 | - (void) handlePan: (UIPanGestureRecognizer *)rec{ 92 | 93 | CGPoint point = [rec translationInView:self.view]; 94 | _scalef = (point.x * self.speedf + _scalef); 95 | 96 | BOOL needMoveWithTap = YES; //是否还需要跟随手指移动 97 | if (((self.mainVC.view.x <= 0) && (_scalef <= 0)) || ((self.mainVC.view.x >= (kScreenWidth - kMainPageDistance )) && (_scalef >= 0))) 98 | { 99 | //边界值管控 100 | _scalef = 0; 101 | needMoveWithTap = NO; 102 | } 103 | 104 | //根据视图位置判断是左滑还是右边滑动 105 | if (needMoveWithTap && (rec.view.frame.origin.x >= 0) && (rec.view.frame.origin.x <= (kScreenWidth - kMainPageDistance))) 106 | { 107 | CGFloat recCenterX = rec.view.center.x + point.x * self.speedf; 108 | if (recCenterX < kScreenWidth * 0.5 - 2) { 109 | recCenterX = kScreenWidth * 0.5; 110 | } 111 | 112 | CGFloat recCenterY = rec.view.center.y; 113 | 114 | rec.view.center = CGPointMake(recCenterX,recCenterY); 115 | 116 | //scale 1.0~kMainPageScale 117 | CGFloat scale = 1 - (1 - kMainPageScale) * (rec.view.frame.origin.x / (kScreenWidth - kMainPageDistance)); 118 | 119 | rec.view.transform = CGAffineTransformScale(CGAffineTransformIdentity,scale, scale); 120 | [rec setTranslation:CGPointMake(0, 0) inView:self.view]; 121 | 122 | CGFloat leftTabCenterX = kLeftCenterX + ((kScreenWidth - kMainPageDistance) * 0.5 - kLeftCenterX) * (rec.view.frame.origin.x / (kScreenWidth - kMainPageDistance)); 123 | 124 | NSLog(@"%f",leftTabCenterX); 125 | 126 | 127 | //leftScale kLeftScale~1.0 128 | CGFloat leftScale = kLeftScale + (1 - kLeftScale) * (rec.view.frame.origin.x / (kScreenWidth - kMainPageDistance)); 129 | 130 | self.leftTableview.center = CGPointMake(leftTabCenterX, kScreenHeight * 0.5); 131 | self.leftTableview.transform = CGAffineTransformScale(CGAffineTransformIdentity, leftScale,leftScale); 132 | 133 | //tempAlpha kLeftAlpha~0 134 | CGFloat tempAlpha = kLeftAlpha - kLeftAlpha * (rec.view.frame.origin.x / (kScreenWidth - kMainPageDistance)); 135 | self.contentView.alpha = tempAlpha; 136 | 137 | } 138 | else 139 | { 140 | //超出范围, 141 | if (self.mainVC.view.x < 0) 142 | { 143 | [self closeLeftView]; 144 | _scalef = 0; 145 | } 146 | else if (self.mainVC.view.x > (kScreenWidth - kMainPageDistance)) 147 | { 148 | [self openLeftView]; 149 | _scalef = 0; 150 | } 151 | } 152 | 153 | //手势结束后修正位置,超过约一半时向多出的一半偏移 154 | if (rec.state == UIGestureRecognizerStateEnded) { 155 | if (fabs(_scalef) > vCouldChangeDeckStateDistance) 156 | { 157 | if (self.closed) 158 | { 159 | [self openLeftView]; 160 | } 161 | else 162 | { 163 | [self closeLeftView]; 164 | } 165 | } 166 | else 167 | { 168 | if (self.closed) 169 | { 170 | [self closeLeftView]; 171 | } 172 | else 173 | { 174 | [self openLeftView]; 175 | } 176 | } 177 | _scalef = 0; 178 | } 179 | } 180 | 181 | 182 | #pragma mark - 单击手势 183 | -(void)handeTap:(UITapGestureRecognizer *)tap{ 184 | 185 | if ((!self.closed) && (tap.state == UIGestureRecognizerStateEnded)) 186 | { 187 | [UIView beginAnimations:nil context:nil]; 188 | tap.view.transform = CGAffineTransformScale(CGAffineTransformIdentity,1.0,1.0); 189 | tap.view.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2,[UIScreen mainScreen].bounds.size.height/2); 190 | self.closed = YES; 191 | 192 | self.leftTableview.center = CGPointMake(kLeftCenterX, kScreenHeight * 0.5); 193 | self.leftTableview.transform = CGAffineTransformScale(CGAffineTransformIdentity,kLeftScale,kLeftScale); 194 | self.contentView.alpha = kLeftAlpha; 195 | 196 | [UIView commitAnimations]; 197 | _scalef = 0; 198 | [self removeSingleTap]; 199 | } 200 | 201 | } 202 | 203 | #pragma mark - 修改视图位置 204 | /** 205 | @brief 关闭左视图 206 | */ 207 | - (void)closeLeftView 208 | { 209 | [UIView beginAnimations:nil context:nil]; 210 | self.mainVC.view.transform = CGAffineTransformScale(CGAffineTransformIdentity,1.0,1.0); 211 | self.mainVC.view.center = CGPointMake(kScreenWidth / 2, kScreenHeight / 2); 212 | self.closed = YES; 213 | 214 | self.leftTableview.center = CGPointMake(kLeftCenterX, kScreenHeight * 0.5); 215 | self.leftTableview.transform = CGAffineTransformScale(CGAffineTransformIdentity,kLeftScale,kLeftScale); 216 | self.contentView.alpha = kLeftAlpha; 217 | 218 | [UIView commitAnimations]; 219 | [self removeSingleTap]; 220 | } 221 | 222 | /** 223 | @brief 打开左视图 224 | */ 225 | - (void)openLeftView; 226 | { 227 | [UIView beginAnimations:nil context:nil]; 228 | self.mainVC.view.transform = CGAffineTransformScale(CGAffineTransformIdentity,kMainPageScale,kMainPageScale); 229 | self.mainVC.view.center = kMainPageCenter; 230 | self.closed = NO; 231 | 232 | self.leftTableview.center = CGPointMake((kScreenWidth - kMainPageDistance) * 0.5, kScreenHeight * 0.5); 233 | self.leftTableview.transform = CGAffineTransformScale(CGAffineTransformIdentity,1.0,1.0); 234 | self.contentView.alpha = 0; 235 | 236 | [UIView commitAnimations]; 237 | [self disableTapButton]; 238 | } 239 | 240 | #pragma mark - 行为收敛控制 241 | - (void)disableTapButton 242 | { 243 | for (UIButton *tempButton in [_mainVC.view subviews]) 244 | { 245 | [tempButton setUserInteractionEnabled:NO]; 246 | } 247 | //单击 248 | if (!self.sideslipTapGes) 249 | { 250 | //单击手势 251 | self.sideslipTapGes= [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handeTap:)]; 252 | [self.sideslipTapGes setNumberOfTapsRequired:1]; 253 | 254 | [self.mainVC.view addGestureRecognizer:self.sideslipTapGes]; 255 | self.sideslipTapGes.cancelsTouchesInView = YES; //点击事件盖住其它响应事件,但盖不住Button; 256 | } 257 | } 258 | 259 | //关闭行为收敛 260 | - (void) removeSingleTap 261 | { 262 | for (UIButton *tempButton in [self.mainVC.view subviews]) 263 | { 264 | [tempButton setUserInteractionEnabled:YES]; 265 | } 266 | [self.mainVC.view removeGestureRecognizer:self.sideslipTapGes]; 267 | self.sideslipTapGes = nil; 268 | } 269 | 270 | /** 271 | * 设置滑动开关是否开启 272 | * 273 | * @param enabled YES:支持滑动手势,NO:不支持滑动手势 274 | */ 275 | 276 | - (void)setPanEnabled: (BOOL) enabled 277 | { 278 | [self.pan setEnabled:enabled]; 279 | } 280 | 281 | -(BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldReceiveTouch:(UITouch*)touch { 282 | 283 | if(touch.view.tag == vDeckCanNotPanViewTag) 284 | { 285 | // NSLog(@"不响应侧滑"); 286 | return NO; 287 | } 288 | else 289 | { 290 | // NSLog(@"响应侧滑"); 291 | return YES; 292 | } 293 | } 294 | 295 | @end 296 | -------------------------------------------------------------------------------- /LeftSlide/LeftSlideViewController/UIView_extra.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView_extra.h 3 | // Woyoli 4 | // 5 | // Created by jamie on 14-11-25. 6 | // Copyright (c) 2014年 Missionsky. All rights reserved. 7 | // 8 | 9 | #define vAlertTag 10086 10 | 11 | #import 12 | 13 | @interface UIView (UIView) 14 | 15 | @property (nonatomic, assign) CGFloat x; 16 | @property (nonatomic, assign) CGFloat y; 17 | @property (nonatomic, assign) CGFloat width; 18 | @property (nonatomic, assign) CGFloat height; 19 | @property (nonatomic, assign) CGPoint origin; 20 | @property (nonatomic, assign) CGSize size; 21 | @property (nonatomic, assign) CGFloat bottom; 22 | @property (nonatomic, assign) CGFloat right; 23 | @property (nonatomic, assign) CGFloat centerX; 24 | @property (nonatomic, assign) CGFloat centerY; 25 | @property (nonatomic, strong, readonly) UIView *lastSubviewOnX; 26 | @property (nonatomic, strong, readonly) UIView *lastSubviewOnY; 27 | 28 | /** 29 | * @brief 移除此view上的所有子视图 30 | */ 31 | - (void)removeAllSubviews; 32 | 33 | /** 34 | @brief 弹窗 35 | @param title 弹窗标题 36 | message 弹窗信息 37 | */ 38 | + (void) showAlertView: (NSString*) title andMessage: (NSString *) message; 39 | 40 | /** 41 | * 弹窗 42 | * 43 | * @param title 弹窗标题 44 | * @param message 弹窗信息 45 | * @param delegate 弹窗代理 46 | */ 47 | + (void) showAlertView: (NSString*) title 48 | andMessage: (NSString *) message 49 | withDelegate: (UIViewController *) delegate; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /LeftSlide/LeftSlideViewController/UIView_extra.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView_extra.m 3 | // Woyoli 4 | // 5 | // Created by jamie on 14-11-25. 6 | // Copyright (c) 2014年 Missionsky. All rights reserved. 7 | // 8 | 9 | #import "UIView_extra.h" 10 | 11 | @implementation UIView (UIView) 12 | 13 | @dynamic x; 14 | @dynamic y; 15 | @dynamic width; 16 | @dynamic height; 17 | @dynamic origin; 18 | @dynamic size; 19 | 20 | #pragma mark ---------------- Setters----------------- 21 | -(void)setX:(CGFloat)x{ 22 | CGRect r = self.frame; 23 | r.origin.x = x; 24 | self.frame = r; 25 | } 26 | 27 | -(void)setY:(CGFloat)y{ 28 | CGRect r = self.frame; 29 | r.origin.y = y; 30 | self.frame = r; 31 | } 32 | 33 | -(void)setWidth:(CGFloat)width{ 34 | CGRect r = self.frame; 35 | r.size.width = width; 36 | self.frame = r; 37 | } 38 | 39 | -(void)setHeight:(CGFloat)height{ 40 | CGRect r = self.frame; 41 | r.size.height = height; 42 | self.frame = r; 43 | } 44 | 45 | -(void)setOrigin:(CGPoint)origin{ 46 | self.x = origin.x; 47 | self.y = origin.y; 48 | } 49 | 50 | -(void)setSize:(CGSize)size{ 51 | self.width = size.width; 52 | self.height = size.height; 53 | } 54 | 55 | -(void)setRight:(CGFloat)right { 56 | CGRect frame = self.frame; 57 | frame.origin.x = right - frame.size.width; 58 | self.frame = frame; 59 | } 60 | 61 | -(void)setBottom:(CGFloat)bottom { 62 | CGRect frame = self.frame; 63 | frame.origin.y = bottom - frame.size.height; 64 | self.frame = frame; 65 | } 66 | 67 | -(void)setCenterX:(CGFloat)centerX { 68 | self.center = CGPointMake(centerX, self.center.y); 69 | } 70 | 71 | -(void)setCenterY:(CGFloat)centerY { 72 | self.center = CGPointMake(self.center.x, centerY); 73 | } 74 | 75 | #pragma mark ---------------- Getters----------------- 76 | -(CGFloat)x{ 77 | return self.frame.origin.x; 78 | } 79 | 80 | -(CGFloat)y{ 81 | return self.frame.origin.y; 82 | } 83 | 84 | -(CGFloat)width{ 85 | return self.frame.size.width; 86 | } 87 | 88 | -(CGFloat)height{ 89 | return self.frame.size.height; 90 | } 91 | 92 | -(CGPoint)origin{ 93 | return CGPointMake(self.x, self.y); 94 | } 95 | 96 | -(CGSize)size{ 97 | return CGSizeMake(self.width, self.height); 98 | } 99 | 100 | -(CGFloat)right { 101 | return self.frame.origin.x + self.frame.size.width; 102 | } 103 | 104 | -(CGFloat)bottom { 105 | return self.frame.origin.y + self.frame.size.height; 106 | } 107 | 108 | -(CGFloat)centerX { 109 | return self.center.x; 110 | } 111 | 112 | -(CGFloat)centerY { 113 | return self.center.y; 114 | } 115 | 116 | -(UIView *)lastSubviewOnX{ 117 | if(self.subviews.count > 0){ 118 | UIView *outView = self.subviews[0]; 119 | 120 | for(UIView *v in self.subviews) 121 | if(v.x > outView.x) 122 | outView = v; 123 | 124 | return outView; 125 | } 126 | 127 | return nil; 128 | } 129 | 130 | -(UIView *)lastSubviewOnY{ 131 | if(self.subviews.count > 0){ 132 | UIView *outView = self.subviews[0]; 133 | 134 | for(UIView *v in self.subviews) 135 | if(v.y > outView.y) 136 | outView = v; 137 | 138 | return outView; 139 | } 140 | 141 | return nil; 142 | } 143 | 144 | #pragma mark ---------------- other----------------- 145 | /** 146 | * @brief 移除此view上的所有子视图 147 | */ 148 | - (void)removeAllSubviews { 149 | for (UIView *view in self.subviews) { 150 | [view removeFromSuperview]; 151 | } 152 | return; 153 | } 154 | 155 | /** 156 | @brief 弹窗 157 | @param title 弹窗标题 158 | message 弹窗信息 159 | */ 160 | + (void) showAlertView: (NSString*) title andMessage: (NSString *) message 161 | { 162 | dispatch_async(dispatch_get_main_queue() , ^{ 163 | UIAlertView *alert = [[UIAlertView alloc] init]; 164 | alert.title = title; 165 | alert.message = message; 166 | [alert addButtonWithTitle:@"确定"]; 167 | [alert show]; 168 | alert = nil; 169 | }); 170 | } 171 | 172 | /** 173 | * 弹窗 174 | * 175 | * @param title 弹窗标题 176 | * @param message 弹窗信息 177 | * @param delegate 弹窗代理 178 | */ 179 | + (void) showAlertView: (NSString*) title 180 | andMessage: (NSString *) message 181 | withDelegate: (UIViewController *) delegate 182 | { 183 | dispatch_async(dispatch_get_main_queue() , ^{ 184 | UIAlertView *alert = [[UIAlertView alloc] init]; 185 | alert.title = title; 186 | alert.message = message; 187 | alert.delegate = delegate; 188 | alert.tag = vAlertTag; 189 | [alert addButtonWithTitle:@"确定"]; 190 | [alert show]; 191 | alert = nil; 192 | }); 193 | } 194 | 195 | 196 | @end 197 | -------------------------------------------------------------------------------- /LeftSlide/LeftSortsViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LeftSortsViewController.h 3 | // LGDeckViewController 4 | // 5 | // Created by jamie on 15/3/31. 6 | // Copyright (c) 2015年 Jamie-Ling. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LeftSortsViewController : UIViewController 12 | @property (nonatomic,strong) UITableView *tableview; 13 | @end 14 | -------------------------------------------------------------------------------- /LeftSlide/LeftSortsViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // LeftSortsViewController.m 3 | // LGDeckViewController 4 | // 5 | // Created by jamie on 15/3/31. 6 | // Copyright (c) 2015年 Jamie-Ling. All rights reserved. 7 | // 8 | 9 | #import "LeftSortsViewController.h" 10 | #import "AppDelegate.h" 11 | #import "otherViewController.h" 12 | 13 | @interface LeftSortsViewController () 14 | 15 | @end 16 | 17 | @implementation LeftSortsViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | // Do any additional setup after loading the view. 22 | 23 | UIImageView *imageview = [[UIImageView alloc] initWithFrame:self.view.bounds]; 24 | imageview.image = [UIImage imageNamed:@"leftbackiamge"]; 25 | [self.view addSubview:imageview]; 26 | 27 | UITableView *tableview = [[UITableView alloc] init]; 28 | self.tableview = tableview; 29 | tableview.frame = self.view.bounds; 30 | tableview.dataSource = self; 31 | tableview.delegate = self; 32 | tableview.separatorStyle = UITableViewCellSeparatorStyleNone; 33 | [self.view addSubview:tableview]; 34 | } 35 | 36 | - (void)didReceiveMemoryWarning { 37 | [super didReceiveMemoryWarning]; 38 | // Dispose of any resources that can be recreated. 39 | } 40 | 41 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 42 | { 43 | return 7; 44 | } 45 | 46 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 47 | { 48 | static NSString *Identifier = @"Identifier"; 49 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier]; 50 | if (cell == nil) { 51 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Identifier]; 52 | } 53 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 54 | cell.textLabel.font = [UIFont systemFontOfSize:20.0f]; 55 | cell.backgroundColor = [UIColor clearColor]; 56 | cell.textLabel.textColor = [UIColor whiteColor]; 57 | 58 | if (indexPath.row == 0) { 59 | cell.textLabel.text = @"开通会员"; 60 | } else if (indexPath.row == 1) { 61 | cell.textLabel.text = @"QQ钱包"; 62 | } else if (indexPath.row == 2) { 63 | cell.textLabel.text = @"网上营业厅"; 64 | } else if (indexPath.row == 3) { 65 | cell.textLabel.text = @"个性装扮"; 66 | } else if (indexPath.row == 4) { 67 | cell.textLabel.text = @"我的收藏"; 68 | } else if (indexPath.row == 5) { 69 | cell.textLabel.text = @"我的相册"; 70 | } else if (indexPath.row == 6) { 71 | cell.textLabel.text = @"我的文件"; 72 | } 73 | return cell; 74 | } 75 | 76 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 77 | { 78 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 79 | AppDelegate *tempAppDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 80 | otherViewController *vc = [[otherViewController alloc] init]; 81 | [tempAppDelegate.LeftSlideVC closeLeftView];//关闭左侧抽屉 82 | 83 | [tempAppDelegate.mainNavigationController pushViewController:vc animated:NO]; 84 | } 85 | 86 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 87 | { 88 | return 180; 89 | } 90 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 91 | { 92 | UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableview.bounds.size.width, 180)]; 93 | view.backgroundColor = [UIColor clearColor]; 94 | return view; 95 | } 96 | @end 97 | -------------------------------------------------------------------------------- /LeftSlide/MainPageViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MainPageViewController.h 3 | // LeftSlide 4 | // 5 | // Created by huangzhenyu on 15/6/18. 6 | // Copyright (c) 2015年 eamon. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MainPageViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /LeftSlide/MainPageViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MainPageViewController.m 3 | // LeftSlide 4 | // 5 | // Created by huangzhenyu on 15/6/18. 6 | // Copyright (c) 2015年 eamon. All rights reserved. 7 | // 8 | 9 | #import "MainPageViewController.h" 10 | #import "AppDelegate.h" 11 | #define vBackBarButtonItemName @"backArrow.png" //导航条返回默认图片名 12 | @interface MainPageViewController () 13 | 14 | @end 15 | 16 | @implementation MainPageViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | self.title = @"主界面"; 21 | self.view.backgroundColor = [UIColor whiteColor]; 22 | 23 | UIButton *menuBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 24 | menuBtn.frame = CGRectMake(0, 0, 20, 18); 25 | [menuBtn setBackgroundImage:[UIImage imageNamed:@"menu"] forState:UIControlStateNormal]; 26 | [menuBtn addTarget:self action:@selector(openOrCloseLeftList) forControlEvents:UIControlEventTouchUpInside]; 27 | self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:menuBtn]; 28 | } 29 | 30 | - (void) openOrCloseLeftList 31 | { 32 | AppDelegate *tempAppDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 33 | 34 | if (tempAppDelegate.LeftSlideVC.closed) 35 | { 36 | [tempAppDelegate.LeftSlideVC openLeftView]; 37 | } 38 | else 39 | { 40 | [tempAppDelegate.LeftSlideVC closeLeftView]; 41 | } 42 | } 43 | 44 | - (void)viewWillDisappear:(BOOL)animated 45 | { 46 | [super viewWillDisappear:animated]; 47 | NSLog(@"viewWillDisappear"); 48 | AppDelegate *tempAppDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 49 | [tempAppDelegate.LeftSlideVC setPanEnabled:NO]; 50 | } 51 | 52 | - (void)viewWillAppear:(BOOL)animated 53 | { 54 | [super viewWillAppear:animated]; 55 | NSLog(@"viewWillAppear"); 56 | AppDelegate *tempAppDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 57 | [tempAppDelegate.LeftSlideVC setPanEnabled:YES]; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /LeftSlide/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LeftSlide 4 | // 5 | // Created by huangzhenyu on 15/6/18. 6 | // Copyright (c) 2015年 eamon. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /LeftSlide/otherViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // otherViewController.h 3 | // LGDeckViewController 4 | // 5 | // Created by huangzhenyu on 15/6/1. 6 | // Copyright (c) 2015年 Jamie-Ling. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface otherViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /LeftSlide/otherViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // otherViewController.m 3 | // LGDeckViewController 4 | // 5 | // Created by huangzhenyu on 15/6/1. 6 | // Copyright (c) 2015年 Jamie-Ling. All rights reserved. 7 | // 8 | 9 | #import "otherViewController.h" 10 | 11 | @interface otherViewController () 12 | 13 | @end 14 | 15 | @implementation otherViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | self.view.backgroundColor = [UIColor brownColor]; 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | /* 28 | #pragma mark - Navigation 29 | 30 | // In a storyboard-based application, you will often want to do a little preparation before navigation 31 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 32 | // Get the new view controller using [segue destinationViewController]. 33 | // Pass the selected object to the new view controller. 34 | } 35 | */ 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /LeftSlideTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.eamon.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /LeftSlideTests/LeftSlideTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // LeftSlideTests.m 3 | // LeftSlideTests 4 | // 5 | // Created by huangzhenyu on 15/6/18. 6 | // Copyright (c) 2015年 eamon. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface LeftSlideTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation LeftSlideTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /LeftSlideViewController/LeftSlideViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LeftSlideViewController.h 3 | // LeftSlideViewController 4 | // 5 | // Created by huangzhenyu on 15/06/18. 6 | // Copyright (c) 2015年 huangzhenyu. All rights reserved. 7 | 8 | #define kScreenSize [[UIScreen mainScreen] bounds].size 9 | #define kScreenWidth [[UIScreen mainScreen] bounds].size.width 10 | #define kScreenHeight [[UIScreen mainScreen] bounds].size.height 11 | 12 | #define kMainPageDistance 100 //打开左侧窗时,中视图(右视图)露出的宽度 13 | #define kMainPageScale 0.8 //打开左侧窗时,中视图(右视图)缩放比例 14 | #define kMainPageCenter CGPointMake(kScreenWidth + kScreenWidth * kMainPageScale / 2.0 - kMainPageDistance, kScreenHeight / 2) //打开左侧窗时,中视图中心点 15 | 16 | #define vCouldChangeDeckStateDistance (kScreenWidth - kMainPageDistance) / 2.0 - 40 //滑动距离大于此数时,状态改变(关--》开,或者开--》关) 17 | #define vSpeedFloat 0.7 //滑动速度 18 | 19 | #define kLeftAlpha 0.9 //左侧蒙版的最大值 20 | #define kLeftCenterX 30 //左侧初始偏移量 21 | #define kLeftScale 0.7 //左侧初始缩放比例 22 | 23 | #define vDeckCanNotPanViewTag 987654 // 不响应此侧滑的View的tag 24 | 25 | #import 26 | #import "UIView_extra.h" 27 | 28 | @interface DeckViewController : UIViewController 29 | 30 | //滑动速度系数-建议在0.5-1之间。默认为0.5 31 | @property (nonatomic, assign) CGFloat speedf; 32 | 33 | //左侧窗控制器 34 | @property (nonatomic, strong) UIViewController *leftVC; 35 | 36 | //点击手势控制器,是否允许点击视图恢复视图位置。默认为yes 37 | @property (nonatomic, strong) UITapGestureRecognizer *sideslipTapGes; 38 | 39 | //滑动手势控制器 40 | @property (nonatomic, strong) UIPanGestureRecognizer *pan; 41 | 42 | //侧滑窗是否关闭(关闭时显示为主页) 43 | @property (nonatomic, assign) BOOL closed; 44 | 45 | 46 | /** 47 | @brief 初始化侧滑控制器 48 | @param leftVC 右视图控制器 49 | mainVC 中间视图控制器 50 | @result instancetype 初始化生成的对象 51 | */ 52 | - (instancetype)initWithLeftView:(UIViewController *)leftVC 53 | andMainView:(UIViewController *)mainVC; 54 | 55 | /** 56 | @brief 关闭左视图 57 | */ 58 | - (void)closeLeftView; 59 | 60 | 61 | /** 62 | @brief 打开左视图 63 | */ 64 | - (void)openLeftView; 65 | 66 | /** 67 | * 设置滑动开关是否开启 68 | * 69 | * @param enabled YES:支持滑动手势,NO:不支持滑动手势 70 | */ 71 | - (void)setPanEnabled: (BOOL) enabled; 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /LeftSlideViewController/LeftSlideViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // LeftSlideViewController.m 3 | // LeftSlideViewController 4 | // 5 | // Created by huangzhenyu on 15/06/18. 6 | // Copyright (c) 2015年 huangzhenyu. All rights reserved. 7 | 8 | #import "LeftSlideViewController.h" 9 | 10 | 11 | @interface DeckViewController () 12 | { 13 | CGFloat _scalef; //实时横向位移 14 | } 15 | @property (nonatomic,strong) UIViewController *mainVC; 16 | @property (nonatomic,strong) UITableView *leftTableview; 17 | @property (nonatomic,assign) CGFloat leftTableviewW; 18 | @property (nonatomic,strong) UIView *contentView; 19 | @end 20 | 21 | 22 | @implementation DeckViewController 23 | 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | // Do any additional setup after loading the view. 27 | } 28 | 29 | /** 30 | @brief 初始化侧滑控制器 31 | @param leftVC 左视图控制器 32 | mainVC 中间视图控制器 33 | @result instancetype 初始化生成的对象 34 | */ 35 | - (instancetype)initWithLeftView:(UIViewController *)leftVC 36 | andMainView:(UIViewController *)mainVC 37 | { 38 | if(self = [super init]){ 39 | self.speedf = vSpeedFloat; 40 | 41 | self.leftVC = leftVC; 42 | self.mainVC = mainVC; 43 | 44 | //滑动手势 45 | self.pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)]; 46 | [self.mainVC.view addGestureRecognizer:self.pan]; 47 | 48 | [self.pan setCancelsTouchesInView:YES]; 49 | self.pan.delegate = self; 50 | 51 | self.leftVC.view.hidden = YES; 52 | 53 | [self.view addSubview:self.leftVC.view]; 54 | 55 | //蒙版 56 | UIView *view = [[UIView alloc] init]; 57 | view.frame = self.leftVC.view.bounds; 58 | view.backgroundColor = [UIColor blackColor]; 59 | view.alpha = 0.5; 60 | self.contentView = view; 61 | [self.leftVC.view addSubview:view]; 62 | 63 | //获取左侧tableview 64 | for (UIView *obj in self.leftVC.view.subviews) { 65 | if ([obj isKindOfClass:[UITableView class]]) { 66 | self.leftTableview = (UITableView *)obj; 67 | } 68 | } 69 | self.leftTableview.backgroundColor = [UIColor clearColor]; 70 | self.leftTableview.frame = CGRectMake(0, 0, kScreenWidth - kMainPageDistance, kScreenHeight); 71 | //设置左侧tableview的初始位置和缩放系数 72 | self.leftTableview.transform = CGAffineTransformMakeScale(kLeftScale, kLeftScale); 73 | self.leftTableview.center = CGPointMake(kLeftCenterX, kScreenHeight * 0.5); 74 | 75 | [self.view addSubview:self.mainVC.view]; 76 | self.closed = YES;//初始时侧滑窗关闭 77 | 78 | } 79 | return self; 80 | } 81 | 82 | - (void) viewWillAppear:(BOOL)animated 83 | { 84 | [super viewWillAppear:animated]; 85 | self.leftVC.view.hidden = NO; 86 | } 87 | 88 | #pragma mark - 滑动手势 89 | 90 | //滑动手势 91 | - (void) handlePan: (UIPanGestureRecognizer *)rec{ 92 | 93 | CGPoint point = [rec translationInView:self.view]; 94 | _scalef = (point.x * self.speedf + _scalef); 95 | 96 | BOOL needMoveWithTap = YES; //是否还需要跟随手指移动 97 | if (((self.mainVC.view.x <= 0) && (_scalef <= 0)) || ((self.mainVC.view.x >= (kScreenWidth - kMainPageDistance )) && (_scalef >= 0))) 98 | { 99 | //边界值管控 100 | _scalef = 0; 101 | needMoveWithTap = NO; 102 | } 103 | 104 | //根据视图位置判断是左滑还是右边滑动 105 | if (needMoveWithTap && (rec.view.frame.origin.x >= 0) && (rec.view.frame.origin.x <= (kScreenWidth - kMainPageDistance))) 106 | { 107 | CGFloat recCenterX = rec.view.center.x + point.x * self.speedf; 108 | if (recCenterX < kScreenWidth * 0.5 - 2) { 109 | recCenterX = kScreenWidth * 0.5; 110 | } 111 | 112 | CGFloat recCenterY = rec.view.center.y; 113 | 114 | rec.view.center = CGPointMake(recCenterX,recCenterY); 115 | 116 | //scale 1.0~kMainPageScale 117 | CGFloat scale = 1 - (1 - kMainPageScale) * (rec.view.frame.origin.x / (kScreenWidth - kMainPageDistance)); 118 | 119 | rec.view.transform = CGAffineTransformScale(CGAffineTransformIdentity,scale, scale); 120 | [rec setTranslation:CGPointMake(0, 0) inView:self.view]; 121 | 122 | CGFloat leftTabCenterX = kLeftCenterX + ((kScreenWidth - kMainPageDistance) * 0.5 - kLeftCenterX) * (rec.view.frame.origin.x / (kScreenWidth - kMainPageDistance)); 123 | 124 | NSLog(@"%f",leftTabCenterX); 125 | 126 | 127 | //leftScale kLeftScale~1.0 128 | CGFloat leftScale = kLeftScale + (1 - kLeftScale) * (rec.view.frame.origin.x / (kScreenWidth - kMainPageDistance)); 129 | 130 | self.leftTableview.center = CGPointMake(leftTabCenterX, kScreenHeight * 0.5); 131 | self.leftTableview.transform = CGAffineTransformScale(CGAffineTransformIdentity, leftScale,leftScale); 132 | 133 | //tempAlpha kLeftAlpha~0 134 | CGFloat tempAlpha = kLeftAlpha - kLeftAlpha * (rec.view.frame.origin.x / (kScreenWidth - kMainPageDistance)); 135 | self.contentView.alpha = tempAlpha; 136 | 137 | } 138 | else 139 | { 140 | //超出范围, 141 | if (self.mainVC.view.x < 0) 142 | { 143 | [self closeLeftView]; 144 | _scalef = 0; 145 | } 146 | else if (self.mainVC.view.x > (kScreenWidth - kMainPageDistance)) 147 | { 148 | [self openLeftView]; 149 | _scalef = 0; 150 | } 151 | } 152 | 153 | //手势结束后修正位置,超过约一半时向多出的一半偏移 154 | if (rec.state == UIGestureRecognizerStateEnded) { 155 | if (fabs(_scalef) > vCouldChangeDeckStateDistance) 156 | { 157 | if (self.closed) 158 | { 159 | [self openLeftView]; 160 | } 161 | else 162 | { 163 | [self closeLeftView]; 164 | } 165 | } 166 | else 167 | { 168 | if (self.closed) 169 | { 170 | [self closeLeftView]; 171 | } 172 | else 173 | { 174 | [self openLeftView]; 175 | } 176 | } 177 | _scalef = 0; 178 | } 179 | } 180 | 181 | 182 | #pragma mark - 单击手势 183 | -(void)handeTap:(UITapGestureRecognizer *)tap{ 184 | 185 | if ((!self.closed) && (tap.state == UIGestureRecognizerStateEnded)) 186 | { 187 | [UIView beginAnimations:nil context:nil]; 188 | tap.view.transform = CGAffineTransformScale(CGAffineTransformIdentity,1.0,1.0); 189 | tap.view.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2,[UIScreen mainScreen].bounds.size.height/2); 190 | self.closed = YES; 191 | 192 | self.leftTableview.center = CGPointMake(kLeftCenterX, kScreenHeight * 0.5); 193 | self.leftTableview.transform = CGAffineTransformScale(CGAffineTransformIdentity,kLeftScale,kLeftScale); 194 | self.contentView.alpha = kLeftAlpha; 195 | 196 | [UIView commitAnimations]; 197 | _scalef = 0; 198 | [self removeSingleTap]; 199 | } 200 | 201 | } 202 | 203 | #pragma mark - 修改视图位置 204 | /** 205 | @brief 关闭左视图 206 | */ 207 | - (void)closeLeftView 208 | { 209 | [UIView beginAnimations:nil context:nil]; 210 | self.mainVC.view.transform = CGAffineTransformScale(CGAffineTransformIdentity,1.0,1.0); 211 | self.mainVC.view.center = CGPointMake(kScreenWidth / 2, kScreenHeight / 2); 212 | self.closed = YES; 213 | 214 | self.leftTableview.center = CGPointMake(kLeftCenterX, kScreenHeight * 0.5); 215 | self.leftTableview.transform = CGAffineTransformScale(CGAffineTransformIdentity,kLeftScale,kLeftScale); 216 | self.contentView.alpha = kLeftAlpha; 217 | 218 | [UIView commitAnimations]; 219 | [self removeSingleTap]; 220 | } 221 | 222 | /** 223 | @brief 打开左视图 224 | */ 225 | - (void)openLeftView; 226 | { 227 | [UIView beginAnimations:nil context:nil]; 228 | self.mainVC.view.transform = CGAffineTransformScale(CGAffineTransformIdentity,kMainPageScale,kMainPageScale); 229 | self.mainVC.view.center = kMainPageCenter; 230 | self.closed = NO; 231 | 232 | self.leftTableview.center = CGPointMake((kScreenWidth - kMainPageDistance) * 0.5, kScreenHeight * 0.5); 233 | self.leftTableview.transform = CGAffineTransformScale(CGAffineTransformIdentity,1.0,1.0); 234 | self.contentView.alpha = 0; 235 | 236 | [UIView commitAnimations]; 237 | [self disableTapButton]; 238 | } 239 | 240 | #pragma mark - 行为收敛控制 241 | - (void)disableTapButton 242 | { 243 | for (UIButton *tempButton in [_mainVC.view subviews]) 244 | { 245 | [tempButton setUserInteractionEnabled:NO]; 246 | } 247 | //单击 248 | if (!self.sideslipTapGes) 249 | { 250 | //单击手势 251 | self.sideslipTapGes= [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handeTap:)]; 252 | [self.sideslipTapGes setNumberOfTapsRequired:1]; 253 | 254 | [self.mainVC.view addGestureRecognizer:self.sideslipTapGes]; 255 | self.sideslipTapGes.cancelsTouchesInView = YES; //点击事件盖住其它响应事件,但盖不住Button; 256 | } 257 | } 258 | 259 | //关闭行为收敛 260 | - (void) removeSingleTap 261 | { 262 | for (UIButton *tempButton in [self.mainVC.view subviews]) 263 | { 264 | [tempButton setUserInteractionEnabled:YES]; 265 | } 266 | [self.mainVC.view removeGestureRecognizer:self.sideslipTapGes]; 267 | self.sideslipTapGes = nil; 268 | } 269 | 270 | /** 271 | * 设置滑动开关是否开启 272 | * 273 | * @param enabled YES:支持滑动手势,NO:不支持滑动手势 274 | */ 275 | 276 | - (void)setPanEnabled: (BOOL) enabled 277 | { 278 | [self.pan setEnabled:enabled]; 279 | } 280 | 281 | -(BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldReceiveTouch:(UITouch*)touch { 282 | 283 | if(touch.view.tag == vDeckCanNotPanViewTag) 284 | { 285 | // NSLog(@"不响应侧滑"); 286 | return NO; 287 | } 288 | else 289 | { 290 | // NSLog(@"响应侧滑"); 291 | return YES; 292 | } 293 | } 294 | 295 | @end 296 | -------------------------------------------------------------------------------- /LeftSlideViewController/UIView_extra.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView_extra.h 3 | // Woyoli 4 | // 5 | // Created by jamie on 14-11-25. 6 | // Copyright (c) 2014年 Missionsky. All rights reserved. 7 | // 8 | 9 | #define vAlertTag 10086 10 | 11 | #import 12 | 13 | @interface UIView (UIView) 14 | 15 | @property (nonatomic, assign) CGFloat x; 16 | @property (nonatomic, assign) CGFloat y; 17 | @property (nonatomic, assign) CGFloat width; 18 | @property (nonatomic, assign) CGFloat height; 19 | @property (nonatomic, assign) CGPoint origin; 20 | @property (nonatomic, assign) CGSize size; 21 | @property (nonatomic, assign) CGFloat bottom; 22 | @property (nonatomic, assign) CGFloat right; 23 | @property (nonatomic, assign) CGFloat centerX; 24 | @property (nonatomic, assign) CGFloat centerY; 25 | @property (nonatomic, strong, readonly) UIView *lastSubviewOnX; 26 | @property (nonatomic, strong, readonly) UIView *lastSubviewOnY; 27 | 28 | /** 29 | * @brief 移除此view上的所有子视图 30 | */ 31 | - (void)removeAllSubviews; 32 | 33 | /** 34 | @brief 弹窗 35 | @param title 弹窗标题 36 | message 弹窗信息 37 | */ 38 | + (void) showAlertView: (NSString*) title andMessage: (NSString *) message; 39 | 40 | /** 41 | * 弹窗 42 | * 43 | * @param title 弹窗标题 44 | * @param message 弹窗信息 45 | * @param delegate 弹窗代理 46 | */ 47 | + (void) showAlertView: (NSString*) title 48 | andMessage: (NSString *) message 49 | withDelegate: (UIViewController *) delegate; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /LeftSlideViewController/UIView_extra.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView_extra.m 3 | // Woyoli 4 | // 5 | // Created by jamie on 14-11-25. 6 | // Copyright (c) 2014年 Missionsky. All rights reserved. 7 | // 8 | 9 | #import "UIView_extra.h" 10 | 11 | @implementation UIView (UIView) 12 | 13 | @dynamic x; 14 | @dynamic y; 15 | @dynamic width; 16 | @dynamic height; 17 | @dynamic origin; 18 | @dynamic size; 19 | 20 | #pragma mark ---------------- Setters----------------- 21 | -(void)setX:(CGFloat)x{ 22 | CGRect r = self.frame; 23 | r.origin.x = x; 24 | self.frame = r; 25 | } 26 | 27 | -(void)setY:(CGFloat)y{ 28 | CGRect r = self.frame; 29 | r.origin.y = y; 30 | self.frame = r; 31 | } 32 | 33 | -(void)setWidth:(CGFloat)width{ 34 | CGRect r = self.frame; 35 | r.size.width = width; 36 | self.frame = r; 37 | } 38 | 39 | -(void)setHeight:(CGFloat)height{ 40 | CGRect r = self.frame; 41 | r.size.height = height; 42 | self.frame = r; 43 | } 44 | 45 | -(void)setOrigin:(CGPoint)origin{ 46 | self.x = origin.x; 47 | self.y = origin.y; 48 | } 49 | 50 | -(void)setSize:(CGSize)size{ 51 | self.width = size.width; 52 | self.height = size.height; 53 | } 54 | 55 | -(void)setRight:(CGFloat)right { 56 | CGRect frame = self.frame; 57 | frame.origin.x = right - frame.size.width; 58 | self.frame = frame; 59 | } 60 | 61 | -(void)setBottom:(CGFloat)bottom { 62 | CGRect frame = self.frame; 63 | frame.origin.y = bottom - frame.size.height; 64 | self.frame = frame; 65 | } 66 | 67 | -(void)setCenterX:(CGFloat)centerX { 68 | self.center = CGPointMake(centerX, self.center.y); 69 | } 70 | 71 | -(void)setCenterY:(CGFloat)centerY { 72 | self.center = CGPointMake(self.center.x, centerY); 73 | } 74 | 75 | #pragma mark ---------------- Getters----------------- 76 | -(CGFloat)x{ 77 | return self.frame.origin.x; 78 | } 79 | 80 | -(CGFloat)y{ 81 | return self.frame.origin.y; 82 | } 83 | 84 | -(CGFloat)width{ 85 | return self.frame.size.width; 86 | } 87 | 88 | -(CGFloat)height{ 89 | return self.frame.size.height; 90 | } 91 | 92 | -(CGPoint)origin{ 93 | return CGPointMake(self.x, self.y); 94 | } 95 | 96 | -(CGSize)size{ 97 | return CGSizeMake(self.width, self.height); 98 | } 99 | 100 | -(CGFloat)right { 101 | return self.frame.origin.x + self.frame.size.width; 102 | } 103 | 104 | -(CGFloat)bottom { 105 | return self.frame.origin.y + self.frame.size.height; 106 | } 107 | 108 | -(CGFloat)centerX { 109 | return self.center.x; 110 | } 111 | 112 | -(CGFloat)centerY { 113 | return self.center.y; 114 | } 115 | 116 | -(UIView *)lastSubviewOnX{ 117 | if(self.subviews.count > 0){ 118 | UIView *outView = self.subviews[0]; 119 | 120 | for(UIView *v in self.subviews) 121 | if(v.x > outView.x) 122 | outView = v; 123 | 124 | return outView; 125 | } 126 | 127 | return nil; 128 | } 129 | 130 | -(UIView *)lastSubviewOnY{ 131 | if(self.subviews.count > 0){ 132 | UIView *outView = self.subviews[0]; 133 | 134 | for(UIView *v in self.subviews) 135 | if(v.y > outView.y) 136 | outView = v; 137 | 138 | return outView; 139 | } 140 | 141 | return nil; 142 | } 143 | 144 | #pragma mark ---------------- other----------------- 145 | /** 146 | * @brief 移除此view上的所有子视图 147 | */ 148 | - (void)removeAllSubviews { 149 | for (UIView *view in self.subviews) { 150 | [view removeFromSuperview]; 151 | } 152 | return; 153 | } 154 | 155 | /** 156 | @brief 弹窗 157 | @param title 弹窗标题 158 | message 弹窗信息 159 | */ 160 | + (void) showAlertView: (NSString*) title andMessage: (NSString *) message 161 | { 162 | dispatch_async(dispatch_get_main_queue() , ^{ 163 | UIAlertView *alert = [[UIAlertView alloc] init]; 164 | alert.title = title; 165 | alert.message = message; 166 | [alert addButtonWithTitle:@"确定"]; 167 | [alert show]; 168 | alert = nil; 169 | }); 170 | } 171 | 172 | /** 173 | * 弹窗 174 | * 175 | * @param title 弹窗标题 176 | * @param message 弹窗信息 177 | * @param delegate 弹窗代理 178 | */ 179 | + (void) showAlertView: (NSString*) title 180 | andMessage: (NSString *) message 181 | withDelegate: (UIViewController *) delegate 182 | { 183 | dispatch_async(dispatch_get_main_queue() , ^{ 184 | UIAlertView *alert = [[UIAlertView alloc] init]; 185 | alert.title = title; 186 | alert.message = message; 187 | alert.delegate = delegate; 188 | alert.tag = vAlertTag; 189 | [alert addButtonWithTitle:@"确定"]; 190 | [alert show]; 191 | alert = nil; 192 | }); 193 | } 194 | 195 | 196 | @end 197 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # leftSlideMenu 2 | 仿QQ左侧抽屉效果,左侧有渐入和放大效果。 3 | 4 | ![image](https://github.com/chennyhuang/LeftSlide/blob/master/leftSlideMenu.gif) -------------------------------------------------------------------------------- /leftSlideMenu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chennyhuang/LeftSlide/8c7aa31f77a7078579fe70cf902e9fe4ffccde16/leftSlideMenu.gif --------------------------------------------------------------------------------