diff --git a/Classes/Popover/ARCHelper.h b/Classes/Popover/ARCHelper.h new file mode 100644 index 0000000..492b012 --- /dev/null +++ b/Classes/Popover/ARCHelper.h @@ -0,0 +1,59 @@ +// +// ARC Helper +// +// Version 2.1 +// +// Created by Nick Lockwood on 05/01/2012. +// Copyright 2012 Charcoal Design +// +// Distributed under the permissive zlib license +// Get the latest version from here: +// +// https://gist.github.com/1563325 +// + +#ifndef ah_retain +#if __has_feature(objc_arc) +#define ah_retain self +#define ah_dealloc self +#define release self +#define autorelease self +#else +#define ah_retain retain +#define ah_dealloc dealloc +#define __bridge +#endif +#endif + +// Weak reference support + +#import +#if (!__has_feature(objc_arc)) || \ +(defined __IPHONE_OS_VERSION_MIN_REQUIRED && \ +__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0) || \ +(defined __MAC_OS_X_VERSION_MIN_REQUIRED && \ +__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7) +#undef weak +#define weak unsafe_unretained +#undef __weak +#define __weak __unsafe_unretained +#endif + +// Weak delegate support + +#ifndef ah_weak +#import +#if (__has_feature(objc_arc)) && \ +((defined __IPHONE_OS_VERSION_MIN_REQUIRED && \ +__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_5_0) || \ +(defined __MAC_OS_X_VERSION_MIN_REQUIRED && \ +__MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_7)) +#define ah_weak weak +#define __ah_weak __weak +#else +#define ah_weak unsafe_unretained +#define __ah_weak __unsafe_unretained +#endif +#endif + +// ARC Helper ends diff --git a/Classes/Popover/WEPopoverContainerView.m b/Classes/Popover/WEPopoverContainerView.m index 78e3b14..a9de52f 100755 --- a/Classes/Popover/WEPopoverContainerView.m +++ b/Classes/Popover/WEPopoverContainerView.m @@ -19,7 +19,7 @@ - (void)dealloc { self.downArrowImageName = nil; self.leftArrowImageName = nil; self.rightArrowImageName = nil; - [super dealloc]; + [super ah_dealloc]; } @end @@ -52,7 +52,7 @@ - (id)initWithSize:(CGSize)theSize [self initFrame]; self.backgroundColor = [UIColor clearColor]; UIImage *theImage = [UIImage imageNamed:properties.bgImageName]; - bgImage = [[theImage stretchableImageWithLeftCapWidth:properties.leftBgCapSize topCapHeight:properties.topBgCapSize] retain]; + bgImage = [[theImage stretchableImageWithLeftCapWidth:properties.leftBgCapSize topCapHeight:properties.topBgCapSize] ah_retain]; self.clipsToBounds = YES; self.userInteractionEnabled = YES; @@ -65,7 +65,7 @@ - (void)dealloc { [contentView release]; [bgImage release]; [arrowImage release]; - [super dealloc]; + [super ah_dealloc]; } - (void)drawRect:(CGRect)rect { @@ -103,7 +103,7 @@ - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - (void)setContentView:(UIView *)v { if (v != contentView) { [contentView release]; - contentView = [v retain]; + contentView = [v ah_retain]; contentView.frame = self.contentRect; [self addSubview:contentView]; } @@ -123,7 +123,7 @@ - (void)initFrame { bgRect = CGRectOffset(bgRect, arrowOffset.x, arrowOffset.y); arrowRect = CGRectOffset(arrowRect, arrowOffset.x, arrowOffset.y); - self.frame = theFrame; + self.frame = CGRectIntegral(theFrame); } - (CGSize)contentSize { @@ -141,7 +141,7 @@ - (CGRect)contentRect { - (void)setProperties:(WEPopoverContainerViewProperties *)props { if (properties != props) { [properties release]; - properties = [props retain]; + properties = [props ah_retain]; } } @@ -345,16 +345,16 @@ - (void)determineGeometryForSize:(CGSize)theSize anchorRect:(CGRect)anchorRect d switch (arrowDirection) { case UIPopoverArrowDirectionUp: - arrowImage = [upArrowImage retain]; + arrowImage = [upArrowImage ah_retain]; break; case UIPopoverArrowDirectionDown: - arrowImage = [downArrowImage retain]; + arrowImage = [downArrowImage ah_retain]; break; case UIPopoverArrowDirectionLeft: - arrowImage = [leftArrowImage retain]; + arrowImage = [leftArrowImage ah_retain]; break; case UIPopoverArrowDirectionRight: - arrowImage = [rightArrowImage retain]; + arrowImage = [rightArrowImage ah_retain]; break; } } diff --git a/Classes/Popover/WEPopoverController.h b/Classes/Popover/WEPopoverController.h index 324c869..1d30a87 100755 --- a/Classes/Popover/WEPopoverController.h +++ b/Classes/Popover/WEPopoverController.h @@ -29,7 +29,7 @@ BOOL popoverVisible; UIPopoverArrowDirection popoverArrowDirection; - id delegate; + id __ah_weak delegate; CGSize popoverContentSize; WEPopoverContainerViewProperties *containerViewProperties; id context; @@ -41,12 +41,14 @@ @property (nonatomic, readonly) UIView *view; @property (nonatomic, readonly, getter=isPopoverVisible) BOOL popoverVisible; @property (nonatomic, readonly) UIPopoverArrowDirection popoverArrowDirection; -@property (nonatomic, assign) id delegate; +@property (nonatomic, ah_weak) id delegate; @property (nonatomic, assign) CGSize popoverContentSize; @property (nonatomic, retain) WEPopoverContainerViewProperties *containerViewProperties; @property (nonatomic, retain) id context; @property (nonatomic, copy) NSArray *passthroughViews; ++ (void)setCustomKeyViewIndex:(NSUInteger)keyViewIndex; + - (id)initWithContentViewController:(UIViewController *)theContentViewController; - (void)dismissPopoverAnimated:(BOOL)animated; diff --git a/Classes/Popover/WEPopoverController.m b/Classes/Popover/WEPopoverController.m index 33d0f78..40fe96f 100755 --- a/Classes/Popover/WEPopoverController.m +++ b/Classes/Popover/WEPopoverController.m @@ -10,7 +10,14 @@ #import "WEPopoverParentView.h" #import "UIBarButtonItem+WEPopover.h" -#define FADE_DURATION 0.25 +#define FADE_DURATION 0.25 +#define DIM_ALPHA 0.25 + +@interface WEPopoverController () + +@property (nonatomic, retain) UIView *dimView; + +@end @interface WEPopoverController(Private) @@ -36,6 +43,13 @@ @implementation WEPopoverController @synthesize context; @synthesize passthroughViews; +static NSUInteger customKeyViewIndex; + ++ (void)setCustomKeyViewIndex:(NSUInteger)keyViewIndex +{ + customKeyViewIndex = keyViewIndex; +} + - (id)init { if ((self = [super init])) { } @@ -55,13 +69,14 @@ - (void)dealloc { [containerViewProperties release]; [passthroughViews release]; self.context = nil; - [super dealloc]; + self.dimView = nil; + [super ah_dealloc]; } - (void)setContentViewController:(UIViewController *)vc { if (vc != contentViewController) { [contentViewController release]; - contentViewController = [vc retain]; + contentViewController = [vc ah_retain]; popoverContentSize = CGSizeZero; } } @@ -76,7 +91,7 @@ - (void)setPassthroughViews:(NSArray *)array { [self updateBackgroundPassthroughViews]; } -- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)theContext { +- (void)fadeAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)theContext { if ([animationID isEqual:@"FadeIn"]) { self.view.userInteractionEnabled = YES; @@ -91,7 +106,7 @@ - (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished c [backgroundView release]; backgroundView = nil; - BOOL userInitiatedDismissal = [(NSNumber *)theContext boolValue]; + BOOL userInitiatedDismissal = [(__bridge NSNumber *)theContext boolValue]; if (userInitiatedDismissal) { //Only send message to delegate in case the user initiated this event, which is if he touched outside the view @@ -124,7 +139,7 @@ - (void)presentPopoverFromRect:(CGRect)rect [self dismissPopoverAnimated:NO]; //First force a load view for the contentViewController so the popoverContentSize is properly initialized - contentViewController.view; + contentViewController.view = contentViewController.view; if (CGSizeEqualToSize(popoverContentSize, CGSizeZero)) { popoverContentSize = contentViewController.contentSizeForViewInPopover; @@ -165,21 +180,30 @@ - (void)presentPopoverFromRect:(CGRect)rect [contentViewController viewWillAppear:animated]; [self.view becomeFirstResponder]; + + [_dimView removeFromSuperview]; + self.dimView = [[[UIView alloc] initWithFrame:keyView.bounds] autorelease]; + _dimView.backgroundColor = [UIColor blackColor]; + [keyView insertSubview:self.dimView belowSubview:backgroundView]; if (animated) { self.view.alpha = 0.0; + _dimView.alpha = 0.0; [UIView beginAnimations:@"FadeIn" context:nil]; [UIView setAnimationDelegate:self]; - [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; + [UIView setAnimationDidStopSelector:@selector(fadeAnimationDidStop:finished:context:)]; [UIView setAnimationDuration:FADE_DURATION]; self.view.alpha = 1.0; + _dimView.alpha = DIM_ALPHA; [UIView commitAnimations]; } else { popoverVisible = YES; + _dimView.alpha = DIM_ALPHA; + [contentViewController viewDidAppear:animated]; } } @@ -217,7 +241,7 @@ @implementation WEPopoverController(Private) - (UIView *)keyView { UIWindow *w = [[UIApplication sharedApplication] keyWindow]; if (w.subviews.count > 0) { - return [w.subviews objectAtIndex:0]; + return [w.subviews objectAtIndex:customKeyViewIndex]; } else { return w; } @@ -226,7 +250,7 @@ - (UIView *)keyView { - (void)setView:(UIView *)v { if (view != v) { [view release]; - view = [v retain]; + view = [v ah_retain]; } } @@ -243,19 +267,22 @@ - (void)dismissPopoverAnimated:(BOOL)animated userInitiated:(BOOL)userInitiated if (animated) { self.view.userInteractionEnabled = NO; - [UIView beginAnimations:@"FadeOut" context:[NSNumber numberWithBool:userInitiated]]; + [UIView beginAnimations:@"FadeOut" context:(__bridge void *)([NSNumber numberWithBool:userInitiated])]; [UIView setAnimationDelegate:self]; - [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; + [UIView setAnimationDidStopSelector:@selector(fadeAnimationDidStop:finished:context:)]; [UIView setAnimationDuration:FADE_DURATION]; self.view.alpha = 0.0; + _dimView.alpha = 0.0; [UIView commitAnimations]; } else { [contentViewController viewDidDisappear:animated]; [self.view removeFromSuperview]; self.view = nil; + [_dimView removeFromSuperview]; + self.dimView = nil; [backgroundView removeFromSuperview]; [backgroundView release]; backgroundView = nil; @@ -275,31 +302,36 @@ - (CGRect)displayAreaForView:(UIView *)theView { //Enable to use the simple popover style - (WEPopoverContainerViewProperties *)defaultContainerViewProperties { - WEPopoverContainerViewProperties *ret = [[WEPopoverContainerViewProperties new] autorelease]; - - CGSize imageSize = CGSizeMake(30.0f, 30.0f); - NSString *bgImageName = @"popoverBgSimple.png"; - CGFloat bgMargin = 6.0; - CGFloat contentMargin = 2.0; - - ret.leftBgMargin = bgMargin; - ret.rightBgMargin = bgMargin; - ret.topBgMargin = bgMargin; - ret.bottomBgMargin = bgMargin; - ret.leftBgCapSize = imageSize.width/2; - ret.topBgCapSize = imageSize.height/2; - ret.bgImageName = bgImageName; - ret.leftContentMargin = contentMargin; - ret.rightContentMargin = contentMargin; - ret.topContentMargin = contentMargin; - ret.bottomContentMargin = contentMargin; - ret.arrowMargin = 1.0; - - ret.upArrowImageName = @"popoverArrowUpSimple.png"; - ret.downArrowImageName = @"popoverArrowDownSimple.png"; - ret.leftArrowImageName = @"popoverArrowLeftSimple.png"; - ret.rightArrowImageName = @"popoverArrowRightSimple.png"; - return ret; + WEPopoverContainerViewProperties *ret = [[[WEPopoverContainerViewProperties alloc] init] autorelease]; + + NSString *bgImageName = nil; + CGFloat bgMargin = 0.0; + CGFloat bgCapSize = 0.0; + CGFloat contentMargin = 4.0; + + bgImageName = @"popoverBg.png"; + + // These constants are determined by the popoverBg.png image file and are image dependent + bgMargin = 13; // margin width of 13 pixels on all sides popoverBg.png (62 pixels wide - 36 pixel background) / 2 == 26 / 2 == 13 + bgCapSize = 31; // ImageSize/2 == 62 / 2 == 31 pixels + + ret.leftBgMargin = bgMargin; + ret.rightBgMargin = bgMargin; + ret.topBgMargin = bgMargin; + ret.bottomBgMargin = bgMargin; + ret.leftBgCapSize = bgCapSize; + ret.topBgCapSize = bgCapSize; + ret.bgImageName = bgImageName; + ret.leftContentMargin = contentMargin; + ret.rightContentMargin = contentMargin - 1; // Need to shift one pixel for border to look correct + ret.topContentMargin = contentMargin - 1; + ret.bottomContentMargin = contentMargin; + + ret.upArrowImageName = @"popoverArrowUp.png"; + ret.downArrowImageName = @"popoverArrowDown.png"; + ret.leftArrowImageName = @"popoverArrowLeft.png"; + ret.rightArrowImageName = @"popoverArrowRight.png"; + return ret; } @end diff --git a/Classes/Popover/WETouchableView.h b/Classes/Popover/WETouchableView.h index b260812..d78ebf6 100644 --- a/Classes/Popover/WETouchableView.h +++ b/Classes/Popover/WETouchableView.h @@ -7,6 +7,7 @@ // #import +#import "ARCHelper.h" @class WETouchableView; @@ -24,13 +25,13 @@ */ @interface WETouchableView : UIView { BOOL touchForwardingDisabled; - id delegate; + id __ah_weak delegate; NSArray *passthroughViews; BOOL testHits; } @property (nonatomic, assign) BOOL touchForwardingDisabled; -@property (nonatomic, assign) id delegate; +@property (nonatomic, ah_weak) id delegate; @property (nonatomic, copy) NSArray *passthroughViews; @end diff --git a/Classes/Popover/WETouchableView.m b/Classes/Popover/WETouchableView.m index e04fc9d..441d17e 100644 --- a/Classes/Popover/WETouchableView.m +++ b/Classes/Popover/WETouchableView.m @@ -20,7 +20,7 @@ @implementation WETouchableView - (void)dealloc { [passthroughViews release]; - [super dealloc]; + [super ah_dealloc]; } - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { diff --git a/WEPopover.xcodeproj/project.pbxproj b/WEPopover.xcodeproj/project.pbxproj index f059514..4080dd1 100755 --- a/WEPopover.xcodeproj/project.pbxproj +++ b/WEPopover.xcodeproj/project.pbxproj @@ -79,6 +79,7 @@ 749FAE831286130000AB97F9 /* WEPopoverController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WEPopoverController.h; sourceTree = ""; }; 749FAE841286130000AB97F9 /* WEPopoverController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WEPopoverController.m; sourceTree = ""; }; 749FAE851286130000AB97F9 /* WEPopoverParentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WEPopoverParentView.h; sourceTree = ""; }; + 8C193A0A163C4470006FEF03 /* ARCHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ARCHelper.h; sourceTree = ""; }; 8D1107310486CEB800E47090 /* WEPopover-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "WEPopover-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -194,6 +195,7 @@ 749FAE6F1286123500AB97F9 /* Popover */ = { isa = PBXGroup; children = ( + 8C193A0A163C4470006FEF03 /* ARCHelper.h */, 74634FFF13729C6F000EF936 /* WETouchableView.h */, 7463500013729C6F000EF936 /* WETouchableView.m */, 749FAE7F1286130000AB97F9 /* WEPopoverContainerView.h */, diff --git a/popoverArrowDownSimple.png b/popoverArrowDownSimple.png deleted file mode 100755 index ddae902..0000000 Binary files a/popoverArrowDownSimple.png and /dev/null differ diff --git a/popoverArrowLeftSimple.png b/popoverArrowLeftSimple.png deleted file mode 100755 index adc4a8a..0000000 Binary files a/popoverArrowLeftSimple.png and /dev/null differ diff --git a/popoverArrowRightSimple.png b/popoverArrowRightSimple.png deleted file mode 100755 index b3ebfe3..0000000 Binary files a/popoverArrowRightSimple.png and /dev/null differ diff --git a/popoverArrowUpSimple.png b/popoverArrowUpSimple.png deleted file mode 100755 index 099d54f..0000000 Binary files a/popoverArrowUpSimple.png and /dev/null differ diff --git a/popoverBgSimple.png b/popoverBgSimple.png deleted file mode 100755 index 3cdf457..0000000 Binary files a/popoverBgSimple.png and /dev/null differ