diff --git a/Example/JVFloatingDrawer.xcodeproj/project.pbxproj b/Example/JVFloatingDrawer.xcodeproj/project.pbxproj index 7fbee34..0b46692 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,95 @@ /* 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 = ( + "${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_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 */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + 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_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; }; - 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 +513,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 +526,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 +539,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 +559,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..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,4 +95,10 @@ - (void)didReceiveMemoryWarning { // Dispose of any resources that can be recreated. } +#pragma mark - JVFloatingDrawerPanGestureDelegate + +- (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide { + return YES; +} + @end diff --git a/Example/JVFloatingDrawer/JVGitHubViewController.m b/Example/JVFloatingDrawer/JVGitHubViewController.m index 7575944..783d825 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 - JVFloatingDrawerPanGestureDelegate + +- (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..4a808cb 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.3.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..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]; }; @@ -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..89c0a5d 100644 --- a/Pod/Classes/JVFloatingDrawerViewController.h +++ b/Pod/Classes/JVFloatingDrawerViewController.h @@ -16,6 +16,12 @@ typedef NS_ENUM(NSInteger, JVFloatingDrawerSide) { JVFloatingDrawerSideRight }; +@protocol JVFloatingDrawerPanGestureDelegate +@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..584a480 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; diff --git a/README.md b/README.md index d4fb7e3..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 @@ -69,6 +75,14 @@ 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. +#### `JVFloatingDrawerPanGestureDelegate` + +The `JVFloatingDrawerPanGestureDelegate` is a protocol that allows each ViewController in the Drawer to decides their own gesture behaviour. + +```objective-c +- (BOOL)shouldOpenDrawerWithSide:(JVFloatingDrawerSide)drawerSide; +``` + #### `JVFloatingDrawerView` `JVFloatingDrawerView` is an internal class that you will not have to deal with as a user. It's tasked with laying out the drawer via autolayout constraints. It handles decorations like the shadow and rounded corners you see around the center view controller. Each view controller (center, left, and right) of the `JVFloatingDrawerViewController` are wrapped in `UIView` containers. This is how we support swapping drawers. @@ -79,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. @@ -101,6 +123,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.