From 59a2cbf25a5559ce37121dfd23c609f0fce245dc Mon Sep 17 00:00:00 2001 From: Justin Buchanan Date: Mon, 2 Dec 2013 16:01:42 -0500 Subject: [PATCH 1/3] require ARC --- FPPopover.podspec | 1 + FPPopoverDemo.xcodeproj/project.pbxproj | 2 ++ 2 files changed, 3 insertions(+) diff --git a/FPPopover.podspec b/FPPopover.podspec index df3c2cf..55a31cd 100644 --- a/FPPopover.podspec +++ b/FPPopover.podspec @@ -10,6 +10,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/50pixels/FPPopover.git', :tag => '1.4.1' } s.platform = :ios s.source_files = '*.{h,m}' + s.requires_arc = true s.frameworks = 'QuartzCore', 'UIKit' end diff --git a/FPPopoverDemo.xcodeproj/project.pbxproj b/FPPopoverDemo.xcodeproj/project.pbxproj index 2f2b7e0..a032fc8 100644 --- a/FPPopoverDemo.xcodeproj/project.pbxproj +++ b/FPPopoverDemo.xcodeproj/project.pbxproj @@ -560,6 +560,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ENABLE_OBJC_ARC = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -585,6 +586,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + CLANG_ENABLE_OBJC_ARC = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; GCC_C_LANGUAGE_STANDARD = gnu99; From e42ab8f37795553aee109c1bbbd9a4e568425c2b Mon Sep 17 00:00:00 2001 From: Justin Buchanan Date: Mon, 2 Dec 2013 16:39:16 -0500 Subject: [PATCH 2/3] point Podspec at BluMenlo repo, master branch --- FPPopover.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FPPopover.podspec b/FPPopover.podspec index 55a31cd..02771d8 100644 --- a/FPPopover.podspec +++ b/FPPopover.podspec @@ -7,7 +7,7 @@ Pod::Spec.new do |s| s.homepage = 'http://www.gingerbeard.me' s.author = { 'Alvise Susmel' => 'alvise@50pixels.com' } - s.source = { :git => 'https://github.com/50pixels/FPPopover.git', :tag => '1.4.1' } + s.source = { :git => 'https://github.com/BluMenlo/FPPopover.git', :branch => :master } s.platform = :ios s.source_files = '*.{h,m}' s.requires_arc = true From e40fe7d0e04619473a8e7d12d8ac302401cf2934 Mon Sep 17 00:00:00 2001 From: Goffredo Marocchi Date: Fri, 13 Dec 2013 13:33:50 +0000 Subject: [PATCH 3/3] Allow the API user to specify how the view should behave when touched and to block touches from dismissing it until specified otherwise. Added the ability to provide autoresizingmask and contentSize when initialising the popover controller object. Signed-off-by: Goffredo Marocchi --- FPPopoverController.h | 21 ++++-- FPPopoverController.m | 156 +++++++++++++++++++++++++++--------------- 2 files changed, 119 insertions(+), 58 deletions(-) diff --git a/FPPopoverController.h b/FPPopoverController.h index f8aee39..4bc67b3 100644 --- a/FPPopoverController.h +++ b/FPPopoverController.h @@ -21,7 +21,7 @@ @optional - (void)popoverControllerDidDismissPopover:(FPPopoverController *)popoverController; -- (void)presentedNewPopoverController:(FPPopoverController *)newPopoverController +- (void)presentedNewPopoverController:(FPPopoverController *)newPopoverController shouldDismissVisiblePopover:(FPPopoverController*)visiblePopoverController; @end @@ -31,9 +31,9 @@ } //ARC-enable and disable support #if __has_feature(objc_arc) - @property(nonatomic,weak) id delegate; +@property(nonatomic,weak) id delegate; #else - @property(nonatomic,assign) id delegate; +@property(nonatomic,assign) id delegate; #endif /** @brief FPPopoverArrowDirectionAny, FPPopoverArrowDirectionVertical or FPPopoverArrowDirectionHorizontal for automatic arrow direction. @@ -55,11 +55,24 @@ /** @brief Popover border, default is YES **/ @property(nonatomic, assign) BOOL border; +/** @brief Popover dismiss upon touch, default is YES **/ +@property(nonatomic, assign) BOOL dismissUponTouch; + /** @brief Initialize the popover with the content view controller **/ -(id)initWithViewController:(UIViewController*)viewController; -(id)initWithViewController:(UIViewController*)viewController - delegate:(id)delegate; + delegate:(id)delegate + autoresizingMask:(UIViewAutoresizing)autoresizingMask; +-(id)initWithViewController:(UIViewController*)viewController + delegate:(id)delegate + autoresizingMask:(UIViewAutoresizing)autoresizingMask + contentSize:(CGSize)contentSize; +-(id)initWithViewController:(UIViewController*)viewController + delegate:(id)delegate + autoresizingMask:(UIViewAutoresizing)autoresizingMask + contentSize:(CGSize)contentSize + dismissUponTouch:(BOOL)dismissUponTouch; /** @brief Presenting the popover from a specified view **/ -(void)presentPopoverFromView:(UIView*)fromView; diff --git a/FPPopoverController.m b/FPPopoverController.m index 28406d4..c48efbb 100644 --- a/FPPopoverController.m +++ b/FPPopoverController.m @@ -35,7 +35,7 @@ -(CGFloat)parentHeight; #pragma mark Space management /* This methods help the controller to found a proper way to display the view. - * If the "from point" will be on the left, the arrow will be on the left and the + * If the "from point" will be on the left, the arrow will be on the left and the * view will be move on the right of the from point. */ @@ -56,14 +56,14 @@ @implementation FPPopoverController -(void)addObservers { - [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(deviceOrientationDidChange:) + name:@"UIDeviceOrientationDidChangeNotification" + object:nil]; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(deviceOrientationDidChange:) - name:@"UIDeviceOrientationDidChangeNotification" - object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willPresentNewPopover:) name:@"FPNewPopoverPresented" object:nil]; @@ -88,7 +88,7 @@ -(void)dealloc #ifdef FP_DEBUG NSLog(@"FPPopoverController dealloc"); #endif - + SAFE_ARC_RELEASE(_contentView); SAFE_ARC_RELEASE(_touchView); self.delegate = nil; @@ -103,11 +103,41 @@ -(id)initWithViewController:(UIViewController*)viewController { return [self initWithViewController:viewController delegate:nil]; } +-(id)initWithViewController:(UIViewController*)viewController + delegate:(id)delegate { + return [self initWithViewController:viewController + delegate:delegate + autoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; +} + -(id)initWithViewController:(UIViewController*)viewController delegate:(id)delegate + autoresizingMask:(UIViewAutoresizing)autoresizingMask { + return [self initWithViewController:viewController + delegate:delegate + autoresizingMask:autoresizingMask + contentSize:CGSizeMake(200, 300)]; +} + +-(id)initWithViewController:(UIViewController*)viewController + delegate:(id)delegate + autoresizingMask:(UIViewAutoresizing)autoresizingMask + contentSize:(CGSize)contentSize { + return [self initWithViewController:viewController + delegate:delegate + autoresizingMask:autoresizingMask + contentSize:contentSize + dismissUponTouch:YES]; +} + +-(id)initWithViewController:(UIViewController*)viewController + delegate:(id)delegate + autoresizingMask:(UIViewAutoresizing)autoresizingMask + contentSize:(CGSize)contentSize + dismissUponTouch:(BOOL)dismissUponTouch{ self = [super init]; - if(self) + if(self != nil) { self.delegate = delegate; @@ -115,10 +145,12 @@ -(id)initWithViewController:(UIViewController*)viewController self.arrowDirection = FPPopoverArrowDirectionAny; self.view.userInteractionEnabled = YES; _border = YES; + _dismissUponTouch = dismissUponTouch; _touchView = [[FPTouchView alloc] initWithFrame:self.view.bounds]; + _touchView.userInteractionEnabled = _dismissUponTouch; _touchView.backgroundColor = [UIColor clearColor]; - _touchView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _touchView.autoresizingMask = autoresizingMask; _touchView.clipsToBounds = NO; [self.view addSubview:_touchView]; @@ -133,22 +165,23 @@ -(id)initWithViewController:(UIViewController*)viewController [_touchView setTouchedOutsideBlock:^{ [bself dismissPopoverAnimated:YES]; }]; - - self.contentSize = CGSizeMake(200, 300); //default size - - _contentView = [[FPPopoverView alloc] initWithFrame:CGRectMake(0, 0, - self.contentSize.width, self.contentSize.height)]; + + + self.contentSize = contentSize; //default size + + _contentView = [[FPPopoverView alloc] initWithFrame:CGRectMake(0, 0, + self.contentSize.width, self.contentSize.height)]; _viewController = SAFE_ARC_RETAIN(viewController); [_touchView addSubview:_contentView]; [_contentView addContentView:_viewController.view]; - _viewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _viewController.view.autoresizingMask = autoresizingMask; + self.view.autoresizingMask = autoresizingMask; self.view.clipsToBounds = NO; - - _touchView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + + _touchView.autoresizingMask = autoresizingMask; _touchView.clipsToBounds = NO; //setting contentview @@ -181,7 +214,7 @@ -(void)setupView //view position, size and best arrow direction [self bestArrowDirectionAndFrameFromView:_fromView]; - + [_contentView setNeedsDisplay]; [_touchView setNeedsDisplay]; } @@ -193,7 +226,7 @@ - (void)viewDidLoad //initialize and load the content view [_contentView setArrowDirection:FPPopoverArrowDirectionUp]; [_contentView addContentView:_viewController.view]; - + [self setupView]; [self addObservers]; } @@ -233,12 +266,12 @@ -(void)presentPopoverFromPoint:(CGPoint)fromPoint } _contentView.relativeOrigin = [_parentView convertPoint:fromPoint toView:_contentView]; - + [self.view removeFromSuperview]; NSArray *windows = [UIApplication sharedApplication].windows; if(windows.count > 0) { - _parentView=nil; + _parentView=nil; _window = [windows objectAtIndex:0]; //keep the first subview if(_window.subviews.count > 0) @@ -248,14 +281,12 @@ -(void)presentPopoverFromPoint:(CGPoint)fromPoint [_viewController viewDidAppear:YES]; } - } + } else { [self dismissPopoverAnimated:NO]; } - - [self setupView]; self.view.alpha = 0.0; [UIView animateWithDuration:0.2 animations:^{ @@ -289,7 +320,7 @@ -(CGPoint)originFromView:(UIView*)fromView else if([_contentView arrowDirection] == FPPopoverArrowDirectionDown) { p.x = fromView.frame.origin.x + fromView.frame.size.width/2.0; - p.y = fromView.frame.origin.y; + p.y = fromView.frame.origin.y; } else if([_contentView arrowDirection] == FPPopoverArrowDirectionLeft) { @@ -301,7 +332,7 @@ -(CGPoint)originFromView:(UIView*)fromView p.x = fromView.frame.origin.x; p.y = fromView.frame.origin.y + fromView.frame.size.height/2.0; } - + return p; } @@ -319,8 +350,8 @@ -(void)dismissPopover { [self.delegate popoverControllerDidDismissPopover:self]; } - _window=nil; - _parentView=nil; + _window=nil; + _parentView=nil; } @@ -346,7 +377,7 @@ -(void)dismissPopoverAnimated:(BOOL)animated completion:(FPPopoverCompletion)com if (completionBlock) completionBlock(); } - + } -(void)setOrigin:(CGPoint)origin @@ -361,9 +392,9 @@ -(void)setOrigin:(CGPoint)origin -(void)deviceOrientationDidChange:(NSNotification*)notification { _deviceOrientation = [UIDevice currentDevice].orientation; - + BOOL shouldResetView = NO; - + //iOS6 has a new orientation implementation. //we ask to reset the view if is >= 6.0 if ([_viewController respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)] && @@ -392,10 +423,10 @@ -(void)deviceOrientationDidChange:(NSNotification*)notification { shouldResetView = YES; } - + if (shouldResetView) [UIView animateWithDuration:0.2 animations:^{ - [self setupView]; + [self setupView]; }]; } @@ -443,20 +474,20 @@ -(CGRect)bestArrowDirectionAndFrameFromView:(UIView*)v CGFloat hb = [self parentHeight] - (p.y + v.frame.size.height); //on the bottom CGFloat wl = p.x; //on the left CGFloat wr = [self parentWidth] - (p.x + v.frame.size.width); //on the right - + CGFloat best_h = MAX(ht, hb); //much space down or up ? CGFloat best_w = MAX(wl, wr); CGRect r; r.size = self.contentSize; - + FPPopoverArrowDirection bestDirection; - //if the user wants vertical arrow, check if the content will fit vertically - if(FPPopoverArrowDirectionIsVertical(self.arrowDirection) || + //if the user wants vertical arrow, check if the content will fit vertically + if(FPPopoverArrowDirectionIsVertical(self.arrowDirection) || (self.arrowDirection == FPPopoverArrowDirectionAny && best_h >= best_w)) { - + //ok, will be vertical if(ht == best_h || self.arrowDirection == FPPopoverArrowDirectionDown) { @@ -470,16 +501,16 @@ -(CGRect)bestArrowDirectionAndFrameFromView:(UIView*)v { //on the bottom and arrow up bestDirection = FPPopoverArrowDirectionUp; - + r.origin.x = p.x + v.frame.size.width/2.0 - r.size.width/2.0; r.origin.y = p.y + v.frame.size.height; } - + } - else + else { //ok, will be horizontal //the arrow must NOT be forced to left @@ -487,26 +518,26 @@ -(CGRect)bestArrowDirectionAndFrameFromView:(UIView*)v { //on the left and arrow right bestDirection = FPPopoverArrowDirectionRight; - + r.origin.x = p.x - r.size.width; r.origin.y = p.y + v.frame.size.height/2.0 - r.size.height/2.0; - + } else { //on the right then arrow left bestDirection = FPPopoverArrowDirectionLeft; - + r.origin.x = p.x + v.frame.size.width; r.origin.y = p.y + v.frame.size.height/2.0 - r.size.height/2.0; } - + } - //need to moved left ? + //need to moved left ? if(r.origin.x + r.size.width > [self parentWidth]) { r.origin.x = [self parentWidth] - r.size.width; @@ -544,20 +575,31 @@ -(CGRect)bestArrowDirectionAndFrameFromView:(UIView*)v { if(r.origin.y <= 20) r.origin.y += 20; } - + //check if the developer wants and arrow if(self.arrowDirection != FPPopoverNoArrow) _contentView.arrowDirection = bestDirection; //no arrow else _contentView.arrowDirection = FPPopoverNoArrow; - + //using the frame calculated - _contentView.frame = r; - + + if (self.view.autoresizingMask != UIViewAutoresizingNone) + { + _contentView.frame = r; + } + else + { + _contentView.frame = CGRectMake(r.origin.x, + r.origin.y, + _contentView.frame.size.width, + _contentView.frame.size.height); + } + self.origin = CGPointMake(p.x + v.frame.size.width/2.0, p.y + v.frame.size.height/2.0); _contentView.relativeOrigin = [_parentView convertPoint:self.origin toView:_contentView]; - + return r; } @@ -587,6 +629,12 @@ -(void)setShadowsHidden:(BOOL)hidden } } +- (void) setDismissUponTouch:(BOOL)dismissUponTouch +{ + _dismissUponTouch = dismissUponTouch; + self.touchView.userInteractionEnabled = _dismissUponTouch; +} + #pragma mark 3D Border -(void)setBorder:(BOOL)border