From f4611a631be12b49a40b47c99c6e8a82d63c4336 Mon Sep 17 00:00:00 2001 From: Ilya Timofeev Date: Wed, 3 Sep 2014 12:52:59 +0400 Subject: [PATCH 1/2] UIView with REMenuItems replaced with UIScrollView to be able to scroll when items not fit to the screen --- REMenu/REMenu.m | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/REMenu/REMenu.m b/REMenu/REMenu.m index 7d0859d..71bd830 100644 --- a/REMenu/REMenu.m +++ b/REMenu/REMenu.m @@ -35,7 +35,7 @@ @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) UIButton *backgroundButton; @@ -43,6 +43,7 @@ @interface REMenu () @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 @@ -115,7 +116,9 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view self.isOpen = YES; self.isAnimating = YES; - + + self.viewToShowFrom = view; + // Create views // self.containerView = ({ @@ -129,9 +132,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; } @@ -222,8 +225,11 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view // 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) { + CGFloat height = MIN(self.viewToShowFrom.bounds.size.height, self.combinedHeight) + navigationBarOffset; + self.menuView.frame = CGRectMake(0, 0, self.viewToShowFrom.bounds.size.width, height); + self.menuView.contentSize = CGSizeMake(rect.size.width, self.combinedHeight + navigationBarOffset); + + 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); @@ -284,6 +290,19 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view self.isAnimating = NO; }]; } + + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(updateViewOnRotate:) + name:UIDeviceOrientationDidChangeNotification + object:nil]; +} + +-(void) updateViewOnRotate:(NSNotification*) notification { + CGFloat navigationBarOffset = self.appearsBehindNavigationBar && self.navigationBar ? 64 : 0; + CGFloat height = MIN(self.viewToShowFrom.bounds.size.height, self.combinedHeight) + navigationBarOffset; + self.menuView.frame = CGRectMake(0, 0, self.viewToShowFrom.bounds.size.width, height); + self.menuView.contentSize = CGSizeMake(self.viewToShowFrom.bounds.size.width, self.combinedHeight + navigationBarOffset); } - (void)showInView:(UIView *)view @@ -311,7 +330,9 @@ - (void)closeWithCompletion:(void (^)(void))completion if (self.isAnimating) return; self.isAnimating = YES; - + + [[NSNotificationCenter defaultCenter] removeObserver:self]; + CGFloat navigationBarOffset = self.appearsBehindNavigationBar && self.navigationBar ? 64 : 0; void (^closeMenu)(void) = ^{ From b34d5c0033a65d09e4c28a979e6cd4b2256c46d2 Mon Sep 17 00:00:00 2001 From: Ilya Timofeev Date: Thu, 25 Sep 2014 10:25:57 +0400 Subject: [PATCH 2/2] UIView with REMenuItems replaced with UIScrollView to be able to scroll when items not fit to the screen --- REMenu/REMenu.m | 40 ++++++++++++++-------------- REMenu/REMenuContainerView.h | 33 ----------------------- REMenu/REMenuContainerView.m | 51 ------------------------------------ 3 files changed, 21 insertions(+), 103 deletions(-) delete mode 100644 REMenu/REMenuContainerView.h delete mode 100644 REMenu/REMenuContainerView.m diff --git a/REMenu/REMenu.m b/REMenu/REMenu.m index 71bd830..eeb0f14 100644 --- a/REMenu/REMenu.m +++ b/REMenu/REMenu.m @@ -37,7 +37,7 @@ @interface REMenu () @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; @@ -122,7 +122,7 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view // Create views // self.containerView = ({ - REMenuContainerView *view = [[REMenuContainerView alloc] init]; + UIView *view = [[UIView alloc] init]; view.clipsToBounds = YES; view.autoresizingMask = UIViewAutoresizingFlexibleWidth; @@ -186,8 +186,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) { @@ -198,7 +196,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; @@ -206,7 +204,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 @@ -221,13 +219,13 @@ - (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); - CGFloat height = MIN(self.viewToShowFrom.bounds.size.height, self.combinedHeight) + navigationBarOffset; + 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(rect.size.width, self.combinedHeight + navigationBarOffset); + self.menuView.contentSize = CGSizeMake(self.viewToShowFrom.bounds.size.width, self.combinedHeight); if (REUIKitIsFlatMode() && self.liveBlur) { self.toolbar.frame = self.menuWrapperView.bounds; @@ -258,7 +256,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; @@ -270,7 +268,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; @@ -284,7 +282,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,11 +296,17 @@ - (void)showFromRect:(CGRect)rect inView:(UIView *)view 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 navigationBarOffset = self.appearsBehindNavigationBar && self.navigationBar ? 64 : 0; - CGFloat height = MIN(self.viewToShowFrom.bounds.size.height, self.combinedHeight) + navigationBarOffset; + 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 + navigationBarOffset); + 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 @@ -318,8 +322,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]; } @@ -389,7 +391,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