diff --git a/FPPopover.podspec b/FPPopover.podspec index df3c2cf..02771d8 100644 --- a/FPPopover.podspec +++ b/FPPopover.podspec @@ -7,9 +7,10 @@ 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 s.frameworks = 'QuartzCore', 'UIKit' end 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 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;