diff --git a/KitchenSink/MMDrawerControllerKitchenSink.xcodeproj/project.pbxproj b/KitchenSink/MMDrawerControllerKitchenSink.xcodeproj/project.pbxproj index 225c3a0f..2fc71229 100644 --- a/KitchenSink/MMDrawerControllerKitchenSink.xcodeproj/project.pbxproj +++ b/KitchenSink/MMDrawerControllerKitchenSink.xcodeproj/project.pbxproj @@ -84,6 +84,7 @@ 29E2C6171738A10F00606309 /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Icon@2x.png"; sourceTree = ""; }; 29F61639172AC22A00B31282 /* MMDrawerBarButtonItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMDrawerBarButtonItem.h; sourceTree = ""; }; 29F6163A172AC22A00B31282 /* MMDrawerBarButtonItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMDrawerBarButtonItem.m; sourceTree = ""; }; + 462C592D1757C16B006C1D6F /* MMDrawerController+Subclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MMDrawerController+Subclass.h"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -164,6 +165,7 @@ children = ( 294A1D2E1719982B005BF6B1 /* MMDrawerController.h */, 294A1D2F1719982B005BF6B1 /* MMDrawerController.m */, + 462C592D1757C16B006C1D6F /* MMDrawerController+Subclass.h */, 294A1D3117199844005BF6B1 /* UIViewController+MMDrawerController.h */, 294A1D3217199844005BF6B1 /* UIViewController+MMDrawerController.m */, 29F61639172AC22A00B31282 /* MMDrawerBarButtonItem.h */, diff --git a/KitchenSink/MMDrawerControllerKitchenSink.xcodeproj/project.xcworkspace/xcshareddata/MMDrawerControllerKitchenSink.xccheckout b/KitchenSink/MMDrawerControllerKitchenSink.xcodeproj/project.xcworkspace/xcshareddata/MMDrawerControllerKitchenSink.xccheckout new file mode 100644 index 00000000..1859c2d5 --- /dev/null +++ b/KitchenSink/MMDrawerControllerKitchenSink.xcodeproj/project.xcworkspace/xcshareddata/MMDrawerControllerKitchenSink.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + 4C4E27BF-53C6-43BF-A4EF-1C812D609BDD + IDESourceControlProjectName + MMDrawerControllerKitchenSink + IDESourceControlProjectOriginsDictionary + + E52E2B19-E9AC-4E28-86DB-511AF3178D5E + https://github.com/mutualmobile/MMDrawerController.git + + IDESourceControlProjectPath + KitchenSink/MMDrawerControllerKitchenSink.xcodeproj/project.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + E52E2B19-E9AC-4E28-86DB-511AF3178D5E + ../../.. + + IDESourceControlProjectURL + https://github.com/mutualmobile/MMDrawerController.git + IDESourceControlProjectVersion + 110 + IDESourceControlProjectWCCIdentifier + E52E2B19-E9AC-4E28-86DB-511AF3178D5E + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + E52E2B19-E9AC-4E28-86DB-511AF3178D5E + IDESourceControlWCCName + MMDrawerController-GitHub + + + + diff --git a/MMDrawerController.podspec b/MMDrawerController.podspec index e651c77c..57188c8e 100644 --- a/MMDrawerController.podspec +++ b/MMDrawerController.podspec @@ -25,4 +25,9 @@ Pod::Spec.new do |s| ss.source_files = 'MMDrawerController/MMDrawerVisualState.{h,m}' ss.dependency 'MMDrawerController/Core' end + + s.subspec 'Subclass' do |ss| + ss.source_files = 'MMDrawerController/MMDrawerController+Subclass.h' + ss.dependency 'MMDrawerController/Core' + end end diff --git a/MMDrawerController/MMDrawerController+Subclass.h b/MMDrawerController/MMDrawerController+Subclass.h new file mode 100644 index 00000000..419ff682 --- /dev/null +++ b/MMDrawerController/MMDrawerController+Subclass.h @@ -0,0 +1,111 @@ +// Copyright (c) 2013 Mutual Mobile (http://mutualmobile.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "MMDrawerController.h" + +/** + This class extension is designed for use by subclasses of `MMDrawerController` to customize the functionality to support a specific use-case by a developer. When importing this file, there is no need to also call `#import MMDrawerController.h`. + + None of these methods are meant to be called by non-subclasses of `MMDrawerController`. + */ + +@interface MMDrawerController (Subclass) +///--------------------------------------- +/// @name Gesture Interaction +///--------------------------------------- +/** + `MMDrawerController`'s single-tap gesture recognizer callback. This method is called every time the `UITapGestureRecognizer` is triggered. + + @param tapGesture The single-tap gesture recognizer instance that triggered the callback + */ +-(void)tapGestureCallback:(UITapGestureRecognizer *)tapGesture __attribute((objc_requires_super)); + +/** + `MMDrawerController`'s pan gesture recognizer callback. This method is called every time the `UIPanGestureRecognizer` is updated. + + @warning This method do the minimal amount of work to keep the pan gesture responsive. + + @param panGesture The pan gesture recognizer instance that triggered the callback + */ +-(void)panGestureCallback:(UIPanGestureRecognizer *)panGesture __attribute((objc_requires_super)); + +/** + A `UIGestureRecognizerDelegate` method that is queried by `MMDrawerController`'s gestures to determine if it should receive the touch. + + @param gestureRecognizer The gesture recognizer that is asking if it should recieve a touch + @param touch The touch in question in gestureRecognizer.view's coordinate space + */ +-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch __attribute((objc_requires_super)); + +///--------------------------------------- +/// @name Drawer Presentation +///--------------------------------------- +/** + Sets the initial conditions for `MMDrawerController` and its child view controllers to prepare the drawer for a transition. If a drawer is open and the opposite drawer is being presented, it prepares that drawer to be hidden and vice-versa for the closing drawer. + + @param drawer The drawer side that will be presented + @param animated A boolean that indicates whether the presentation is being animated or not + */ +-(void)prepareToPresentDrawer:(MMDrawerSide)drawer animated:(BOOL)animated __attribute((objc_requires_super)); + +///--------------------------------------- +/// @name Opening/Closing Drawer +///--------------------------------------- +/** + The method that handles closing the drawer. You can subclass this method to get a callback every time the drawer is about to be closed. You can inspect the current open side to determine what side is about to be closed. + + @param animated A boolean that indicates whether the drawer should close with animation + @param velocity A float indicating how fast the drawer should close + @param animationOptions A mask defining the animation options of the animation + @param completion A completion block to be called when the drawer is finished closing + */ +-(void)closeDrawerAnimated:(BOOL)animated velocity:(CGFloat)velocity animationOptions:(UIViewAnimationOptions)options completion:(void (^)(BOOL))completion __attribute((objc_requires_super)); + +/** + The method that handles opening the drawer. You can subclass this method to get a callback every time the drawer is about to be opened. + + @param drawerSide The drawer side that will be opened + @param animated A boolean that indicates whether the drawer should open with animation + @param velocity A float indicating how fast the drawer should open + @param animationOptions A mask defining the animation options of the animation + @param completion A completion block to be called when the drawer is finished opening + */ +-(void)openDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated velocity:(CGFloat)velocity animationOptions:(UIViewAnimationOptions)options completion:(void (^)(BOOL))completion __attribute((objc_requires_super)); + +///--------------------------------------- +/// @name `UIViewController` Subclass Methods +///--------------------------------------- +/** + Included here to ensure subclasses call `super`. + + @param toInterfaceOrientation The interface orientation that the interface is moving to + @param duration The duration of the interface orientation animation + */ +-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration __attribute((objc_requires_super)); + +/** + Included here to ensure subclasses call `super`. + + @param toInterfaceOrientation The interface orientation that the interface is moving to + @param duration The duration of the interface orientation animation + */ +-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration __attribute((objc_requires_super)); + +@end diff --git a/MMDrawerController/MMDrawerController.m b/MMDrawerController/MMDrawerController.m index ce904307..6bd2d21d 100644 --- a/MMDrawerController/MMDrawerController.m +++ b/MMDrawerController/MMDrawerController.m @@ -837,7 +837,7 @@ -(CGFloat)visibleRightDrawerWidth{ #pragma mark - Gesture Handlers --(void)tapGesture:(UITapGestureRecognizer *)tapGesture{ +-(void)tapGestureCallback:(UITapGestureRecognizer *)tapGesture{ if(self.openSide != MMDrawerSideNone){ [self closeDrawerAnimated:YES completion:^(BOOL finished) { if(self.gestureCompletion){ @@ -847,7 +847,7 @@ -(void)tapGesture:(UITapGestureRecognizer *)tapGesture{ } } --(void)panGesture:(UIPanGestureRecognizer *)panGesture{ +-(void)panGestureCallback:(UIPanGestureRecognizer *)panGesture{ switch (panGesture.state) { case UIGestureRecognizerStateBegan: self.startingPanRect = self.centerContainerView.frame; @@ -1030,11 +1030,11 @@ static inline CGFloat originXForDrawerOriginAndTargetOriginOffset(CGFloat origin #pragma mark - Helpers -(void)setupGestureRecognizers{ - UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)]; + UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureCallback:)]; [pan setDelegate:self]; [self.view addGestureRecognizer:pan]; - UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)]; + UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureCallback:)]; [tap setDelegate:self]; [self.view addGestureRecognizer:tap]; } diff --git a/README.md b/README.md index cd0c08ba..b321333c 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,12 @@ When a drawer is open, you can control how a user can interact with the center v ###Accessing the Drawer Controller from a Child View Controller You can use the `UIViewController+MMDrawerController` category in order to query the drawerController directly from child view controllers. +--- +##Subclassing +If you plan to subclass `MMDrawerController`, import `MMDrawerController+Subclass.h` into your subclass to access protected methods for `MMDrawerController.` Note that several methods assume and require you to call super, so be sure to follow that convention. + +If there is specific functionality you need that is not supported by these methods, please open a Github issue explaining your needs and we can try and find a way to open up methods that can help you out. + --- ##Bells and Whistles A few extras to make your life easier...