From 62164d834458ce09b0f0a7ad5394186343a03a5d Mon Sep 17 00:00:00 2001 From: Jonas Gessner Date: Mon, 28 Oct 2013 16:03:07 +0100 Subject: [PATCH 1/4] Fixed Issue #152 & improved iOS 7 status bar view By fixing #152 I discovred that there was also no longer the need for `dummyStatusBarView`. MMDrawerContoller's view can simply be used to display the `statusBarViewBackgroundColor`. It also has the benefit that the drawer's shadow doesn't get cut off. --- MMDrawerController/MMDrawerController.m | 106 +++++++++++------------- 1 file changed, 48 insertions(+), 58 deletions(-) diff --git a/MMDrawerController/MMDrawerController.m b/MMDrawerController/MMDrawerController.m index d2fd3f4d..8198a927 100644 --- a/MMDrawerController/MMDrawerController.m +++ b/MMDrawerController/MMDrawerController.m @@ -94,7 +94,7 @@ -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{ UINavigationBar * navBar = [self navigationBarContainedWithinSubviewsOfView:self]; CGRect navBarFrame = [navBar convertRect:navBar.frame toView:self]; if((self.centerInteractionMode == MMDrawerOpenCenterInteractionModeNavigationBarOnly && - CGRectContainsPoint(navBarFrame, point) == NO) || + CGRectContainsPoint(navBarFrame, point) == NO) || self.centerInteractionMode == MMDrawerOpenCenterInteractionModeNone){ hitView = nil; } @@ -130,7 +130,6 @@ @interface MMDrawerController () { @property (nonatomic, strong) UIView * childControllerContainerView; @property (nonatomic, strong) MMDrawerCenterContainerView * centerContainerView; -@property (nonatomic, strong) UIView * dummyStatusBarView; @property (nonatomic, assign) CGRect startingPanRect; @property (nonatomic, copy) MMDrawerControllerDrawerVisualStateBlock drawerVisualState; @@ -199,36 +198,36 @@ - (void)encodeRestorableStateWithCoder:(NSCoder *)coder{ if (self.leftDrawerViewController){ [coder encodeObject:self.leftDrawerViewController forKey:MMDrawerLeftDrawerKey]; } - + if (self.rightDrawerViewController){ [coder encodeObject:self.rightDrawerViewController forKey:MMDrawerRightDrawerKey]; } - + if (self.centerViewController){ [coder encodeObject:self.centerViewController forKey:MMDrawerCenterKey]; } - + [coder encodeInteger:self.openSide forKey:MMDrawerOpenSideKey]; } - (void)decodeRestorableStateWithCoder:(NSCoder *)coder{ UIViewController *controller; MMDrawerSide openside; - + [super decodeRestorableStateWithCoder:coder]; if ((controller = [coder decodeObjectForKey:MMDrawerLeftDrawerKey])){ self.leftDrawerViewController = [coder decodeObjectForKey:MMDrawerLeftDrawerKey]; } - + if ((controller = [coder decodeObjectForKey:MMDrawerRightDrawerKey])){ self.rightDrawerViewController = controller; } - + if ((controller = [coder decodeObjectForKey:MMDrawerCenterKey])){ self.centerViewController = controller; } - + if ((openside = [coder decodeIntegerForKey:MMDrawerOpenSideKey])){ [self openDrawerSide:openside animated:false completion:nil]; } @@ -241,11 +240,11 @@ -(void)toggleDrawerSide:(MMDrawerSide)drawerSide animated:(BOOL)animated complet } else { if((drawerSide == MMDrawerSideLeft && - self.openSide == MMDrawerSideLeft) || + self.openSide == MMDrawerSideLeft) || (drawerSide == MMDrawerSideRight && - self.openSide == MMDrawerSideRight)){ - [self closeDrawerAnimated:animated completion:completion]; - } + self.openSide == MMDrawerSideRight)){ + [self closeDrawerAnimated:animated completion:completion]; + } else if(completion){ completion(NO); } @@ -473,7 +472,7 @@ -(void)setCenterViewController:(UIViewController *)newCenterViewController withF [sideDrawerViewController.view setFrame:self.childControllerContainerView.bounds]; } completion:^(BOOL finished) { - + CGRect oldCenterRect = self.centerContainerView.frame; [self setCenterViewController:newCenterViewController animated:animated]; [oldCenterViewController endAppearanceTransition]; @@ -481,28 +480,28 @@ -(void)setCenterViewController:(UIViewController *)newCenterViewController withF [self updateDrawerVisualStateForDrawerSide:self.openSide percentVisible:1.0]; [self.centerViewController beginAppearanceTransition:YES animated:animated]; [sideDrawerViewController beginAppearanceTransition:NO animated:animated]; - [UIView - animateWithDuration:[self animationDurationForAnimationDistance:CGRectGetWidth(self.childControllerContainerView.bounds)] - delay:MMDrawerDefaultFullAnimationDelay - options:UIViewAnimationOptionCurveEaseInOut - animations:^{ - [self.centerContainerView setFrame:self.childControllerContainerView.bounds]; - [self updateDrawerVisualStateForDrawerSide:self.openSide percentVisible:0.0]; - } - completion:^(BOOL finished) { - [self.centerViewController endAppearanceTransition]; - [self.centerViewController didMoveToParentViewController:self]; - [sideDrawerViewController endAppearanceTransition]; - [self resetDrawerVisualStateForDrawerSide:self.openSide]; - - [sideDrawerViewController.view setFrame:sideDrawerViewController.mm_visibleDrawerFrame]; - - [self setOpenSide:MMDrawerSideNone]; - - if(completion){ - completion(finished); - } - }]; + [UIView + animateWithDuration:[self animationDurationForAnimationDistance:CGRectGetWidth(self.childControllerContainerView.bounds)] + delay:MMDrawerDefaultFullAnimationDelay + options:UIViewAnimationOptionCurveEaseInOut + animations:^{ + [self.centerContainerView setFrame:self.childControllerContainerView.bounds]; + [self updateDrawerVisualStateForDrawerSide:self.openSide percentVisible:0.0]; + } + completion:^(BOOL finished) { + [self.centerViewController endAppearanceTransition]; + [self.centerViewController didMoveToParentViewController:self]; + [sideDrawerViewController endAppearanceTransition]; + [self resetDrawerVisualStateForDrawerSide:self.openSide]; + + [sideDrawerViewController.view setFrame:sideDrawerViewController.mm_visibleDrawerFrame]; + + [self setOpenSide:MMDrawerSideNone]; + + if(completion){ + completion(finished); + } + }]; }]; } else { @@ -641,9 +640,9 @@ -(BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers{ - (void)viewDidLoad { [super viewDidLoad]; - + [self.childControllerContainerView setBackgroundColor:[UIColor blackColor]]; - + [self setupGestureRecognizers]; } @@ -827,7 +826,6 @@ -(void)setShowsStatusBarBackgroundView:(BOOL)showsDummyStatusBar{ frame.size.height = CGRectGetHeight(self.view.bounds); } [self.childControllerContainerView setFrame:frame]; - [self.dummyStatusBarView setHidden:!showsDummyStatusBar]; } } else { @@ -837,7 +835,7 @@ -(void)setShowsStatusBarBackgroundView:(BOOL)showsDummyStatusBar{ -(void)setStatusBarViewBackgroundColor:(UIColor *)dummyStatusBarColor{ _statusBarViewBackgroundColor = dummyStatusBarColor; - [self.dummyStatusBarView setBackgroundColor:_statusBarViewBackgroundColor]; + [self.view setBackgroundColor:_statusBarViewBackgroundColor]; } #pragma mark - Getters @@ -873,26 +871,18 @@ -(CGFloat)visibleRightDrawerWidth{ } -(UIView*)childControllerContainerView{ - if(_childControllerContainerView == nil){ - _childControllerContainerView = [[UIView alloc] initWithFrame:self.view.bounds]; - [_childControllerContainerView setBackgroundColor:[UIColor clearColor]]; - [_childControllerContainerView setAutoresizingMask:UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth]; - [self.view addSubview:_childControllerContainerView]; + if (_childControllerContainerView == nil) { + CGRect b = self.view.bounds; + if(_childControllerContainerView == nil) { + _childControllerContainerView = [[UIView alloc] initWithFrame:b]; + [_childControllerContainerView setBackgroundColor:[UIColor clearColor]]; + [_childControllerContainerView setAutoresizingMask:UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth]; + [self.view addSubview:_childControllerContainerView]; + } } return _childControllerContainerView; } --(UIView*)dummyStatusBarView{ - if(_dummyStatusBarView==nil){ - _dummyStatusBarView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 20)]; - [_dummyStatusBarView setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; - [_dummyStatusBarView setBackgroundColor:self.statusBarViewBackgroundColor]; - [_dummyStatusBarView setHidden:!_showsStatusBarBackgroundView]; - [self.view addSubview:_dummyStatusBarView]; - } - return _dummyStatusBarView; -} - -(UIColor*)statusBarViewBackgroundColor{ if(_statusBarViewBackgroundColor == nil){ _statusBarViewBackgroundColor = [UIColor blackColor]; @@ -940,7 +930,7 @@ -(void)panGestureCallback:(UIPanGestureRecognizer *)panGesture{ UIViewController * sideDrawerViewController = [self sideDrawerViewControllerForSide:self.openSide]; [sideDrawerViewController beginAppearanceTransition:NO animated:NO]; [sideDrawerViewController endAppearanceTransition]; - + //Drawer is about to become visible [self prepareToPresentDrawer:visibleSide animated:NO]; [visibleSideDrawerViewController endAppearanceTransition]; @@ -1130,7 +1120,7 @@ -(void)prepareToPresentDrawer:(MMDrawerSide)drawer animated:(BOOL)animated{ UIViewController * sideDrawerViewControllerToPresent = [self sideDrawerViewControllerForSide:drawer]; UIViewController * sideDrawerViewControllerToHide = [self sideDrawerViewControllerForSide:drawerToHide]; - + [self.childControllerContainerView sendSubviewToBack:sideDrawerViewControllerToHide.view]; [sideDrawerViewControllerToHide.view setHidden:YES]; [sideDrawerViewControllerToPresent.view setHidden:NO]; From b13636e642dcfd43f253b2e1aa285451cd26c7c3 Mon Sep 17 00:00:00 2001 From: Jonas Gessner Date: Sun, 9 Feb 2014 22:20:46 +0100 Subject: [PATCH 2/4] Improved shadow and added corner rounding --- .../MMDrawerControllerKitchenSink.xccheckout | 16 ++-- MMDrawerController/MMDrawerBarButtonItem.h | 2 +- MMDrawerController/MMDrawerBarButtonItem.m | 6 +- MMDrawerController/MMDrawerController.h | 41 ++++++++- MMDrawerController/MMDrawerController.m | 88 +++++++++---------- 5 files changed, 90 insertions(+), 63 deletions(-) diff --git a/KitchenSink/MMDrawerControllerKitchenSink.xcodeproj/project.xcworkspace/xcshareddata/MMDrawerControllerKitchenSink.xccheckout b/KitchenSink/MMDrawerControllerKitchenSink.xcodeproj/project.xcworkspace/xcshareddata/MMDrawerControllerKitchenSink.xccheckout index 2bf4fcb5..359870a5 100644 --- a/KitchenSink/MMDrawerControllerKitchenSink.xcodeproj/project.xcworkspace/xcshareddata/MMDrawerControllerKitchenSink.xccheckout +++ b/KitchenSink/MMDrawerControllerKitchenSink.xcodeproj/project.xcworkspace/xcshareddata/MMDrawerControllerKitchenSink.xccheckout @@ -5,36 +5,36 @@ IDESourceControlProjectFavoriteDictionaryKey IDESourceControlProjectIdentifier - 88813EDE-C4BC-4EAD-BA3F-F5FC71109468 + D3FB706E-2D9D-49C9-A41B-C96BA055436E IDESourceControlProjectName MMDrawerControllerKitchenSink IDESourceControlProjectOriginsDictionary - C486FB0C-7803-4607-BCA9-799E743ECFBA - https://github.com/mutualmobile/MMDrawerController.git + 3BEF8252-7798-436C-8CB9-B085CDB20C27 + https://github.com/JonasGessner/MMDrawerController.git IDESourceControlProjectPath KitchenSink/MMDrawerControllerKitchenSink.xcodeproj/project.xcworkspace IDESourceControlProjectRelativeInstallPathDictionary - C486FB0C-7803-4607-BCA9-799E743ECFBA + 3BEF8252-7798-436C-8CB9-B085CDB20C27 ../../.. IDESourceControlProjectURL - https://github.com/mutualmobile/MMDrawerController.git + https://github.com/JonasGessner/MMDrawerController.git IDESourceControlProjectVersion 110 IDESourceControlProjectWCCIdentifier - C486FB0C-7803-4607-BCA9-799E743ECFBA + 3BEF8252-7798-436C-8CB9-B085CDB20C27 IDESourceControlProjectWCConfigurations IDESourceControlRepositoryExtensionIdentifierKey public.vcs.git IDESourceControlWCCIdentifierKey - C486FB0C-7803-4607-BCA9-799E743ECFBA + 3BEF8252-7798-436C-8CB9-B085CDB20C27 IDESourceControlWCCName - MMDrawerController-GitHub + MMDrawerController diff --git a/MMDrawerController/MMDrawerBarButtonItem.h b/MMDrawerController/MMDrawerBarButtonItem.h index e765424f..f0ee3647 100644 --- a/MMDrawerController/MMDrawerBarButtonItem.h +++ b/MMDrawerController/MMDrawerBarButtonItem.h @@ -38,7 +38,7 @@ @return The newly-initialized bar button item. */ --(id)initWithTarget:(id)target action:(SEL)action; +-(instancetype)initWithTarget:(id)target action:(SEL)action; /** Returns the current color of the menu button for the state requested. This property is deprecated in iOS 7.0. Use `tintColor` instead. diff --git a/MMDrawerController/MMDrawerBarButtonItem.m b/MMDrawerController/MMDrawerBarButtonItem.m index 2fc99978..d29609cb 100644 --- a/MMDrawerController/MMDrawerBarButtonItem.m +++ b/MMDrawerController/MMDrawerBarButtonItem.m @@ -38,7 +38,7 @@ -(void)setShadowColor:(UIColor *)color forState:(UIControlState)state; @implementation MMDrawerMenuButtonView --(id)initWithFrame:(CGRect)frame{ +-(instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if(self){ [self setMenuButtonNormalColor:[[UIColor whiteColor] colorWithAlphaComponent:0.9f]]; @@ -238,7 +238,7 @@ +(UIImage*)drawerButtonItemImage{ return drawerButtonImage; } --(id)initWithTarget:(id)target action:(SEL)action{ +-(instancetype)initWithTarget:(id)target action:(SEL)action{ if((floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)){ return [self initWithImage:[self.class drawerButtonItemImage] @@ -259,7 +259,7 @@ -(id)initWithTarget:(id)target action:(SEL)action{ } } --(id)initWithCoder:(NSCoder *)aDecoder{ +-(instancetype)initWithCoder:(NSCoder *)aDecoder{ // non-ideal way to get the target/action, but it works UIBarButtonItem* barButtonItem = [[UIBarButtonItem alloc] initWithCoder: aDecoder]; return [self initWithTarget:barButtonItem.target action:barButtonItem.action]; diff --git a/MMDrawerController/MMDrawerController.h b/MMDrawerController/MMDrawerController.h index bf895cbb..1ddff3f5 100644 --- a/MMDrawerController/MMDrawerController.h +++ b/MMDrawerController/MMDrawerController.h @@ -50,6 +50,26 @@ - Support container view controllers other than `UINavigationController` as the center view controller. */ + +typedef struct { + CGFloat shadowRadius; + CGFloat shadowOpacity; + + CGSize shadowOffset; +} MMShadowOptions; + + +NS_INLINE MMShadowOptions MMShadowOptionsMake(CGFloat shadowRadius, CGFloat shadowOpacity, CGSize shadowOffset) { + MMShadowOptions options; + + options.shadowRadius = shadowRadius; + options.shadowOpacity = shadowOpacity; + options.shadowOffset = shadowOffset; + + return options; +} + + typedef NS_ENUM(NSInteger,MMDrawerSide){ MMDrawerSideNone = 0, MMDrawerSideLeft, @@ -193,6 +213,13 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController * dr */ @property (nonatomic, assign) MMDrawerOpenCenterInteractionMode centerHiddenInteractionMode; +/** + A structure containing information about the shadow. + + By default, this is set to {0.8f, 10.0f, {0.0f, 0.0f}} + */ +@property (nonatomic, assign) MMShadowOptions shadowOptions; + /** The flag determining if a shadow should be drawn off of `centerViewController` when a drawer is open. @@ -200,6 +227,14 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController * dr */ @property (nonatomic, assign) BOOL showsShadow; +/** + The value by how many points the center view's top corners should be rounded. + + By default, this is set to 0.0f; + */ +@property (nonatomic, assign) CGFloat centerViewTopCornerRadius; + + /** The flag determining if a custom background view should appear beneath the status bar, forcing the child content to be drawn lower than the status bar. This property is only available for > iOS 7.0 to take into account for the new behavior of the status bar. @@ -227,7 +262,7 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController * dr @return The newly-initialized drawer container view controller. */ --(id)initWithCenterViewController:(UIViewController *)centerViewController leftDrawerViewController:(UIViewController *)leftDrawerViewController rightDrawerViewController:(UIViewController *)rightDrawerViewController; +-(instancetype)initWithCenterViewController:(UIViewController *)centerViewController leftDrawerViewController:(UIViewController *)leftDrawerViewController rightDrawerViewController:(UIViewController *)rightDrawerViewController; /** Creates and initializes an `MMDrawerController` object with the specified center view controller, left drawer view controller. @@ -237,7 +272,7 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController * dr @return The newly-initialized drawer container view controller. */ --(id)initWithCenterViewController:(UIViewController *)centerViewController leftDrawerViewController:(UIViewController *)leftDrawerViewController; +-(instancetype)initWithCenterViewController:(UIViewController *)centerViewController leftDrawerViewController:(UIViewController *)leftDrawerViewController; /** Creates and initializes an `MMDrawerController` object with the specified center view controller, right drawer view controller. @@ -247,7 +282,7 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController * dr @return The newly-initialized drawer container view controller. */ --(id)initWithCenterViewController:(UIViewController *)centerViewController rightDrawerViewController:(UIViewController *)rightDrawerViewController; +-(instancetype)initWithCenterViewController:(UIViewController *)centerViewController rightDrawerViewController:(UIViewController *)rightDrawerViewController; ///--------------------------------------- /// @name Opening and Closing a Drawer diff --git a/MMDrawerController/MMDrawerController.m b/MMDrawerController/MMDrawerController.m index 76148a93..5d872b82 100644 --- a/MMDrawerController/MMDrawerController.m +++ b/MMDrawerController/MMDrawerController.m @@ -143,7 +143,7 @@ @implementation MMDrawerController #pragma mark - Init -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{ +- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { [self commonSetup]; @@ -151,7 +151,7 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil return self; } -- (id)initWithCoder:(NSCoder *)aDecoder{ +- (instancetype)initWithCoder:(NSCoder *)aDecoder{ self = [super initWithCoder:aDecoder]; if (self) { [self commonSetup]; @@ -159,10 +159,12 @@ - (id)initWithCoder:(NSCoder *)aDecoder{ return self; } --(id)initWithCenterViewController:(UIViewController *)centerViewController leftDrawerViewController:(UIViewController *)leftDrawerViewController rightDrawerViewController:(UIViewController *)rightDrawerViewController{ +-(instancetype)initWithCenterViewController:(UIViewController *)centerViewController leftDrawerViewController:(UIViewController *)leftDrawerViewController rightDrawerViewController:(UIViewController *)rightDrawerViewController{ NSParameterAssert(centerViewController); self = [super init]; if(self){ + self.shadowOptions = MMShadowOptionsMake(MMDrawerDefaultShadowRadius, MMDrawerDefaultShadowOpacity, CGSizeZero); + [self setCenterViewController:centerViewController]; [self setLeftDrawerViewController:leftDrawerViewController]; [self setRightDrawerViewController:rightDrawerViewController]; @@ -170,11 +172,11 @@ -(id)initWithCenterViewController:(UIViewController *)centerViewController leftD return self; } --(id)initWithCenterViewController:(UIViewController *)centerViewController leftDrawerViewController:(UIViewController *)leftDrawerViewController{ +-(instancetype)initWithCenterViewController:(UIViewController *)centerViewController leftDrawerViewController:(UIViewController *)leftDrawerViewController{ return [self initWithCenterViewController:centerViewController leftDrawerViewController:leftDrawerViewController rightDrawerViewController:nil]; } --(id)initWithCenterViewController:(UIViewController *)centerViewController rightDrawerViewController:(UIViewController *)rightDrawerViewController{ +-(instancetype)initWithCenterViewController:(UIViewController *)centerViewController rightDrawerViewController:(UIViewController *)rightDrawerViewController{ return [self initWithCenterViewController:centerViewController leftDrawerViewController:nil rightDrawerViewController:rightDrawerViewController]; } @@ -731,6 +733,31 @@ -(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOr } #pragma mark - Setters + +- (void)setCenterViewTopCornerRadius:(CGFloat)centerViewTopCornerRadius { + _centerViewTopCornerRadius = centerViewTopCornerRadius; + + if (_centerViewTopCornerRadius > 0.0f) { + UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.centerContainerView.bounds byRoundingCorners:UIRectCornerTopRight | UIRectCornerTopLeft cornerRadii:CGSizeMake(_centerViewTopCornerRadius, _centerViewTopCornerRadius)]; + + CAShapeLayer *maskLayer = [CAShapeLayer layer]; + maskLayer.frame = self.centerContainerView.bounds; + maskLayer.path = maskPath.CGPath; + + self.centerViewController.view.layer.mask = maskLayer; + } + else { + self.centerViewController.view.layer.mask = nil; + } + + [self updateShadowForCenterView]; +} + +- (void)setShadowOptions:(MMShadowOptions)shadowOptions { + _shadowOptions = shadowOptions; + [self updateShadowForCenterView]; +} + -(void)setRightDrawerViewController:(UIViewController *)rightDrawerViewController{ [self setDrawerViewController:rightDrawerViewController forSide:MMDrawerSideRight]; } @@ -817,29 +844,6 @@ -(void)setMaximumRightDrawerWidth:(CGFloat)maximumRightDrawerWidth{ [self setMaximumRightDrawerWidth:maximumRightDrawerWidth animated:NO completion:nil]; } --(void)setShowsStatusBarBackgroundView:(BOOL)showsDummyStatusBar{ - NSArray *sysVersion = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."]; - float majorVersion = [[sysVersion objectAtIndex:0] floatValue]; - if (majorVersion >= 7){ - if(showsDummyStatusBar!=_showsStatusBarBackgroundView){ - _showsStatusBarBackgroundView = showsDummyStatusBar; - CGRect frame = self.childControllerContainerView.frame; - if(_showsStatusBarBackgroundView){ - frame.origin.y = 20; - frame.size.height = CGRectGetHeight(self.view.bounds)-20; - } - else { - frame.origin.y = 0; - frame.size.height = CGRectGetHeight(self.view.bounds); - } - [self.childControllerContainerView setFrame:frame]; - } - } - else { - _showsStatusBarBackgroundView = NO; - } -} - -(void)setStatusBarViewBackgroundColor:(UIColor *)dummyStatusBarColor{ _statusBarViewBackgroundColor = dummyStatusBarColor; [self.view setBackgroundColor:_statusBarViewBackgroundColor]; @@ -1156,29 +1160,17 @@ -(void)prepareToPresentDrawer:(MMDrawerSide)drawer animated:(BOOL)animated{ [sideDrawerViewControllerToPresent beginAppearanceTransition:YES animated:animated]; } --(void)updateShadowForCenterView{ - UIView * centerView = self.centerContainerView; +- (void)updateShadowForCenterView{ + UIView *centerView = self.centerContainerView; if(self.showsShadow){ centerView.layer.masksToBounds = NO; - centerView.layer.shadowRadius = MMDrawerDefaultShadowRadius; - centerView.layer.shadowOpacity = MMDrawerDefaultShadowOpacity; - - /** In the event this gets called a lot, we won't update the shadowPath - unless it needs to be updated (like during rotation) */ - if (centerView.layer.shadowPath == NULL) { - centerView.layer.shadowPath = [[UIBezierPath bezierPathWithRect:self.centerContainerView.bounds] CGPath]; - } - else{ - CGRect currentPath = CGPathGetPathBoundingBox(centerView.layer.shadowPath); - if (CGRectEqualToRect(currentPath, centerView.bounds) == NO){ - centerView.layer.shadowPath = [[UIBezierPath bezierPathWithRect:self.centerContainerView.bounds] CGPath]; - } - } + centerView.layer.shadowRadius = self.shadowOptions.shadowRadius; + centerView.layer.shadowOpacity = self.shadowOptions.shadowOpacity; + centerView.layer.shadowOffset = self.shadowOptions.shadowOffset; + centerView.layer.shadowPath = (self.centerViewTopCornerRadius ? [[UIBezierPath bezierPathWithRect:self.centerContainerView.bounds] CGPath] : [[UIBezierPath bezierPathWithRoundedRect:self.centerContainerView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(self.centerViewTopCornerRadius, self.centerViewTopCornerRadius)] CGPath]); } - else if (centerView.layer.shadowPath != NULL) { - centerView.layer.shadowRadius = 0.f; - centerView.layer.shadowOpacity = 0.f; - centerView.layer.shadowPath = NULL; + else { + centerView.layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectNull].CGPath; centerView.layer.masksToBounds = YES; } } From 73a123a76d1c43f80313ba20b818c39186ada39b Mon Sep 17 00:00:00 2001 From: Jonas Gessner Date: Sun, 9 Feb 2014 22:27:40 +0100 Subject: [PATCH 3/4] Publicly expose isAnimating drawer method, close drawer with full animation --- MMDrawerController/MMDrawerController.h | 12 ++++++ MMDrawerController/MMDrawerController.m | 54 +++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/MMDrawerController/MMDrawerController.h b/MMDrawerController/MMDrawerController.h index 1ddff3f5..3a385925 100644 --- a/MMDrawerController/MMDrawerController.h +++ b/MMDrawerController/MMDrawerController.h @@ -249,6 +249,13 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController * dr */ @property (nonatomic, strong) UIColor * statusBarViewBackgroundColor; + +/** + Returns if the drawer is currently moving. + */ +- (BOOL)isAnimatingDrawer; + + ///--------------------------------------- /// @name Initializing a `MMDrawerController` ///--------------------------------------- @@ -309,6 +316,11 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController * dr */ -(void)closeDrawerAnimated:(BOOL)animated completion:(void(^)(BOOL finished))completion; +/** + Closes the open drawer by performing a full animation. + */ +- (void)closeDrawerWithFullAnimation:(void (^)(void))completion; + /** Opens the `drawer` passed in. diff --git a/MMDrawerController/MMDrawerController.m b/MMDrawerController/MMDrawerController.m index 5d872b82..f95eb5b9 100644 --- a/MMDrawerController/MMDrawerController.m +++ b/MMDrawerController/MMDrawerController.m @@ -257,6 +257,60 @@ -(void)closeDrawerAnimated:(BOOL)animated completion:(void (^)(BOOL finished))co [self closeDrawerAnimated:animated velocity:self.animationVelocity animationOptions:UIViewAnimationOptionCurveEaseInOut completion:completion]; } +- (void)closeDrawerWithFullAnimation:(void (^)(void))completion { + UIViewController * sideDrawerViewController = [self sideDrawerViewControllerForSide:self.openSide]; + + CGFloat targetClosePoint = 0.0f; + if(self.openSide == MMDrawerSideRight){ + targetClosePoint = -CGRectGetWidth(self.childControllerContainerView.bounds); + } + else if(self.openSide == MMDrawerSideLeft) { + targetClosePoint = CGRectGetWidth(self.childControllerContainerView.bounds); + } + + CGFloat distance = ABS(self.centerContainerView.frame.origin.x-targetClosePoint); + NSTimeInterval firstDuration = [self animationDurationForAnimationDistance:distance]; + + CGRect newCenterRect = self.centerContainerView.frame; + newCenterRect.origin.x = targetClosePoint; + + [UIView + animateWithDuration:firstDuration + delay:0.0 + options:UIViewAnimationOptionCurveEaseInOut + animations:^{ + [self.centerContainerView setFrame:newCenterRect]; + [sideDrawerViewController.view setFrame:self.childControllerContainerView.bounds]; + } + completion:^(BOOL finished) { + + CGRect oldCenterRect = self.centerContainerView.frame; + + [self.centerContainerView setFrame:oldCenterRect]; + [self updateDrawerVisualStateForDrawerSide:self.openSide percentVisible:1.0]; + [UIView + animateWithDuration:[self animationDurationForAnimationDistance:CGRectGetWidth(self.childControllerContainerView.bounds)] + delay:MMDrawerDefaultFullAnimationDelay + options:UIViewAnimationOptionCurveEaseInOut + animations:^{ + [self.centerContainerView setFrame:self.childControllerContainerView.bounds]; + [self updateDrawerVisualStateForDrawerSide:self.openSide percentVisible:0.0]; + } + completion:^(BOOL finished) { + [self resetDrawerVisualStateForDrawerSide:self.openSide]; + + [sideDrawerViewController.view setFrame:sideDrawerViewController.mm_visibleDrawerFrame]; + + [self setOpenSide:MMDrawerSideNone]; + + if (completion) { + completion(); + } + }]; + }]; +} + + -(void)closeDrawerAnimated:(BOOL)animated velocity:(CGFloat)velocity animationOptions:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion{ if(self.isAnimatingDrawer){ if(completion){ From f99a6fc9e9d1eef4fc422bc9827830ae69ddc56c Mon Sep 17 00:00:00 2001 From: Jonas Gessner Date: Sun, 9 Feb 2014 23:00:47 +0100 Subject: [PATCH 4/4] Bug fixes, new methods --- MMDrawerController/MMDrawerController.h | 6 +++ MMDrawerController/MMDrawerController.m | 50 +++++++++++++++++++++---- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/MMDrawerController/MMDrawerController.h b/MMDrawerController/MMDrawerController.h index 3a385925..b2b0a2e8 100644 --- a/MMDrawerController/MMDrawerController.h +++ b/MMDrawerController/MMDrawerController.h @@ -185,6 +185,12 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController * dr */ @property (nonatomic, assign) BOOL shouldStretchDrawer; + +/** + A boolean that determines whether or not the side drawers should be stretched with the center drawer. This only has any effects when \c shouldStretchDrawer is set to \c YES. + */ +@property (nonatomic, assign) BOOL shouldStrechSideDrawers; + /** The current open side of the drawer. diff --git a/MMDrawerController/MMDrawerController.m b/MMDrawerController/MMDrawerController.m index f95eb5b9..345b0abe 100644 --- a/MMDrawerController/MMDrawerController.m +++ b/MMDrawerController/MMDrawerController.m @@ -123,7 +123,6 @@ -(UINavigationBar*)navigationBarContainedWithinSubviewsOfView:(UIView*)view{ @interface MMDrawerController () { CGFloat _maximumRightDrawerWidth; CGFloat _maximumLeftDrawerWidth; - UIColor * _statusBarViewBackgroundColor; } @property (nonatomic, assign, readwrite) MMDrawerSide openSide; @@ -141,6 +140,8 @@ @interface MMDrawerController () { @implementation MMDrawerController +@synthesize statusBarViewBackgroundColor = _statusBarViewBackgroundColor; + #pragma mark - Init - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{ @@ -704,13 +705,12 @@ -(BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers{ - (void)viewDidLoad { [super viewDidLoad]; - [self.childControllerContainerView setBackgroundColor:[UIColor blackColor]]; - [self setupGestureRecognizers]; } -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; + [self updateShadowForCenterView]; [self.centerViewController beginAppearanceTransition:YES animated:animated]; } @@ -788,9 +788,7 @@ -(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOr #pragma mark - Setters -- (void)setCenterViewTopCornerRadius:(CGFloat)centerViewTopCornerRadius { - _centerViewTopCornerRadius = centerViewTopCornerRadius; - +- (void)updateCornerRounding { if (_centerViewTopCornerRadius > 0.0f) { UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.centerContainerView.bounds byRoundingCorners:UIRectCornerTopRight | UIRectCornerTopLeft cornerRadii:CGSizeMake(_centerViewTopCornerRadius, _centerViewTopCornerRadius)]; @@ -803,6 +801,10 @@ - (void)setCenterViewTopCornerRadius:(CGFloat)centerViewTopCornerRadius { else { self.centerViewController.view.layer.mask = nil; } +} + +- (void)setCenterViewTopCornerRadius:(CGFloat)centerViewTopCornerRadius { + _centerViewTopCornerRadius = centerViewTopCornerRadius; [self updateShadowForCenterView]; } @@ -898,8 +900,37 @@ -(void)setMaximumRightDrawerWidth:(CGFloat)maximumRightDrawerWidth{ [self setMaximumRightDrawerWidth:maximumRightDrawerWidth animated:NO completion:nil]; } --(void)setStatusBarViewBackgroundColor:(UIColor *)dummyStatusBarColor{ +- (void)setShowsStatusBarBackgroundView:(BOOL)showsDummyStatusBar{ + NSArray *sysVersion = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."]; + float majorVersion = [[sysVersion objectAtIndex:0] floatValue]; + + if (majorVersion >= 7){ + if(showsDummyStatusBar!=_showsStatusBarBackgroundView){ + + _showsStatusBarBackgroundView = showsDummyStatusBar; + CGRect frame = self.childControllerContainerView.frame; + + if(_showsStatusBarBackgroundView){ + CGFloat statusBarheight = [UIApplication sharedApplication].statusBarFrame.size.height; + frame.origin.y = statusBarheight; + frame.size.height = CGRectGetHeight(self.view.bounds)-statusBarheight; + } + else { + frame.origin.y = 0.0f; + frame.size.height = CGRectGetHeight(self.view.bounds); + } + + [self.childControllerContainerView setFrame:frame]; + } + } + else { + _showsStatusBarBackgroundView = NO; + } +} + +-(void)setStatusBarViewBackgroundColor:(UIColor *)dummyStatusBarColor { _statusBarViewBackgroundColor = dummyStatusBarColor; + [self setShowsStatusBarBackgroundView:(_statusBarViewBackgroundColor != nil)]; [self.view setBackgroundColor:_statusBarViewBackgroundColor]; } @@ -1108,7 +1139,7 @@ -(void)updateDrawerVisualStateForDrawerSide:(MMDrawerSide)drawerSide percentVisi if(self.drawerVisualState){ self.drawerVisualState(self,drawerSide,percentVisible); } - else if(self.shouldStretchDrawer){ + else if(self.shouldStretchDrawer && self.shouldStrechSideDrawers){ [self applyOvershootScaleTransformForDrawerSide:drawerSide percentVisible:percentVisible]; } } @@ -1221,12 +1252,15 @@ - (void)updateShadowForCenterView{ centerView.layer.shadowRadius = self.shadowOptions.shadowRadius; centerView.layer.shadowOpacity = self.shadowOptions.shadowOpacity; centerView.layer.shadowOffset = self.shadowOptions.shadowOffset; + centerView.layer.shadowPath = (self.centerViewTopCornerRadius ? [[UIBezierPath bezierPathWithRect:self.centerContainerView.bounds] CGPath] : [[UIBezierPath bezierPathWithRoundedRect:self.centerContainerView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(self.centerViewTopCornerRadius, self.centerViewTopCornerRadius)] CGPath]); } else { centerView.layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectNull].CGPath; centerView.layer.masksToBounds = YES; } + + [self updateCornerRounding]; } -(NSTimeInterval)animationDurationForAnimationDistance:(CGFloat)distance{