From 39ffd4ec8e2ab571d4924d17c5ffd05300fe5e4d Mon Sep 17 00:00:00 2001 From: Kevin Harwood Date: Mon, 12 Aug 2013 09:41:31 -0500 Subject: [PATCH] Potential fix for #71 --- MMDrawerController/MMDrawerController.m | 181 +++++++++++++----------- 1 file changed, 98 insertions(+), 83 deletions(-) diff --git a/MMDrawerController/MMDrawerController.m b/MMDrawerController/MMDrawerController.m index 22db0db6..b5f5a9cc 100644 --- a/MMDrawerController/MMDrawerController.m +++ b/MMDrawerController/MMDrawerController.m @@ -125,6 +125,7 @@ @interface MMDrawerController () { @property (nonatomic, copy) MMDrawerControllerDrawerVisualStateBlock drawerVisualState; @property (nonatomic, copy) MMDrawerGestureShouldRecognizeTouchBlock gestureShouldRecognizeTouch; @property (nonatomic, copy) MMDrawerGestureCompletionBlock gestureCompletion; +@property (nonatomic, assign) BOOL isAnimating; @end @@ -193,84 +194,40 @@ -(void)closeDrawerAnimated:(BOOL)animated completion:(void (^)(BOOL))completion{ } -(void)closeDrawerAnimated:(BOOL)animated velocity:(CGFloat)velocity animationOptions:(UIViewAnimationOptions)options completion:(void (^)(BOOL))completion{ - CGRect newFrame = self.view.bounds; - - CGFloat distance = ABS(CGRectGetMinX(self.centerContainerView.frame)); - NSTimeInterval duration = MAX(distance/ABS(velocity),MMDrawerMinimumAnimationDuration); - - BOOL leftDrawerVisible = CGRectGetMinX(self.centerContainerView.frame) > 0; - BOOL rightDrawerVisible = CGRectGetMinX(self.centerContainerView.frame) < 0; - - MMDrawerSide visibleSide = MMDrawerSideNone; - CGFloat percentVisble = 0.0; - - if(leftDrawerVisible){ - CGFloat visibleDrawerPoints = CGRectGetMinX(self.centerContainerView.frame); - percentVisble = MAX(0.0,visibleDrawerPoints/self.maximumLeftDrawerWidth); - visibleSide = MMDrawerSideLeft; - } - else if(rightDrawerVisible){ - CGFloat visibleDrawerPoints = CGRectGetWidth(self.centerContainerView.frame)-CGRectGetMaxX(self.centerContainerView.frame); - percentVisble = MAX(0.0,visibleDrawerPoints/self.maximumRightDrawerWidth); - visibleSide = MMDrawerSideRight; - } - - UIViewController * sideDrawerViewController = [self sideDrawerViewControllerForSide:visibleSide]; - - [self updateDrawerVisualStateForDrawerSide:visibleSide percentVisible:percentVisble]; - - [sideDrawerViewController beginAppearanceTransition:NO animated:animated]; - - [UIView - animateWithDuration:(animated?duration:0.0) - delay:0.0 - options:options - animations:^{ - [self.centerContainerView setFrame:newFrame]; - [self updateDrawerVisualStateForDrawerSide:visibleSide percentVisible:0.0]; - } - completion:^(BOOL finished) { - [sideDrawerViewController endAppearanceTransition]; - [self setOpenSide:MMDrawerSideNone]; - [self resetDrawerVisualStateForDrawerSide:visibleSide]; - - if(completion){ - completion(finished); - } - }]; -} - --(void)openDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated completion:(void (^)(BOOL))completion{ - NSParameterAssert(drawerSide != MMDrawerSideNone); - - [self openDrawerSide:drawerSide animated:animated velocity:self.animationVelocity animationOptions:UIViewAnimationOptionCurveEaseInOut completion:completion]; -} - --(void)openDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated velocity:(CGFloat)velocity animationOptions:(UIViewAnimationOptions)options completion:(void (^)(BOOL))completion{ - NSParameterAssert(drawerSide != MMDrawerSideNone); - - UIViewController * sideDrawerViewController = [self sideDrawerViewControllerForSide:drawerSide]; - CGRect visibleRect = CGRectIntersection(self.view.bounds,sideDrawerViewController.view.frame); - BOOL drawerFullyCovered = (CGRectContainsRect(self.centerContainerView.frame, visibleRect) || - CGRectIsNull(visibleRect)); - if(drawerFullyCovered){ - [self prepareToPresentDrawer:drawerSide animated:animated]; + if(self.isAnimating){ + if(completion){ + completion(NO); + } } - - if(sideDrawerViewController){ - CGRect newFrame; - CGRect oldFrame = self.centerContainerView.frame; - if(drawerSide == MMDrawerSideLeft){ - newFrame = self.centerContainerView.frame; - newFrame.origin.x = self.maximumLeftDrawerWidth; + else { + self.isAnimating = animated; + CGRect newFrame = self.view.bounds; + + CGFloat distance = ABS(CGRectGetMinX(self.centerContainerView.frame)); + NSTimeInterval duration = MAX(distance/ABS(velocity),MMDrawerMinimumAnimationDuration); + + BOOL leftDrawerVisible = CGRectGetMinX(self.centerContainerView.frame) > 0; + BOOL rightDrawerVisible = CGRectGetMinX(self.centerContainerView.frame) < 0; + + MMDrawerSide visibleSide = MMDrawerSideNone; + CGFloat percentVisble = 0.0; + + if(leftDrawerVisible){ + CGFloat visibleDrawerPoints = CGRectGetMinX(self.centerContainerView.frame); + percentVisble = MAX(0.0,visibleDrawerPoints/self.maximumLeftDrawerWidth); + visibleSide = MMDrawerSideLeft; } - else { - newFrame = self.centerContainerView.frame; - newFrame.origin.x = 0-self.maximumRightDrawerWidth; + else if(rightDrawerVisible){ + CGFloat visibleDrawerPoints = CGRectGetWidth(self.centerContainerView.frame)-CGRectGetMaxX(self.centerContainerView.frame); + percentVisble = MAX(0.0,visibleDrawerPoints/self.maximumRightDrawerWidth); + visibleSide = MMDrawerSideRight; } - CGFloat distance = ABS(CGRectGetMinX(oldFrame)-newFrame.origin.x); - NSTimeInterval duration = MAX(distance/ABS(velocity),MMDrawerMinimumAnimationDuration); + UIViewController * sideDrawerViewController = [self sideDrawerViewControllerForSide:visibleSide]; + + [self updateDrawerVisualStateForDrawerSide:visibleSide percentVisible:percentVisble]; + + [sideDrawerViewController beginAppearanceTransition:NO animated:animated]; [UIView animateWithDuration:(animated?duration:0.0) @@ -278,17 +235,13 @@ -(void)openDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated velocity: options:options animations:^{ [self.centerContainerView setFrame:newFrame]; - [self updateDrawerVisualStateForDrawerSide:drawerSide percentVisible:1.0]; + [self updateDrawerVisualStateForDrawerSide:visibleSide percentVisible:0.0]; } completion:^(BOOL finished) { - //End the appearance transition if it already wasn't open. - if(drawerSide != self.openSide){ - [sideDrawerViewController endAppearanceTransition]; - } - [self setOpenSide:drawerSide]; - - [self resetDrawerVisualStateForDrawerSide:drawerSide]; - + [sideDrawerViewController endAppearanceTransition]; + [self setOpenSide:MMDrawerSideNone]; + [self resetDrawerVisualStateForDrawerSide:visibleSide]; + self.isAnimating = NO; if(completion){ completion(finished); } @@ -296,6 +249,68 @@ -(void)openDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated velocity: } } +-(void)openDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated completion:(void (^)(BOOL))completion{ + NSParameterAssert(drawerSide != MMDrawerSideNone); + + [self openDrawerSide:drawerSide animated:animated velocity:self.animationVelocity animationOptions:UIViewAnimationOptionCurveEaseInOut completion:completion]; +} + +-(void)openDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated velocity:(CGFloat)velocity animationOptions:(UIViewAnimationOptions)options completion:(void (^)(BOOL))completion{ + NSParameterAssert(drawerSide != MMDrawerSideNone); + if(self.isAnimating){ + if(completion){ + completion(NO); + } + } + else { + UIViewController * sideDrawerViewController = [self sideDrawerViewControllerForSide:drawerSide]; + CGRect visibleRect = CGRectIntersection(self.view.bounds,sideDrawerViewController.view.frame); + BOOL drawerFullyCovered = (CGRectContainsRect(self.centerContainerView.frame, visibleRect) || + CGRectIsNull(visibleRect)); + if(drawerFullyCovered){ + [self prepareToPresentDrawer:drawerSide animated:animated]; + } + + if(sideDrawerViewController){ + CGRect newFrame; + CGRect oldFrame = self.centerContainerView.frame; + if(drawerSide == MMDrawerSideLeft){ + newFrame = self.centerContainerView.frame; + newFrame.origin.x = self.maximumLeftDrawerWidth; + } + else { + newFrame = self.centerContainerView.frame; + newFrame.origin.x = 0-self.maximumRightDrawerWidth; + } + + CGFloat distance = ABS(CGRectGetMinX(oldFrame)-newFrame.origin.x); + NSTimeInterval duration = MAX(distance/ABS(velocity),MMDrawerMinimumAnimationDuration); + self.isAnimating = animated; + [UIView + animateWithDuration:(animated?duration:0.0) + delay:0.0 + options:options + animations:^{ + [self.centerContainerView setFrame:newFrame]; + [self updateDrawerVisualStateForDrawerSide:drawerSide percentVisible:1.0]; + } + completion:^(BOOL finished) { + //End the appearance transition if it already wasn't open. + if(drawerSide != self.openSide){ + [sideDrawerViewController endAppearanceTransition]; + } + [self setOpenSide:drawerSide]; + + [self resetDrawerVisualStateForDrawerSide:drawerSide]; + self.isAnimating = NO; + if(completion){ + completion(finished); + } + }]; + } + } +} + #pragma mark - Updating the Center View Controller -(void)setCenterViewController:(UIViewController *)centerViewController animated:(BOOL)animated{ if(_centerContainerView == nil){