diff --git a/README.md b/README.md index 3d6d097..588b276 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ REMenuItem *customViewItem = [[REMenuItem alloc] initWithCustomView:customView a You can customize the following properties of `REMenu`: ``` objective-c +@property (assign, readwrite, nonatomic) UIEdgeInsetsMake contentInset; //padding for the menu @property (assign, readwrite, nonatomic) CGFloat cornerRadius; @property (strong, readwrite, nonatomic) UIColor *shadowColor; @property (assign, readwrite, nonatomic) CGSize shadowOffset; diff --git a/REMenu/RECommonFunctions.m b/REMenu/RECommonFunctions.m old mode 100755 new mode 100644 diff --git a/REMenu/REMenu.h b/REMenu/REMenu.h index 89cd8b5..834ba2b 100644 --- a/REMenu/REMenu.h +++ b/REMenu/REMenu.h @@ -27,7 +27,6 @@ #import #import "RECommonFunctions.h" #import "REMenuItem.h" -#import "REMenuContainerView.h" @class REMenu; @class REMenuItem; @@ -67,6 +66,7 @@ typedef NS_ENUM(NSInteger, REMenuLiveBackgroundStyle) { // Style // +@property (assign, readwrite, nonatomic) UIEdgeInsets contentInset; @property (assign, readwrite, nonatomic) CGFloat cornerRadius; @property (strong, readwrite, nonatomic) UIColor *shadowColor; @property (assign, readwrite, nonatomic) CGSize shadowOffset; diff --git a/REMenu/REMenu.m b/REMenu/REMenu.m index 9d0c367..63cb21f 100644 --- a/REMenu/REMenu.m +++ b/REMenu/REMenu.m @@ -35,14 +35,15 @@ @interface REMenuItem () @interface REMenu () -@property (strong, readwrite, nonatomic) UIView *menuView; +@property (strong, readwrite, nonatomic) UIScrollView *menuView; @property (strong, readwrite, nonatomic) UIView *menuWrapperView; -@property (strong, readwrite, nonatomic) REMenuContainerView *containerView; +@property (strong, readwrite, nonatomic) UIView *containerView; @property (strong, readwrite, nonatomic) UIButton *backgroundButton; @property (assign, readwrite, nonatomic) BOOL isOpen; @property (assign, readwrite, nonatomic) BOOL isAnimating; @property (strong, readwrite, nonatomic) NSMutableArray *itemViews; @property (weak, readwrite, nonatomic) UINavigationBar *navigationBar; +@property (weak, readwrite, nonatomic) UIView *viewToShowFrom; @property (strong, readwrite, nonatomic) UIToolbar *toolbar; @end @@ -59,6 +60,7 @@ - (id)init _separatorHeight = 2.0; _separatorOffset = CGSizeMake(0.0, 0.0); _waitUntilAnimationIsComplete = YES; + _contentInset = UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0); _textOffset = CGSizeMake(0, 0); _subtitleTextOffset = CGSizeMake(0, 0); @@ -116,11 +118,13 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view self.isOpen = YES; self.isAnimating = YES; - + + self.viewToShowFrom = view; + // Create views // self.containerView = ({ - REMenuContainerView *view = [[REMenuContainerView alloc] init]; + UIView *view = [[UIView alloc] init]; view.clipsToBounds = YES; view.autoresizingMask = UIViewAutoresizingFlexibleWidth; @@ -130,9 +134,9 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view } view; }); - + self.menuView = ({ - UIView *view = [[UIView alloc] init]; + UIScrollView *view = [[UIScrollView alloc] init]; if (!self.liveBlur || !REUIKitIsFlatMode()) { view.backgroundColor = self.backgroundColor; } @@ -143,6 +147,7 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view view.layer.shouldRasterize = YES; view.layer.rasterizationScale = [UIScreen mainScreen].scale; view.autoresizingMask = UIViewAutoresizingFlexibleWidth; + view.contentInset = self.contentInset; view; }); @@ -184,8 +189,6 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view button; }); - CGFloat navigationBarOffset = self.appearsBehindNavigationBar && self.navigationBar ? 64 : 0; - // Append new item views to REMenuView // for (REMenuItem *item in self.items) { @@ -196,7 +199,7 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view itemHeight += self.cornerRadius; UIView *separatorView = [[UIView alloc] initWithFrame:CGRectMake(self.separatorOffset.width, - index * self.itemHeight + index * self.separatorHeight + 40.0 + navigationBarOffset + self.separatorOffset.height, + index * self.itemHeight + index * self.separatorHeight + self.separatorOffset.height, rect.size.width - self.separatorOffset.width, self.separatorHeight)]; separatorView.backgroundColor = self.separatorColor; @@ -204,7 +207,7 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view [self.menuView addSubview:separatorView]; REMenuItemView *itemView = [[REMenuItemView alloc] initWithFrame:CGRectMake(0, - index * self.itemHeight + (index + 1.0) * self.separatorHeight + 40.0 + navigationBarOffset, + index * self.itemHeight + (index + 1.0) * self.separatorHeight, rect.size.width, itemHeight) menu:self item:item @@ -219,12 +222,15 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view } [self.menuView addSubview:itemView]; } - + // Set up frames // - self.menuWrapperView.frame = CGRectMake(0, -self.combinedHeight - navigationBarOffset, rect.size.width, self.combinedHeight + navigationBarOffset); - self.menuView.frame = self.menuWrapperView.bounds; - if (REUIKitIsFlatMode() && self.liveBlur) { + self.menuWrapperView.frame = CGRectMake(0, -self.combinedHeight, self.viewToShowFrom.bounds.size.width, self.combinedHeight); + CGFloat height = MIN(self.viewToShowFrom.bounds.size.height - self.navigationBarOffset, self.combinedHeight); + self.menuView.frame = CGRectMake(0, 0, self.viewToShowFrom.bounds.size.width, height); + self.menuView.contentSize = CGSizeMake(self.viewToShowFrom.bounds.size.width, self.combinedHeight); + + if (REUIKitIsFlatMode() && self.liveBlur) { self.toolbar.frame = self.menuWrapperView.bounds; } self.containerView.frame = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); @@ -257,7 +263,7 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view animations:^{ self.backgroundView.alpha = self.backgroundAlpha; CGRect frame = self.menuView.frame; - frame.origin.y = -40.0 - self.separatorHeight; + frame.origin.y = self.navigationBarOffset; self.menuWrapperView.frame = frame; } completion:^(BOOL finished) { self.isAnimating = NO; @@ -272,7 +278,7 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view animations:^{ self.backgroundView.alpha = self.backgroundAlpha; CGRect frame = self.menuView.frame; - frame.origin.y = -40.0 - self.separatorHeight; + frame.origin.y = self.navigationBarOffset; self.menuWrapperView.frame = frame; } completion:^(BOOL finished) { self.isAnimating = NO; @@ -289,7 +295,7 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view animations:^{ self.backgroundView.alpha = self.backgroundAlpha; CGRect frame = self.menuView.frame; - frame.origin.y = -40.0 - self.separatorHeight; + frame.origin.y = self.navigationBarOffset; self.menuWrapperView.frame = frame; } completion:^(BOOL finished) { self.isAnimating = NO; @@ -298,6 +304,25 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view } }]; } + + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(updateViewOnRotate:) + name:UIDeviceOrientationDidChangeNotification + object:nil]; +} + +-(CGFloat) navigationBarOffset { + CGFloat statusBarHeight = MIN([[UIApplication sharedApplication] statusBarFrame].size.width, [[UIApplication sharedApplication] statusBarFrame].size.height); + + return self.navigationBar ? self.navigationBar.frame.size.height + statusBarHeight : 0; +} + +-(void) updateViewOnRotate:(NSNotification*) notification { + CGFloat height = MIN(self.viewToShowFrom.bounds.size.height - self.navigationBarOffset, self.combinedHeight); + self.menuView.frame = CGRectMake(0, 0, self.viewToShowFrom.bounds.size.width, height); + self.menuView.contentSize = CGSizeMake(self.viewToShowFrom.bounds.size.width, self.combinedHeight); + self.menuWrapperView.frame = CGRectMake(0, self.navigationBarOffset, self.viewToShowFrom.bounds.size.width, height); } - (void)showInView:(UIView *)view @@ -313,8 +338,6 @@ - (void)showFromNavigationController:(UINavigationController *)navigationControl self.navigationBar = navigationController.navigationBar; [self showFromRect:CGRectMake(0, 0, navigationController.navigationBar.frame.size.width, navigationController.view.frame.size.height) inView:navigationController.view]; - self.containerView.appearsBehindNavigationBar = self.appearsBehindNavigationBar; - self.containerView.navigationBar = navigationController.navigationBar; if (self.appearsBehindNavigationBar) { [navigationController.view bringSubviewToFront:navigationController.navigationBar]; } @@ -325,16 +348,15 @@ - (void)closeWithCompletion:(void (^)(void))completion if (self.isAnimating) return; self.isAnimating = YES; - - CGFloat navigationBarOffset = self.appearsBehindNavigationBar && self.navigationBar ? 64 : 0; - + [[NSNotificationCenter defaultCenter] removeObserver:self]; + void (^closeMenu)(void) = ^{ [UIView animateWithDuration:self.closeAnimationDuration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseInOut animations:^ { CGRect frame = self.menuView.frame; - frame.origin.y = - self.combinedHeight - navigationBarOffset; + frame.origin.y = - self.combinedHeight - self.navigationBarOffset; self.menuWrapperView.frame = frame; self.backgroundView.alpha = 0; } completion:^(BOOL finished) { @@ -388,7 +410,7 @@ - (void)close - (CGFloat)combinedHeight { - return self.items.count * self.itemHeight + self.items.count * self.separatorHeight + 40.0 + self.cornerRadius; + return self.items.count * self.itemHeight + self.items.count * self.separatorHeight + self.cornerRadius; } - (void)setNeedsLayout diff --git a/REMenu/REMenuContainerView.h b/REMenu/REMenuContainerView.h deleted file mode 100644 index 47f3492..0000000 --- a/REMenu/REMenuContainerView.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// REMenuContainerView.h -// REMenu -// -// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) -// -// 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 - -@interface REMenuContainerView : UIView - -@property (strong, readwrite, nonatomic) UINavigationBar *navigationBar; -@property (assign, readwrite, nonatomic) BOOL appearsBehindNavigationBar; - -@end diff --git a/REMenu/REMenuContainerView.m b/REMenu/REMenuContainerView.m deleted file mode 100644 index ce5e9a5..0000000 --- a/REMenu/REMenuContainerView.m +++ /dev/null @@ -1,51 +0,0 @@ -// -// REMenuContainerView.m -// REMenu -// -// Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) -// -// 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 "REMenuContainerView.h" -#import - -@implementation REMenuContainerView - -- (void)layoutSubviews -{ - [super layoutSubviews]; - UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; - - CGFloat landscapeOffset = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone ? 32.0 : 44.0; - - if (self.navigationBar && !self.appearsBehindNavigationBar) { - CGRect frame = self.frame; - frame.origin.y = self.navigationBar.frame.origin.y + (UIDeviceOrientationIsPortrait(orientation) ? 44.0 : landscapeOffset); - self.frame = frame; - } - - if (self.appearsBehindNavigationBar) { - CGRect frame = self.frame; - frame.origin.y = (UIDeviceOrientationIsPortrait(orientation) ? 44.0 : landscapeOffset) - 44; - self.frame = frame; - } -} - -@end