From ba1bfa919105d469330b792466ba4c961ef6a617 Mon Sep 17 00:00:00 2001 From: i_82 Date: Fri, 7 Apr 2017 11:42:19 +0200 Subject: [PATCH 1/6] Pan Gesture --- .../project.pbxproj | 127 ++++++---- .../JVDrawerSettingsTableViewController.m | 8 +- .../JVFloatingDrawer/JVGitHubViewController.m | 10 +- .../JVLeftDrawerTableViewCell.m | 1 + Example/Podfile | 4 +- Example/Podfile.lock | 6 +- Pod/Classes/JVFloatingDrawerAnimation.h | 17 ++ Pod/Classes/JVFloatingDrawerSpringAnimator.m | 66 ++++- Pod/Classes/JVFloatingDrawerView.m | 2 +- Pod/Classes/JVFloatingDrawerViewController.h | 11 + Pod/Classes/JVFloatingDrawerViewController.m | 229 ++++++++++++++++-- 11 files changed, 396 insertions(+), 85 deletions(-) diff --git a/Example/JVFloatingDrawer.xcodeproj/project.pbxproj b/Example/JVFloatingDrawer.xcodeproj/project.pbxproj index 7fbee34..37d5607 100644 --- a/Example/JVFloatingDrawer.xcodeproj/project.pbxproj +++ b/Example/JVFloatingDrawer.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 10B985A86072CDBA1045907B /* libPods-JVFloatingDrawer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A99CBCB0955D3152FFCA29DB /* libPods-JVFloatingDrawer.a */; }; 2CE7E6631A62D8470072121A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CE7E6621A62D8470072121A /* main.m */; }; 2CE7E6661A62D8470072121A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CE7E6651A62D8470072121A /* AppDelegate.m */; }; 2CE7E66C1A62D8470072121A /* Drawers.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2CE7E66A1A62D8470072121A /* Drawers.storyboard */; }; @@ -15,10 +14,11 @@ 2CE7E6711A62D8470072121A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2CE7E66F1A62D8470072121A /* LaunchScreen.xib */; }; 2CE7E67D1A62D8480072121A /* JVFloatingDrawerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CE7E67C1A62D8480072121A /* JVFloatingDrawerTests.m */; }; 2CE7E6A01A636CBD0072121A /* JVGitHubViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CE7E69F1A636CBD0072121A /* JVGitHubViewController.m */; }; - 9C8841BB0C583D5E61D80A4E /* libPods-JVFloatingDrawerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 225393A6ADE627876AF04BE1 /* libPods-JVFloatingDrawerTests.a */; }; + 94EC5EE44F9569D5533A9749 /* libPods-JVFloatingDrawerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 99EA2C630B37014CB1B959E0 /* libPods-JVFloatingDrawerTests.a */; }; B9E746E41A684DC800C5163E /* JVLeftDrawerTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B9E746E31A684DC800C5163E /* JVLeftDrawerTableViewController.m */; }; B9E746EB1A684E4000C5163E /* JVDrawerSettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B9E746E91A684E4000C5163E /* JVDrawerSettingsTableViewController.m */; }; B9E746FB1A68959100C5163E /* JVLeftDrawerTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B9E746FA1A68959100C5163E /* JVLeftDrawerTableViewCell.m */; }; + E1CDACD23254CAEEAAEB2229 /* libPods-JVFloatingDrawer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BA925659E8024DC86D051335 /* libPods-JVFloatingDrawer.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -32,8 +32,6 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 0B650F2DCB40F4B77A470141 /* Pods-JVFloatingDrawerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JVFloatingDrawerTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-JVFloatingDrawerTests/Pods-JVFloatingDrawerTests.debug.xcconfig"; sourceTree = ""; }; - 225393A6ADE627876AF04BE1 /* libPods-JVFloatingDrawerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-JVFloatingDrawerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 2CE7E65D1A62D8470072121A /* JVFloatingDrawer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JVFloatingDrawer.app; sourceTree = BUILT_PRODUCTS_DIR; }; 2CE7E6611A62D8470072121A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 2CE7E6621A62D8470072121A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; @@ -47,9 +45,9 @@ 2CE7E67C1A62D8480072121A /* JVFloatingDrawerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JVFloatingDrawerTests.m; sourceTree = ""; }; 2CE7E69E1A636CBD0072121A /* JVGitHubViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JVGitHubViewController.h; sourceTree = ""; }; 2CE7E69F1A636CBD0072121A /* JVGitHubViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JVGitHubViewController.m; sourceTree = ""; }; - 4253C21B91BC9E176E687842 /* Pods-JVFloatingDrawer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JVFloatingDrawer.debug.xcconfig"; path = "Pods/Target Support Files/Pods-JVFloatingDrawer/Pods-JVFloatingDrawer.debug.xcconfig"; sourceTree = ""; }; - 43B9557D1EFD5CCA2211B8B7 /* Pods-JVFloatingDrawerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JVFloatingDrawerTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-JVFloatingDrawerTests/Pods-JVFloatingDrawerTests.release.xcconfig"; sourceTree = ""; }; - A99CBCB0955D3152FFCA29DB /* libPods-JVFloatingDrawer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-JVFloatingDrawer.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6CF63AE0A8156781502C18BF /* Pods-JVFloatingDrawerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JVFloatingDrawerTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-JVFloatingDrawerTests/Pods-JVFloatingDrawerTests.debug.xcconfig"; sourceTree = ""; }; + 99EA2C630B37014CB1B959E0 /* libPods-JVFloatingDrawerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-JVFloatingDrawerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 9B7115FC8E61D853292F24CA /* Pods-JVFloatingDrawer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JVFloatingDrawer.debug.xcconfig"; path = "Pods/Target Support Files/Pods-JVFloatingDrawer/Pods-JVFloatingDrawer.debug.xcconfig"; sourceTree = ""; }; B9352DD61A6AE74E008D3B4E /* JVFloatingDrawer.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = JVFloatingDrawer.podspec; path = ../JVFloatingDrawer.podspec; sourceTree = ""; }; B9352DD71A6AE74E008D3B4E /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; B9352DD81A6AE74E008D3B4E /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; @@ -59,7 +57,9 @@ B9E746E91A684E4000C5163E /* JVDrawerSettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JVDrawerSettingsTableViewController.m; sourceTree = ""; }; B9E746F91A68959100C5163E /* JVLeftDrawerTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JVLeftDrawerTableViewCell.h; sourceTree = ""; }; B9E746FA1A68959100C5163E /* JVLeftDrawerTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JVLeftDrawerTableViewCell.m; sourceTree = ""; }; - F1E2F3B7D81A5D13ED695A78 /* Pods-JVFloatingDrawer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JVFloatingDrawer.release.xcconfig"; path = "Pods/Target Support Files/Pods-JVFloatingDrawer/Pods-JVFloatingDrawer.release.xcconfig"; sourceTree = ""; }; + BA925659E8024DC86D051335 /* libPods-JVFloatingDrawer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-JVFloatingDrawer.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + CE53EDF06970A08BF1611438 /* Pods-JVFloatingDrawer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JVFloatingDrawer.release.xcconfig"; path = "Pods/Target Support Files/Pods-JVFloatingDrawer/Pods-JVFloatingDrawer.release.xcconfig"; sourceTree = ""; }; + EB2A8D44D8C10B1140C6F703 /* Pods-JVFloatingDrawerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JVFloatingDrawerTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-JVFloatingDrawerTests/Pods-JVFloatingDrawerTests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -67,7 +67,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 10B985A86072CDBA1045907B /* libPods-JVFloatingDrawer.a in Frameworks */, + E1CDACD23254CAEEAAEB2229 /* libPods-JVFloatingDrawer.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -75,24 +75,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9C8841BB0C583D5E61D80A4E /* libPods-JVFloatingDrawerTests.a in Frameworks */, + 94EC5EE44F9569D5533A9749 /* libPods-JVFloatingDrawerTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 24A3B1CDDA31218747F3825B /* Pods */ = { - isa = PBXGroup; - children = ( - 4253C21B91BC9E176E687842 /* Pods-JVFloatingDrawer.debug.xcconfig */, - F1E2F3B7D81A5D13ED695A78 /* Pods-JVFloatingDrawer.release.xcconfig */, - 0B650F2DCB40F4B77A470141 /* Pods-JVFloatingDrawerTests.debug.xcconfig */, - 43B9557D1EFD5CCA2211B8B7 /* Pods-JVFloatingDrawerTests.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; 2CE7E6541A62D8470072121A = { isa = PBXGroup; children = ( @@ -100,8 +89,8 @@ 2CE7E65F1A62D8470072121A /* JVFloatingDrawer */, 2CE7E6791A62D8480072121A /* JVFloatingDrawerTests */, 2CE7E65E1A62D8470072121A /* Products */, - 24A3B1CDDA31218747F3825B /* Pods */, - 74A0752A6653A2C089003EF7 /* Frameworks */, + 3EC40E26797B0883B5815FC4 /* Pods */, + EC938511F0174DBEAD64E39C /* Frameworks */, ); sourceTree = ""; }; @@ -161,13 +150,15 @@ name = "Supporting Files"; sourceTree = ""; }; - 74A0752A6653A2C089003EF7 /* Frameworks */ = { + 3EC40E26797B0883B5815FC4 /* Pods */ = { isa = PBXGroup; children = ( - A99CBCB0955D3152FFCA29DB /* libPods-JVFloatingDrawer.a */, - 225393A6ADE627876AF04BE1 /* libPods-JVFloatingDrawerTests.a */, + 9B7115FC8E61D853292F24CA /* Pods-JVFloatingDrawer.debug.xcconfig */, + CE53EDF06970A08BF1611438 /* Pods-JVFloatingDrawer.release.xcconfig */, + 6CF63AE0A8156781502C18BF /* Pods-JVFloatingDrawerTests.debug.xcconfig */, + EB2A8D44D8C10B1140C6F703 /* Pods-JVFloatingDrawerTests.release.xcconfig */, ); - name = Frameworks; + name = Pods; sourceTree = ""; }; B9352DDC1A6AE75A008D3B4E /* Podspec Metadata */ = { @@ -180,6 +171,15 @@ name = "Podspec Metadata"; sourceTree = ""; }; + EC938511F0174DBEAD64E39C /* Frameworks */ = { + isa = PBXGroup; + children = ( + BA925659E8024DC86D051335 /* libPods-JVFloatingDrawer.a */, + 99EA2C630B37014CB1B959E0 /* libPods-JVFloatingDrawerTests.a */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -187,11 +187,12 @@ isa = PBXNativeTarget; buildConfigurationList = 2CE7E6801A62D8480072121A /* Build configuration list for PBXNativeTarget "JVFloatingDrawer" */; buildPhases = ( - 5387F51B96BADF6420737642 /* Check Pods Manifest.lock */, + 296EB02D24C4CF53DECB78EC /* [CP] Check Pods Manifest.lock */, 2CE7E6591A62D8470072121A /* Sources */, 2CE7E65A1A62D8470072121A /* Frameworks */, 2CE7E65B1A62D8470072121A /* Resources */, - 783AEA0CD6B8193ECAE917EA /* Copy Pods Resources */, + 0CD29FDC3B59257375C8C94F /* [CP] Embed Pods Frameworks */, + E8CE9E81D5EE16FE7BDF2F4D /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -206,11 +207,12 @@ isa = PBXNativeTarget; buildConfigurationList = 2CE7E6831A62D8480072121A /* Build configuration list for PBXNativeTarget "JVFloatingDrawerTests" */; buildPhases = ( - 011008DF7BAC9783991A0E0C /* Check Pods Manifest.lock */, + 1473D190298B8FC96C5B78CC /* [CP] Check Pods Manifest.lock */, 2CE7E6721A62D8470072121A /* Sources */, 2CE7E6731A62D8470072121A /* Frameworks */, 2CE7E6741A62D8470072121A /* Resources */, - 34A0601F6D36FB16890F3D74 /* Copy Pods Resources */, + 016D68332A4D0250EBF107CD /* [CP] Embed Pods Frameworks */, + C82DA6685D240A17CAF976DE /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -233,6 +235,7 @@ TargetAttributes = { 2CE7E65C1A62D8470072121A = { CreatedOnToolsVersion = 6.1.1; + DevelopmentTeam = GXZ23M5TP2; }; 2CE7E6751A62D8470072121A = { CreatedOnToolsVersion = 6.1.1; @@ -280,59 +283,89 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 011008DF7BAC9783991A0E0C /* Check Pods Manifest.lock */ = { + 016D68332A4D0250EBF107CD /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - 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"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-JVFloatingDrawerTests/Pods-JVFloatingDrawerTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 34A0601F6D36FB16890F3D74 /* Copy Pods Resources */ = { + 0CD29FDC3B59257375C8C94F /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Copy Pods Resources"; + name = "[CP] Embed Pods Frameworks"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-JVFloatingDrawerTests/Pods-JVFloatingDrawerTests-resources.sh\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-JVFloatingDrawer/Pods-JVFloatingDrawer-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 1473D190298B8FC96C5B78CC /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 296EB02D24C4CF53DECB78EC /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; showEnvVarsInLog = 0; }; - 5387F51B96BADF6420737642 /* Check Pods Manifest.lock */ = { + C82DA6685D240A17CAF976DE /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Check Pods Manifest.lock"; + name = "[CP] Copy Pods Resources"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - 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"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-JVFloatingDrawerTests/Pods-JVFloatingDrawerTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 783AEA0CD6B8193ECAE917EA /* Copy Pods Resources */ = { + E8CE9E81D5EE16FE7BDF2F4D /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Copy Pods Resources"; + name = "[CP] Copy Pods Resources"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; @@ -474,9 +507,10 @@ }; 2CE7E6811A62D8480072121A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4253C21B91BC9E176E687842 /* Pods-JVFloatingDrawer.debug.xcconfig */; + baseConfigurationReference = 9B7115FC8E61D853292F24CA /* Pods-JVFloatingDrawer.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = GXZ23M5TP2; INFOPLIST_FILE = JVFloatingDrawer/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -486,9 +520,10 @@ }; 2CE7E6821A62D8480072121A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F1E2F3B7D81A5D13ED695A78 /* Pods-JVFloatingDrawer.release.xcconfig */; + baseConfigurationReference = CE53EDF06970A08BF1611438 /* Pods-JVFloatingDrawer.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = GXZ23M5TP2; INFOPLIST_FILE = JVFloatingDrawer/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.3; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -498,7 +533,7 @@ }; 2CE7E6841A62D8480072121A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0B650F2DCB40F4B77A470141 /* Pods-JVFloatingDrawerTests.debug.xcconfig */; + baseConfigurationReference = 6CF63AE0A8156781502C18BF /* Pods-JVFloatingDrawerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( @@ -518,7 +553,7 @@ }; 2CE7E6851A62D8480072121A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 43B9557D1EFD5CCA2211B8B7 /* Pods-JVFloatingDrawerTests.release.xcconfig */; + baseConfigurationReference = EB2A8D44D8C10B1140C6F703 /* Pods-JVFloatingDrawerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( diff --git a/Example/JVFloatingDrawer/JVDrawerSettingsTableViewController.m b/Example/JVFloatingDrawer/JVDrawerSettingsTableViewController.m index b856571..4de9742 100644 --- a/Example/JVFloatingDrawer/JVDrawerSettingsTableViewController.m +++ b/Example/JVFloatingDrawer/JVDrawerSettingsTableViewController.m @@ -10,7 +10,7 @@ #import "JVFloatingDrawerSpringAnimator.h" #import "AppDelegate.h" -@interface JVDrawerSettingsTableViewController () +@interface JVDrawerSettingsTableViewController () @property (nonatomic, strong, readonly) JVFloatingDrawerSpringAnimator *drawerAnimator; @@ -95,4 +95,10 @@ - (void)didReceiveMemoryWarning { // Dispose of any resources that can be recreated. } +#pragma mark - JVFloatingDrawerCenterViewController + +- (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide { + return YES; +} + @end diff --git a/Example/JVFloatingDrawer/JVGitHubViewController.m b/Example/JVFloatingDrawer/JVGitHubViewController.m index 7575944..c33a8b5 100644 --- a/Example/JVFloatingDrawer/JVGitHubViewController.m +++ b/Example/JVFloatingDrawer/JVGitHubViewController.m @@ -8,10 +8,12 @@ #import "JVGitHubViewController.h" #import "AppDelegate.h" +#import "JVFloatingDrawerViewController.h" + static NSString * const kJVGithubProjectPage = @"http://github.com/JVillella/JVFloatingDrawer"; -@interface JVGitHubViewController () +@interface JVGitHubViewController () @property (weak, nonatomic) IBOutlet UIWebView *webview; @@ -40,4 +42,10 @@ - (IBAction)actionToggleRightDrawer:(id)sender { [[AppDelegate globalDelegate] toggleRightDrawer:self animated:YES]; } +#pragma mark - JVFloatingDrawerCenterViewController + +- (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide { + return YES; +} + @end diff --git a/Example/JVFloatingDrawer/JVLeftDrawerTableViewCell.m b/Example/JVFloatingDrawer/JVLeftDrawerTableViewCell.m index 72f1ea4..440d2c1 100644 --- a/Example/JVFloatingDrawer/JVLeftDrawerTableViewCell.m +++ b/Example/JVFloatingDrawer/JVLeftDrawerTableViewCell.m @@ -18,6 +18,7 @@ @interface JVLeftDrawerTableViewCell () @implementation JVLeftDrawerTableViewCell - (void)awakeFromNib { + [super awakeFromNib]; self.selectionStyle = UITableViewCellSelectionStyleNone; self.backgroundColor = [UIColor clearColor]; } diff --git a/Example/Podfile b/Example/Podfile index aa28bbf..03047c6 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -1,10 +1,10 @@ source 'https://github.com/CocoaPods/Specs.git' -target 'JVFloatingDrawer', :exclusive => true do +target 'JVFloatingDrawer' do pod "JVFloatingDrawer", :path => "../" end -target 'JVFloatingDrawerTests', :exclusive => true do +target 'JVFloatingDrawerTests' do pod "JVFloatingDrawer", :path => "../" end diff --git a/Example/Podfile.lock b/Example/Podfile.lock index e105ca4..fb4e6eb 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -6,9 +6,11 @@ DEPENDENCIES: EXTERNAL SOURCES: JVFloatingDrawer: - :path: "../" + :path: ../ SPEC CHECKSUMS: JVFloatingDrawer: 4782b1df21411aef2c1818f3b346cace02cc2e24 -COCOAPODS: 0.37.2 +PODFILE CHECKSUM: f05e356e11bb0527b08f50ec30940e20a7f1673c + +COCOAPODS: 1.1.1 diff --git a/Pod/Classes/JVFloatingDrawerAnimation.h b/Pod/Classes/JVFloatingDrawerAnimation.h index 4631efb..aed0461 100644 --- a/Pod/Classes/JVFloatingDrawerAnimation.h +++ b/Pod/Classes/JVFloatingDrawerAnimation.h @@ -57,6 +57,23 @@ */ - (void)didRotateOpenDrawerWithOpenSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView; +/** + * Implementations should move the side view and the center view. + * + * @param trans The point that your finger points to + * @param sideView The view of the side of the drawer to be presented + * @param centerView The center view + */ +@optional +- (void)moveWithTranslation:(CGPoint)trans + sideView:(UIView *)sideView + centerView:(UIView *)centerView; + +@optional +- (void)moveBackWithTranslation:(CGPoint)trans + sideView:(UIView *)sideView + centerView:(UIView *)centerView; + @end diff --git a/Pod/Classes/JVFloatingDrawerSpringAnimator.m b/Pod/Classes/JVFloatingDrawerSpringAnimator.m index 1fc61f5..0f57251 100644 --- a/Pod/Classes/JVFloatingDrawerSpringAnimator.m +++ b/Pod/Classes/JVFloatingDrawerSpringAnimator.m @@ -121,18 +121,19 @@ - (void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view { #pragma mark Transforms - (void)applyTransformsWithSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView { - CGFloat direction = drawerSide == JVFloatingDrawerSideLeft ? 1.0 : -1.0; - CGFloat sideWidth = sideView.bounds.size.width; - CGFloat centerWidth = centerView.bounds.size.width; - CGFloat centerViewHorizontalOffset = direction * sideWidth; - CGFloat scaledCenterViewHorizontalOffset = direction * (sideWidth - (centerWidth - kJVCenterViewDestinationScale * centerWidth) / 2.0); + CGFloat sideWidth = sideView.bounds.size.width; + CGFloat direction = (drawerSide == JVFloatingDrawerSideLeft) ? 1.0 : -1.0; - CGAffineTransform sideTranslate = CGAffineTransformMakeTranslation(centerViewHorizontalOffset, 0.0); - sideView.transform = sideTranslate; + CGFloat sideViewHorizontalOffset = direction * sideWidth; + CGFloat centerScaleValue = kJVCenterViewDestinationScale; + + CGFloat scaledCenterViewHorizontalOffset = sideViewHorizontalOffset - direction * (sideWidth * (1 - centerScaleValue)); + CGAffineTransform sideTranslate = CGAffineTransformMakeTranslation(sideViewHorizontalOffset, 0.0); + sideView.transform = sideTranslate; + CGAffineTransform centerScale = CGAffineTransformMakeScale(centerScaleValue, centerScaleValue); CGAffineTransform centerTranslate = CGAffineTransformMakeTranslation(scaledCenterViewHorizontalOffset, 0.0); - CGAffineTransform centerScale = CGAffineTransformMakeScale(kJVCenterViewDestinationScale, kJVCenterViewDestinationScale); centerView.transform = CGAffineTransformConcat(centerScale, centerTranslate); } @@ -141,4 +142,53 @@ - (void)removeTransformsWithSide:(JVFloatingDrawerSide)drawerSide sideView:(UIVi centerView.transform = CGAffineTransformIdentity; } +- (void)moveBackWithTranslation:(CGPoint)trans sideView:(UIView *)sideView centerView:(UIView *)centerView { + CGFloat transX = trans.x; + CGFloat transWidth = fabs(transX); + BOOL toLeft = (transX >= 0.0); + + CGFloat sideWidth = sideView.bounds.size.width; + + CGFloat direction = toLeft ? 1.0 : -1.0; + CGFloat ratio = (transWidth / sideWidth); + + if (ratio > 1.0) return; + + CGFloat sideViewHorizontalOffset = direction * (transWidth - sideWidth); + CGFloat centerScaleValue = kJVCenterViewDestinationScale + (1.0 - kJVCenterViewDestinationScale) * ratio; + + CGFloat scaledCenterViewHorizontalOffset = sideViewHorizontalOffset * centerScaleValue; + + CGAffineTransform sideTranslate = CGAffineTransformMakeTranslation(sideViewHorizontalOffset, 0.0); + sideView.transform = sideTranslate; + + CGAffineTransform centerScale = CGAffineTransformMakeScale(centerScaleValue, centerScaleValue); + CGAffineTransform centerTranslate = CGAffineTransformMakeTranslation(scaledCenterViewHorizontalOffset, 0.0); + centerView.transform = CGAffineTransformConcat(centerScale, centerTranslate); +} + +- (void)moveWithTranslation:(CGPoint)trans sideView:(UIView *)sideView centerView:(UIView *)centerView { + CGFloat transX = trans.x; + CGFloat transWidth = fabs(transX); + BOOL toLeft = (transX >= 0.0); + + CGFloat sideWidth = sideView.bounds.size.width; + CGFloat direction = toLeft ? 1.0 : -1.0; + CGFloat ratio = (transWidth / sideWidth); + + if (ratio > 1.0) return; + + CGFloat sideViewHorizontalOffset = direction * transWidth; + CGFloat centerScaleValue = 1.0 - (1.0 - kJVCenterViewDestinationScale) * ratio; + + CGFloat scaledCenterViewHorizontalOffset = sideViewHorizontalOffset - direction * (transWidth * (1 - centerScaleValue)); + + CGAffineTransform sideTranslate = CGAffineTransformMakeTranslation(sideViewHorizontalOffset, 0.0); + sideView.transform = sideTranslate; + + CGAffineTransform centerScale = CGAffineTransformMakeScale(centerScaleValue, centerScaleValue); + CGAffineTransform centerTranslate = CGAffineTransformMakeTranslation(scaledCenterViewHorizontalOffset, 0.0); + centerView.transform = CGAffineTransformConcat(centerScale, centerTranslate); +} + @end diff --git a/Pod/Classes/JVFloatingDrawerView.m b/Pod/Classes/JVFloatingDrawerView.m index 8dc15d1..2d89240 100644 --- a/Pod/Classes/JVFloatingDrawerView.m +++ b/Pod/Classes/JVFloatingDrawerView.m @@ -8,7 +8,7 @@ #import "JVFloatingDrawerView.h" -static const CGFloat kJVCenterViewContainerCornerRadius = 5.0; +static const CGFloat kJVCenterViewContainerCornerRadius = 6.0; static const CGFloat kJVDefaultViewContainerWidth = 280.0; @interface JVFloatingDrawerView () diff --git a/Pod/Classes/JVFloatingDrawerViewController.h b/Pod/Classes/JVFloatingDrawerViewController.h index b247b79..1509950 100644 --- a/Pod/Classes/JVFloatingDrawerViewController.h +++ b/Pod/Classes/JVFloatingDrawerViewController.h @@ -16,6 +16,12 @@ typedef NS_ENUM(NSInteger, JVFloatingDrawerSide) { JVFloatingDrawerSideRight }; +@protocol JVFloatingDrawerCenterViewController +@optional +- (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide; + +@end + @interface JVFloatingDrawerViewController : UIViewController #pragma mark - Managed View Controllers @@ -50,4 +56,9 @@ typedef NS_ENUM(NSInteger, JVFloatingDrawerSide) { @property (nonatomic, strong) UIImage *backgroundImage; +#pragma mark - Pan Gesture + +@property (nonatomic, assign) CGFloat minimumDragDistance; +@property (nonatomic, assign) CGFloat dragRespondingWidth; + @end diff --git a/Pod/Classes/JVFloatingDrawerViewController.m b/Pod/Classes/JVFloatingDrawerViewController.m index ba704fa..6627ac0 100644 --- a/Pod/Classes/JVFloatingDrawerViewController.m +++ b/Pod/Classes/JVFloatingDrawerViewController.m @@ -14,20 +14,22 @@ const char* c_str = 0; #define PROCESS_VAL(p) case(p): c_str = #p; break; switch(side) { - PROCESS_VAL(JVFloatingDrawerSideNone); - PROCESS_VAL(JVFloatingDrawerSideLeft); - PROCESS_VAL(JVFloatingDrawerSideRight); + PROCESS_VAL(JVFloatingDrawerSideNone); + PROCESS_VAL(JVFloatingDrawerSideLeft); + PROCESS_VAL(JVFloatingDrawerSideRight); } #undef PROCESS_VAL return [NSString stringWithCString:c_str encoding:NSASCIIStringEncoding]; } -@interface JVFloatingDrawerViewController () +@interface JVFloatingDrawerViewController () @property (nonatomic, strong, readonly) JVFloatingDrawerView *drawerView; @property (nonatomic, assign) JVFloatingDrawerSide currentlyOpenedSide; @property (nonatomic, strong) UITapGestureRecognizer *toggleDrawerTapGestureRecognizer; +@property (nonatomic, strong) UIPanGestureRecognizer *toggleDrawerPanGestureRecognizer; +@property (nonatomic, strong) UIPanGestureRecognizer *toggleDrawerPanBackGestureRecognizer; @end @@ -37,7 +39,7 @@ @implementation JVFloatingDrawerViewController - (instancetype)init { self = [super init]; - if(self) { + if (self) { [self setup]; } return self; @@ -45,6 +47,9 @@ - (instancetype)init { - (void)setup { self.currentlyOpenedSide = JVFloatingDrawerSideNone; + self.dragToRevealEnabled = YES; + self.minimumDragDistance = 80.0; + self.dragRespondingWidth = 80.0; } #pragma mark - View Related @@ -69,12 +74,12 @@ - (JVFloatingDrawerView *)drawerView { #pragma mark - Interaction - (void)openDrawerWithSide:(JVFloatingDrawerSide)drawerSide animated:(BOOL)animated completion:(void(^)(BOOL finished))completion { - if(self.currentlyOpenedSide != drawerSide) { + if (self.currentlyOpenedSide != drawerSide) { UIView *sideView = [self.drawerView viewContainerForDrawerSide:drawerSide]; UIView *centerView = self.drawerView.centerViewContainer; // First close opened drawer and then open new drawer - if(self.currentlyOpenedSide != JVFloatingDrawerSideNone) { + if (self.currentlyOpenedSide != JVFloatingDrawerSideNone) { [self closeDrawerWithSide:self.currentlyOpenedSide animated:animated completion:^(BOOL finished) { [self.animator presentationWithSide:drawerSide sideView:sideView centerView:centerView animated:animated completion:completion]; }]; @@ -90,7 +95,7 @@ - (void)openDrawerWithSide:(JVFloatingDrawerSide)drawerSide animated:(BOOL)anima } - (void)closeDrawerWithSide:(JVFloatingDrawerSide)drawerSide animated:(BOOL)animated completion:(void(^)(BOOL finished))completion { - if(self.currentlyOpenedSide == drawerSide && self.currentlyOpenedSide != JVFloatingDrawerSideNone) { + if (self.currentlyOpenedSide == drawerSide && self.currentlyOpenedSide != JVFloatingDrawerSideNone) { UIView *sideView = [self.drawerView viewContainerForDrawerSide:drawerSide]; UIView *centerView = self.drawerView.centerViewContainer; @@ -104,9 +109,21 @@ - (void)closeDrawerWithSide:(JVFloatingDrawerSide)drawerSide animated:(BOOL)anim } } +- (void)moveCenterViewWithSide:(JVFloatingDrawerSide)drawerSide translation:(CGPoint)translation { + UIView *sideView = [self.drawerView viewContainerForDrawerSide:drawerSide]; + UIView *centerView = self.drawerView.centerViewContainer; + [self.animator moveWithTranslation:translation sideView:sideView centerView:centerView]; +} + +- (void)moveBackCenterViewWithSide:(JVFloatingDrawerSide)drawerSide translation:(CGPoint)translation { + UIView *sideView = [self.drawerView viewContainerForDrawerSide:drawerSide]; + UIView *centerView = self.drawerView.centerViewContainer; + [self.animator moveBackWithTranslation:translation sideView:sideView centerView:centerView]; +} + - (void)toggleDrawerWithSide:(JVFloatingDrawerSide)drawerSide animated:(BOOL)animated completion:(void(^)(BOOL finished))completion { - if(drawerSide != JVFloatingDrawerSideNone) { - if(drawerSide == self.currentlyOpenedSide) { + if (drawerSide != JVFloatingDrawerSideNone) { + if (drawerSide == self.currentlyOpenedSide) { [self closeDrawerWithSide:drawerSide animated:animated completion:completion]; } else { [self openDrawerWithSide:drawerSide animated:animated completion:completion]; @@ -116,20 +133,181 @@ - (void)toggleDrawerWithSide:(JVFloatingDrawerSide)drawerSide animated:(BOOL)ani #pragma mark - Gestures +- (void)removeOldGestures { + if (self.toggleDrawerPanGestureRecognizer != nil) { + UINavigationController *navc = ((UINavigationController *)_centerViewController); + [navc.topViewController.view removeGestureRecognizer:self.toggleDrawerPanGestureRecognizer]; + self.toggleDrawerPanGestureRecognizer = nil; + } + if (self.toggleDrawerTapGestureRecognizer != nil) { + [self.drawerView.centerViewContainer removeGestureRecognizer:self.toggleDrawerTapGestureRecognizer]; + self.toggleDrawerTapGestureRecognizer = nil; + } + if (self.toggleDrawerPanBackGestureRecognizer != nil) { + [self.drawerView.centerViewContainer removeGestureRecognizer:self.toggleDrawerPanBackGestureRecognizer]; + self.toggleDrawerPanBackGestureRecognizer = nil; + } +} + - (void)addDrawerGestures { self.centerViewController.view.userInteractionEnabled = NO; - self.toggleDrawerTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(actionCenterViewContainerTapped:)]; + [self removeOldGestures]; + if (self.dragToRevealEnabled) { + self.toggleDrawerPanBackGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self + action:@selector(actionCenterViewContainerPanned:)]; + self.toggleDrawerPanBackGestureRecognizer.delegate = self; + [self.drawerView.centerViewContainer addGestureRecognizer:self.toggleDrawerPanBackGestureRecognizer]; + } + self.toggleDrawerTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self + action:@selector(actionCenterViewContainerTapped:)]; [self.drawerView.centerViewContainer addGestureRecognizer:self.toggleDrawerTapGestureRecognizer]; } - (void)restoreGestures { - [self.drawerView.centerViewContainer removeGestureRecognizer:self.toggleDrawerTapGestureRecognizer]; - self.toggleDrawerTapGestureRecognizer = nil; - self.centerViewController.view.userInteractionEnabled = YES; + [self removeOldGestures]; + if (self.dragToRevealEnabled && [_centerViewController isKindOfClass:[UINavigationController class]]) { + self.toggleDrawerPanGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(actionCenterViewContainerPanned:)]; + self.toggleDrawerPanGestureRecognizer.delegate = self; + UINavigationController *navc = ((UINavigationController *)_centerViewController); + [navc.topViewController.view addGestureRecognizer:self.toggleDrawerPanGestureRecognizer]; + } + self.centerViewController.view.userInteractionEnabled = YES; } -- (void)actionCenterViewContainerTapped:(id)sender { - [self closeDrawerWithSide:self.currentlyOpenedSide animated:YES completion:nil]; +- (void)actionCenterViewContainerTapped:(UITapGestureRecognizer *)gesture { + if (gesture == self.toggleDrawerTapGestureRecognizer) { + [self closeDrawerWithSide:self.currentlyOpenedSide animated:YES completion:nil]; + } +} + +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { + if (gestureRecognizer == self.toggleDrawerPanGestureRecognizer) { + UIView *centerView = self.drawerView.centerViewContainer; + CGPoint where = [gestureRecognizer locationInView:centerView]; + UINavigationController *navc = ((UINavigationController *)_centerViewController); + UIViewController *topViewController = ((UIViewController *)navc.topViewController); + if ([topViewController respondsToSelector:@selector(shouldOpenDrawerWithSide:)]) { + if ( + (where.x < self.dragRespondingWidth && + [topViewController shouldOpenDrawerWithSide:JVFloatingDrawerSideLeft] + ) || + (where.x > (centerView.bounds.size.width - self.dragRespondingWidth) && + [topViewController shouldOpenDrawerWithSide:JVFloatingDrawerSideRight] + ) + ) { + return YES; + } + } + return NO; + } else if (gestureRecognizer == self.toggleDrawerPanBackGestureRecognizer) { + return YES; + } + return NO; +} + +static BOOL canMove = NO; +- (void)actionCenterViewContainerPanned:(UIPanGestureRecognizer *)gesture { + CGPoint trans = [gesture translationInView:self.view]; + CGFloat transX = trans.x; + CGFloat transY = trans.y; + CGFloat transWidth = fabs(transX); + BOOL toLeft = (transX >= 0.0); + if (gesture == self.toggleDrawerPanGestureRecognizer) { + if (gesture.state == UIGestureRecognizerStateBegan) { + canMove = (transY < 16.0); + [self.drawerView willOpenFloatingDrawerViewController:self]; + } else if (gesture.state == UIGestureRecognizerStateChanged) { + if (!canMove) { + return; + } + if (toLeft) { + [self moveCenterViewWithSide:JVFloatingDrawerSideLeft translation:trans]; + } else { + [self moveCenterViewWithSide:JVFloatingDrawerSideRight translation:trans]; + } + } else if (gesture.state == UIGestureRecognizerStateEnded) { + if (!canMove) { + return; + } + BOOL canOpen = YES; + UIView *sideView = [self.drawerView viewContainerForDrawerSide:self.currentlyOpenedSide]; + UIView *centerView = self.drawerView.centerViewContainer; + UINavigationController *navc = ((UINavigationController *)_centerViewController); + UIViewController *topViewController = ((UIViewController *)navc.topViewController); + if (toLeft) { + if (( + [topViewController respondsToSelector:@selector(shouldOpenDrawerWithSide:)] + && ![topViewController shouldOpenDrawerWithSide:JVFloatingDrawerSideLeft] + ) + || transWidth <= self.minimumDragDistance) { + canOpen = NO; + } + if (canOpen) { + [self openDrawerWithSide:JVFloatingDrawerSideLeft animated:YES completion:nil]; + } else { + [self.animator dismissWithSide:JVFloatingDrawerSideLeft sideView:sideView centerView:centerView animated:YES completion:nil]; + [self.drawerView willCloseFloatingDrawerViewController:self]; + } + } else { + if (( + [topViewController respondsToSelector:@selector(shouldOpenDrawerWithSide:)] + && ![topViewController shouldOpenDrawerWithSide:JVFloatingDrawerSideRight] + ) + || transWidth <= self.minimumDragDistance) { + canOpen = NO; + } + if (canOpen) { + [self openDrawerWithSide:JVFloatingDrawerSideRight animated:YES completion:nil]; + } else { + [self.animator dismissWithSide:JVFloatingDrawerSideRight sideView:sideView centerView:centerView animated:YES completion:nil]; + [self.drawerView willCloseFloatingDrawerViewController:self]; + } + } + } + } else if (gesture == self.toggleDrawerPanBackGestureRecognizer) { + if (gesture.state == UIGestureRecognizerStateBegan) { + canMove = (transY < 64.0); + } else if (gesture.state == UIGestureRecognizerStateChanged) { + if (!canMove) { + return; + } + if (!toLeft && self.currentlyOpenedSide == JVFloatingDrawerSideLeft) { + [self moveBackCenterViewWithSide:JVFloatingDrawerSideLeft translation:trans]; + } else if (toLeft && self.currentlyOpenedSide == JVFloatingDrawerSideRight) { + [self moveBackCenterViewWithSide:JVFloatingDrawerSideRight translation:trans]; + } + } else if ( + gesture.state == UIGestureRecognizerStateEnded || + gesture.state == UIGestureRecognizerStateCancelled || + gesture.state == UIGestureRecognizerStateFailed + ) { + if (!canMove) { + return; + } + BOOL canClose = YES; + UIView *sideView = [self.drawerView viewContainerForDrawerSide:self.currentlyOpenedSide]; + UIView *centerView = self.drawerView.centerViewContainer; + if (toLeft && self.currentlyOpenedSide == JVFloatingDrawerSideRight) { + if (transWidth <= self.minimumDragDistance) { + canClose = NO; + } + if (canClose) { + [self closeDrawerWithSide:JVFloatingDrawerSideRight animated:YES completion:nil]; + } else { + [self.animator presentationWithSide:JVFloatingDrawerSideRight sideView:sideView centerView:centerView animated:YES completion:nil]; + } + } else if (!toLeft && self.currentlyOpenedSide == JVFloatingDrawerSideLeft) { + if (transWidth <= self.minimumDragDistance) { + canClose = NO; + } + if (canClose) { + [self closeDrawerWithSide:JVFloatingDrawerSideLeft animated:YES completion:nil]; + } else { + [self.animator presentationWithSide:JVFloatingDrawerSideLeft sideView:sideView centerView:centerView animated:YES completion:nil]; + } + } + } + } } #pragma mark - Managed View Controllers @@ -153,10 +331,12 @@ - (void)setCenterViewController:(UIViewController *)centerViewController { container:self.drawerView.centerViewContainer]; _centerViewController = centerViewController; + [self.drawerView willCloseFloatingDrawerViewController:self]; + [self restoreGestures]; } - (void)replaceViewController:(UIViewController *)sourceViewController withViewController:(UIViewController *)destinationViewController container:(UIView *)container { - + [sourceViewController willMoveToParentViewController:nil]; [sourceViewController.view removeFromSuperview]; [sourceViewController removeFromParentViewController]; @@ -164,14 +344,14 @@ - (void)replaceViewController:(UIViewController *)sourceViewController withViewC if (destinationViewController) { [self addChildViewController:destinationViewController]; [container addSubview:destinationViewController.view]; - + UIView *destinationView = destinationViewController.view; destinationView.translatesAutoresizingMaskIntoConstraints = NO; - + NSDictionary *views = NSDictionaryOfVariableBindings(destinationView); [container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[destinationView]|" options:0 metrics:nil views:views]]; [container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[destinationView]|" options:0 metrics:nil views:views]]; - + [destinationViewController didMoveToParentViewController:self]; } } @@ -211,7 +391,8 @@ - (UIViewController *)viewControllerForDrawerSide:(JVFloatingDrawerSide)drawerSi switch (drawerSide) { case JVFloatingDrawerSideLeft: sideViewController = self.leftViewController; break; case JVFloatingDrawerSideRight: sideViewController = self.rightViewController; break; - case JVFloatingDrawerSideNone: sideViewController = nil; break; + case JVFloatingDrawerSideNone: + sideViewController = nil; break; } return sideViewController; } @@ -222,7 +403,7 @@ - (BOOL)shouldAutorotate { return [self.centerViewController shouldAutorotate]; } -- (NSUInteger)supportedInterfaceOrientations { +- (UIInterfaceOrientationMask)supportedInterfaceOrientations { return [self.centerViewController supportedInterfaceOrientations];; } @@ -231,7 +412,7 @@ - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { } - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - if(self.currentlyOpenedSide != JVFloatingDrawerSideNone) { + if (self.currentlyOpenedSide != JVFloatingDrawerSideNone) { UIView *sideView = [self.drawerView viewContainerForDrawerSide:self.currentlyOpenedSide]; UIView *centerView = self.drawerView.centerViewContainer; @@ -242,7 +423,7 @@ - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrie } - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { - if(self.currentlyOpenedSide != JVFloatingDrawerSideNone) { + if (self.currentlyOpenedSide != JVFloatingDrawerSideNone) { UIView *sideView = [self.drawerView viewContainerForDrawerSide:self.currentlyOpenedSide]; UIView *centerView = self.drawerView.centerViewContainer; From 3133fd427b71bfe71e85526f67375afcb229addf Mon Sep 17 00:00:00 2001 From: i_82 Date: Fri, 7 Apr 2017 11:48:22 +0200 Subject: [PATCH 2/6] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index d4fb7e3..6057fc6 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,12 @@ You can also customize the `leftDrawerWidth` and `rightDrawerWidth` by setting t The background image is set by assigning the `backgroundImage` property. +#### `JVFloatingDrawerCenterViewController` + +The `JVFloatingDrawerCenterViewController` is a protocol that allows each ViewController in the Drawer to decides their own behaviour. + + - (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide; + ##### Animators Animators are the main players of `JVFloatingDrawer`. `JVFloatingDrawer` comes with a prebuilt spring animator that can be customized by settings its `animationDuration`, `animationDelay`, `springDamping`, and `initialSpringVelocity`. After instantiating a new animator object you assign it to the `animator` property on the `JVFloatingDrawerViewController` to let it work its magic. You can make your own animators by implementing the `JVFloatingDrawerAnimation` protocol. More on that later. @@ -101,6 +107,8 @@ Dismissal is the exact same as presentation except it needs to be able to get th Julian Villella +i_82 \ + ## License JVFloatingDrawer is available under the MIT license. See the LICENSE file for more info. From 4b6fd89e4f70a0b92ebd1e96b01c8bd1db7ca39c Mon Sep 17 00:00:00 2001 From: Peter Carnesciali Date: Sun, 16 Jul 2017 17:50:28 -0500 Subject: [PATCH 3/6] Adds void type --- Pod/Classes/JVFloatingDrawerSpringAnimator.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Pod/Classes/JVFloatingDrawerSpringAnimator.m b/Pod/Classes/JVFloatingDrawerSpringAnimator.m index 0f57251..14593b3 100644 --- a/Pod/Classes/JVFloatingDrawerSpringAnimator.m +++ b/Pod/Classes/JVFloatingDrawerSpringAnimator.m @@ -35,7 +35,7 @@ - (void)setup { #pragma mark Presentation/Dismissal - (void)presentationWithSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView animated:(BOOL)animated completion:(void (^)(BOOL))completion { - void (^springAnimation)() = ^{ + void (^springAnimation)(void) = ^{ [self applyTransformsWithSide:drawerSide sideView:sideView centerView:centerView]; }; @@ -53,7 +53,7 @@ - (void)presentationWithSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView * } - (void)dismissWithSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView animated:(BOOL)animated completion:(void (^)(BOOL))completion { - void (^springAnimation)() = ^{ + void (^springAnimation)(void) = ^{ [self removeTransformsWithSide:drawerSide sideView:sideView centerView:centerView]; }; @@ -74,7 +74,7 @@ - (void)dismissWithSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)side - (void)willRotateOpenDrawerWithOpenSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView {} - (void)didRotateOpenDrawerWithOpenSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView { - void (^springAnimation)() = ^{ + void (^springAnimation)(void) = ^{ [self applyTransformsWithSide:drawerSide sideView:sideView centerView:centerView]; }; From 315a37ba383c1846511b19d84fec2fd739873a33 Mon Sep 17 00:00:00 2001 From: i_82 Date: Thu, 12 Oct 2017 20:53:34 -0500 Subject: [PATCH 4/6] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6057fc6..b8eb6c7 100644 --- a/README.md +++ b/README.md @@ -65,15 +65,15 @@ You can also customize the `leftDrawerWidth` and `rightDrawerWidth` by setting t The background image is set by assigning the `backgroundImage` property. -#### `JVFloatingDrawerCenterViewController` +##### Animators -The `JVFloatingDrawerCenterViewController` is a protocol that allows each ViewController in the Drawer to decides their own behaviour. +Animators are the main players of `JVFloatingDrawer`. `JVFloatingDrawer` comes with a prebuilt spring animator that can be customized by settings its `animationDuration`, `animationDelay`, `springDamping`, and `initialSpringVelocity`. After instantiating a new animator object you assign it to the `animator` property on the `JVFloatingDrawerViewController` to let it work its magic. You can make your own animators by implementing the `JVFloatingDrawerAnimation` protocol. More on that later. - - (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide; +#### `JVFloatingDrawerCenterViewController` -##### Animators +The `JVFloatingDrawerCenterViewController` is a protocol that allows each ViewController in the Drawer to decides their own gesture behaviour. -Animators are the main players of `JVFloatingDrawer`. `JVFloatingDrawer` comes with a prebuilt spring animator that can be customized by settings its `animationDuration`, `animationDelay`, `springDamping`, and `initialSpringVelocity`. After instantiating a new animator object you assign it to the `animator` property on the `JVFloatingDrawerViewController` to let it work its magic. You can make your own animators by implementing the `JVFloatingDrawerAnimation` protocol. More on that later. + - (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide; #### `JVFloatingDrawerView` From fb9dcfb6554e47309c56db3da40cfced176b3d7f Mon Sep 17 00:00:00 2001 From: Lessica Date: Fri, 13 Oct 2017 10:02:00 +0800 Subject: [PATCH 5/6] Update gesture delegate name --- Example/JVFloatingDrawer.xcodeproj/project.pbxproj | 10 ++++++++-- .../JVDrawerSettingsTableViewController.m | 4 ++-- Example/JVFloatingDrawer/JVGitHubViewController.m | 4 ++-- Example/Podfile.lock | 2 +- Pod/Classes/JVFloatingDrawerViewController.h | 2 +- Pod/Classes/JVFloatingDrawerViewController.m | 4 ++-- README.md | 4 ++-- 7 files changed, 18 insertions(+), 12 deletions(-) diff --git a/Example/JVFloatingDrawer.xcodeproj/project.pbxproj b/Example/JVFloatingDrawer.xcodeproj/project.pbxproj index 37d5607..0b46692 100644 --- a/Example/JVFloatingDrawer.xcodeproj/project.pbxproj +++ b/Example/JVFloatingDrawer.xcodeproj/project.pbxproj @@ -319,13 +319,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-JVFloatingDrawerTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 296EB02D24C4CF53DECB78EC /* [CP] Check Pods Manifest.lock */ = { @@ -334,13 +337,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-JVFloatingDrawer-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; C82DA6685D240A17CAF976DE /* [CP] Copy Pods Resources */ = { diff --git a/Example/JVFloatingDrawer/JVDrawerSettingsTableViewController.m b/Example/JVFloatingDrawer/JVDrawerSettingsTableViewController.m index 4de9742..6124511 100644 --- a/Example/JVFloatingDrawer/JVDrawerSettingsTableViewController.m +++ b/Example/JVFloatingDrawer/JVDrawerSettingsTableViewController.m @@ -10,7 +10,7 @@ #import "JVFloatingDrawerSpringAnimator.h" #import "AppDelegate.h" -@interface JVDrawerSettingsTableViewController () +@interface JVDrawerSettingsTableViewController () @property (nonatomic, strong, readonly) JVFloatingDrawerSpringAnimator *drawerAnimator; @@ -95,7 +95,7 @@ - (void)didReceiveMemoryWarning { // Dispose of any resources that can be recreated. } -#pragma mark - JVFloatingDrawerCenterViewController +#pragma mark - JVFloatingDrawerPanGestureDelegate - (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide { return YES; diff --git a/Example/JVFloatingDrawer/JVGitHubViewController.m b/Example/JVFloatingDrawer/JVGitHubViewController.m index c33a8b5..783d825 100644 --- a/Example/JVFloatingDrawer/JVGitHubViewController.m +++ b/Example/JVFloatingDrawer/JVGitHubViewController.m @@ -13,7 +13,7 @@ static NSString * const kJVGithubProjectPage = @"http://github.com/JVillella/JVFloatingDrawer"; -@interface JVGitHubViewController () +@interface JVGitHubViewController () @property (weak, nonatomic) IBOutlet UIWebView *webview; @@ -42,7 +42,7 @@ - (IBAction)actionToggleRightDrawer:(id)sender { [[AppDelegate globalDelegate] toggleRightDrawer:self animated:YES]; } -#pragma mark - JVFloatingDrawerCenterViewController +#pragma mark - JVFloatingDrawerPanGestureDelegate - (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide { return YES; diff --git a/Example/Podfile.lock b/Example/Podfile.lock index fb4e6eb..4a808cb 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -13,4 +13,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: f05e356e11bb0527b08f50ec30940e20a7f1673c -COCOAPODS: 1.1.1 +COCOAPODS: 1.3.1 diff --git a/Pod/Classes/JVFloatingDrawerViewController.h b/Pod/Classes/JVFloatingDrawerViewController.h index 1509950..89c0a5d 100644 --- a/Pod/Classes/JVFloatingDrawerViewController.h +++ b/Pod/Classes/JVFloatingDrawerViewController.h @@ -16,7 +16,7 @@ typedef NS_ENUM(NSInteger, JVFloatingDrawerSide) { JVFloatingDrawerSideRight }; -@protocol JVFloatingDrawerCenterViewController +@protocol JVFloatingDrawerPanGestureDelegate @optional - (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide; diff --git a/Pod/Classes/JVFloatingDrawerViewController.m b/Pod/Classes/JVFloatingDrawerViewController.m index 6627ac0..584a480 100644 --- a/Pod/Classes/JVFloatingDrawerViewController.m +++ b/Pod/Classes/JVFloatingDrawerViewController.m @@ -185,7 +185,7 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { UIView *centerView = self.drawerView.centerViewContainer; CGPoint where = [gestureRecognizer locationInView:centerView]; UINavigationController *navc = ((UINavigationController *)_centerViewController); - UIViewController *topViewController = ((UIViewController *)navc.topViewController); + UIViewController *topViewController = ((UIViewController *)navc.topViewController); if ([topViewController respondsToSelector:@selector(shouldOpenDrawerWithSide:)]) { if ( (where.x < self.dragRespondingWidth && @@ -233,7 +233,7 @@ - (void)actionCenterViewContainerPanned:(UIPanGestureRecognizer *)gesture { UIView *sideView = [self.drawerView viewContainerForDrawerSide:self.currentlyOpenedSide]; UIView *centerView = self.drawerView.centerViewContainer; UINavigationController *navc = ((UINavigationController *)_centerViewController); - UIViewController *topViewController = ((UIViewController *)navc.topViewController); + UIViewController *topViewController = ((UIViewController *)navc.topViewController); if (toLeft) { if (( [topViewController respondsToSelector:@selector(shouldOpenDrawerWithSide:)] diff --git a/README.md b/README.md index b8eb6c7..ddbdea3 100644 --- a/README.md +++ b/README.md @@ -69,9 +69,9 @@ The background image is set by assigning the `backgroundImage` property. Animators are the main players of `JVFloatingDrawer`. `JVFloatingDrawer` comes with a prebuilt spring animator that can be customized by settings its `animationDuration`, `animationDelay`, `springDamping`, and `initialSpringVelocity`. After instantiating a new animator object you assign it to the `animator` property on the `JVFloatingDrawerViewController` to let it work its magic. You can make your own animators by implementing the `JVFloatingDrawerAnimation` protocol. More on that later. -#### `JVFloatingDrawerCenterViewController` +#### `JVFloatingDrawerPanGestureDelegate` -The `JVFloatingDrawerCenterViewController` is a protocol that allows each ViewController in the Drawer to decides their own gesture behaviour. +The `JVFloatingDrawerPanGestureDelegate` is a protocol that allows each ViewController in the Drawer to decides their own gesture behaviour. - (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide; From 0eb478b81f2499e94bf1607f690f544ce864af0e Mon Sep 17 00:00:00 2001 From: i_82 Date: Thu, 12 Oct 2017 21:06:38 -0500 Subject: [PATCH 6/6] Update README.md --- README.md | 66 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index ddbdea3..643c655 100644 --- a/README.md +++ b/README.md @@ -7,25 +7,29 @@ [![License](https://img.shields.io/cocoapods/l/JVFloatingDrawer.svg?style=flat)](http://cocoadocs.org/docsets/JVFloatingDrawer) [![Platform](https://img.shields.io/cocoapods/p/JVFloatingDrawer.svg?style=flat)](http://cocoadocs.org/docsets/JVFloatingDrawer) -JVFloatingDrawer is a floating style drawer navigation. There is a growing number of applications leveraging the drawer pattern. Most share a similar look and feel. With JVFloatingDrawer we aimed to bring a facelift to the conventional setup. +**JVFloatingDrawer** is a floating style drawer navigation. There is a growing number of applications leveraging the drawer pattern. Most share a similar look and feel. With JVFloatingDrawer we aimed to bring a facelift to the conventional setup. ![Opening Drawer Animation](http://jvillella.github.io/JVFloatingDrawer/Screenshots/animated-drawer-open-portrait.gif "Opening Drawer") +**JVFloatingDrawer** now supports pan gesture to activate/deactivate drawer, see *JVFloatingDrawerPanGestureDelegate* for more details. + ## Usage JVFloatingDrawer is very easy to use. Below is all that is needed to get going. - - JVFloatingDrawerViewController *drawerViewController = [[JVFloatingDrawerViewController alloc] init]; - - // Assign to your own view controllers - drawerViewController.leftViewController = leftDrawerViewController; - drawerViewController.rightViewController = rightDrawerViewController; - drawerViewController.centerViewController = centerViewController; - - self.drawerViewController.backgroundImage = [UIImage imageNamed:@"background-image-example.jpg"]; - - drawerViewController.animator = [[JVFloatingDrawerSpringAnimator alloc] init]; + +```objective-c +JVFloatingDrawerViewController *drawerViewController = [[JVFloatingDrawerViewController alloc] init]; + +// Assign to your own view controllers +drawerViewController.leftViewController = leftDrawerViewController; +drawerViewController.rightViewController = rightDrawerViewController; +drawerViewController.centerViewController = centerViewController; + +self.drawerViewController.backgroundImage = [UIImage imageNamed:@"background-image-example.jpg"]; + +drawerViewController.animator = [[JVFloatingDrawerSpringAnimator alloc] init]; +``` To see an example implementation of this run the example project. Clone the repo, run `pod install` from the Example directory, and open up `Example/JVFloatingDrawer.xcworkspace`. @@ -48,14 +52,16 @@ The `JVFloatingDrawerViewController` maintains references to a center, left, and `JVFloatingDrawerViewController` is where you open, close, and toggle your side drawers. - - (void)openDrawerWithSide:(JVFloatingDrawerSide)drawerSide animated:(BOOL)animated - completion:(void(^)(BOOL finished))completion; - - - (void)closeDrawerWithSide:(JVFloatingDrawerSide)drawerSide animated:(BOOL)animated - completion:(void(^)(BOOL finished))completion; - - - (void)toggleDrawerWithSide:(JVFloatingDrawerSide)drawerSide animated:(BOOL)animated - completion:(void(^)(BOOL finished))completion; +```objective-c +- (void)openDrawerWithSide:(JVFloatingDrawerSide)drawerSide animated:(BOOL)animated + completion:(void(^)(BOOL finished))completion; + +- (void)closeDrawerWithSide:(JVFloatingDrawerSide)drawerSide animated:(BOOL)animated + completion:(void(^)(BOOL finished))completion; + +- (void)toggleDrawerWithSide:(JVFloatingDrawerSide)drawerSide animated:(BOOL)animated + completion:(void(^)(BOOL finished))completion; +``` ##### Drawer Widths @@ -73,7 +79,9 @@ Animators are the main players of `JVFloatingDrawer`. `JVFloatingDrawer` comes w The `JVFloatingDrawerPanGestureDelegate` is a protocol that allows each ViewController in the Drawer to decides their own gesture behaviour. - - (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide; +```objective-c +- (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide; +``` #### `JVFloatingDrawerView` @@ -85,21 +93,29 @@ The `JVFloatingDrawerSpringAnimator` class is a featured animator for you to use #### Presentation -`- (void)presentationWithSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView animated:(BOOL)animated completion:(void(^)(BOOL finished))completion` +```objective-c +- (void)presentationWithSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView animated:(BOOL)animated completion:(void(^)(BOOL finished))completion +``` Given a drawer side, the containing side view, and the containing center view, implementations must bring the side view on screen. If the `drawerSide` is equal to `JVFloatingDrawerSideLeft` the view will be *left-adjacent* to the `centerView`. If the `drawerSide` is equal to `JVFloatingDrawerSideRight` the view will be *right-adjacent* to the `centerView`. You have complete control over how you do this. I used view transforms in my implementation and called `UIView`'s `-animateWithDuration:delay:usingSpringWithDamping:...`. Technically, you don't even have to make it floating. You could copy the traditional drawer slide-in style if you like. Finally, implementations must react accordingly if the user wants this animated or not via the `animated` flag, and then call the `completion` block at the end. #### Dismissal -`- (void)dismissWithSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView animated:(BOOL)animated completion:(void(^)(BOOL finished))completion` +```objective-c +- (void)dismissWithSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView animated:(BOOL)animated completion:(void(^)(BOOL finished))completion +``` Dismissal is the exact same as presentation except it needs to be able to get the current position of the open drawer and move it off screen. Again, how you do this is up to you. #### Optional Methods -`- (void)willRotateOpenDrawerWithOpenSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView` +```objective-c +- (void)willRotateOpenDrawerWithOpenSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView +``` -`- (void)didRotateOpenDrawerWithOpenSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView` +```objective-c +- (void)didRotateOpenDrawerWithOpenSide:(JVFloatingDrawerSide)drawerSide sideView:(UIView *)sideView centerView:(UIView *)centerView +``` `-willRotateOpenDrawerWithOpenSide:sideView:centerView` is invoked right *before* a device orientation change so the animator can handle it. `-didRotateOpenDrawerWithOpenSide:sideView:centerView` is invoked right *after*. The `JVFloatingDrawerSpringAnimator` only implements `-didRotateOpenDrawerWithOpenSide:sideView:centerView` and calls the same code as `-presentationWithSide:sideView:centerView:animated:completion:` in it.