Permalink
Browse files

Bug fixes in placement of popover and iOS 6 compatibility.

  • Loading branch information...
1 parent b666e8f commit 9f46ca3cf9cebe9a98e06931a1a17681b0751c6f @werner77 committed Sep 16, 2012
@@ -7,6 +7,9 @@
*
*/
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+
@interface UIBarButtonItem(WEPopover)
- (CGRect)frameInView:(UIView *)v;
@@ -13,39 +13,33 @@ @implementation UIBarButtonItem(WEPopover)
- (CGRect)frameInView:(UIView *)v {
- BOOL hasCustomView = (self.customView != nil);
-
- if (!hasCustomView) {
- UIView *tempView = [[UIView alloc] initWithFrame:CGRectZero];
- self.customView = tempView;
- [tempView release];
+ UIView *theView = self.customView;
+ if (!theView && [self respondsToSelector:@selector(view)]) {
+ theView = [self performSelector:@selector(view)];
}
- UIView *parentView = self.customView.superview;
- NSUInteger indexOfView = [parentView.subviews indexOfObject:self.customView];
+ UIView *parentView = theView.superview;
+ NSArray *subviews = parentView.subviews;
+
+ NSUInteger indexOfView = [subviews indexOfObject:theView];
+ NSUInteger subviewCount = subviews.count;
- if (!hasCustomView) {
- self.customView = nil;
+ if (subviewCount > 0 && indexOfView != NSNotFound) {
+ UIView *button = [parentView.subviews objectAtIndex:indexOfView];
+ return [button convertRect:button.bounds toView:v];
+ } else {
+ return CGRectZero;
}
- UIView *button = [parentView.subviews objectAtIndex:indexOfView];
- return [parentView convertRect:button.frame toView:v];
}
- (UIView *)superview {
- BOOL hasCustomView = (self.customView != nil);
-
- if (!hasCustomView) {
- UIView *tempView = [[UIView alloc] initWithFrame:CGRectZero];
- self.customView = tempView;
- [tempView release];
+ UIView *theView = self.customView;
+ if (!theView && [self respondsToSelector:@selector(view)]) {
+ theView = [self performSelector:@selector(view)];
}
- UIView *parentView = self.customView.superview;
-
- if (!hasCustomView) {
- self.customView = nil;
- }
+ UIView *parentView = theView.superview;
return parentView;
}
@@ -7,6 +7,7 @@
//
#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
/**
* @brief Properties for the container view determining the area where the actual content view can/may be displayed. Also Images can be supplied for the arrow images and background.
@@ -91,8 +92,9 @@ permittedArrowDirections:(UIPopoverArrowDirection)permittedArrowDirections
/**
* @brief To update the position of the popover with a new anchor rect, display area and permitted arrow directions
*/
-- (void)updatePositionWithAnchorRect:(CGRect)anchorRect
- displayArea:(CGRect)displayArea
- permittedArrowDirections:(UIPopoverArrowDirection)permittedArrowDirections;
+- (void)updatePositionWithSize:(CGSize)theSize
+ anchorRect:(CGRect)anchorRect
+ displayArea:(CGRect)displayArea
+ permittedArrowDirections:(UIPopoverArrowDirection)permittedArrowDirections;
@end
@@ -73,11 +73,17 @@ - (void)drawRect:(CGRect)rect {
[arrowImage drawInRect:arrowRect blendMode:kCGBlendModeNormal alpha:1.0];
}
-- (void)updatePositionWithAnchorRect:(CGRect)anchorRect
- displayArea:(CGRect)displayArea
- permittedArrowDirections:(UIPopoverArrowDirection)permittedArrowDirections {
+- (void)updatePositionWithSize:(CGSize)theSize
+ anchorRect:(CGRect)anchorRect
+ displayArea:(CGRect)displayArea
+ permittedArrowDirections:(UIPopoverArrowDirection)permittedArrowDirections {
+
+ correctedSize = CGSizeMake(theSize.width + properties.leftBgMargin + properties.rightBgMargin + properties.leftContentMargin + properties.rightContentMargin,
+ theSize.height + properties.topBgMargin + properties.bottomBgMargin + properties.topContentMargin + properties.bottomContentMargin);
[self determineGeometryForSize:correctedSize anchorRect:anchorRect displayArea:displayArea permittedArrowDirections:permittedArrowDirections];
[self initFrame];
+ [self setNeedsDisplay];
+
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
@@ -122,8 +128,8 @@ - (void)initFrame {
arrowOffset = CGPointMake(MAX(0, -arrowRect.origin.x), MAX(0, -arrowRect.origin.y));
bgRect = CGRectOffset(bgRect, arrowOffset.x, arrowOffset.y);
arrowRect = CGRectOffset(arrowRect, arrowOffset.x, arrowOffset.y);
-
- self.frame = theFrame;
+
+ self.frame = CGRectIntegral(theFrame);
}
- (CGSize)contentSize {
@@ -167,7 +173,7 @@ - (void)determineGeometryForSize:(CGSize)theSize anchorRect:(CGRect)anchorRect d
if ((supportedArrowDirections & theArrowDirection)) {
- CGRect theBgRect = CGRectZero;
+ CGRect theBgRect = CGRectMake(0, 0, theSize.width, theSize.height);
CGRect theArrowRect = CGRectZero;
CGPoint theOffset = CGPointZero;
CGFloat xArrowOffset = 0.0;
@@ -177,13 +183,12 @@ - (void)determineGeometryForSize:(CGSize)theSize anchorRect:(CGRect)anchorRect d
switch (theArrowDirection) {
case UIPopoverArrowDirectionUp:
- anchorPoint = CGPointMake(CGRectGetMidX(anchorRect), CGRectGetMaxY(anchorRect));
-
- xArrowOffset = theSize.width / 2 - upArrowImage.size.width / 2;
+ anchorPoint = CGPointMake(CGRectGetMidX(anchorRect) - displayArea.origin.x, CGRectGetMaxY(anchorRect) - displayArea.origin.y);
+
+ xArrowOffset = theSize.width / 2 - upArrowImage.size.width / 2;
yArrowOffset = properties.topBgMargin - upArrowImage.size.height;
theOffset = CGPointMake(anchorPoint.x - xArrowOffset - upArrowImage.size.width / 2, anchorPoint.y - yArrowOffset);
- theBgRect = CGRectMake(0, 0, theSize.width, theSize.height);
if (theOffset.x < 0) {
xArrowOffset += theOffset.x;
@@ -202,13 +207,12 @@ - (void)determineGeometryForSize:(CGSize)theSize anchorRect:(CGRect)anchorRect d
break;
case UIPopoverArrowDirectionDown:
- anchorPoint = CGPointMake(CGRectGetMidX(anchorRect), CGRectGetMinY(anchorRect));
+ anchorPoint = CGPointMake(CGRectGetMidX(anchorRect) - displayArea.origin.x, CGRectGetMinY(anchorRect) - displayArea.origin.y);
xArrowOffset = theSize.width / 2 - downArrowImage.size.width / 2;
yArrowOffset = theSize.height - properties.bottomBgMargin;
theOffset = CGPointMake(anchorPoint.x - xArrowOffset - downArrowImage.size.width / 2, anchorPoint.y - yArrowOffset - downArrowImage.size.height);
- theBgRect = CGRectMake(0, 0, theSize.width, theSize.height);
if (theOffset.x < 0) {
xArrowOffset += theOffset.x;
@@ -227,13 +231,12 @@ - (void)determineGeometryForSize:(CGSize)theSize anchorRect:(CGRect)anchorRect d
break;
case UIPopoverArrowDirectionLeft:
- anchorPoint = CGPointMake(CGRectGetMaxX(anchorRect), CGRectGetMidY(anchorRect));
+ anchorPoint = CGPointMake(CGRectGetMaxX(anchorRect) - displayArea.origin.x, CGRectGetMidY(anchorRect) - displayArea.origin.y);
xArrowOffset = properties.leftBgMargin - leftArrowImage.size.width;
yArrowOffset = theSize.height / 2 - leftArrowImage.size.height / 2;
theOffset = CGPointMake(anchorPoint.x - xArrowOffset, anchorPoint.y - yArrowOffset - leftArrowImage.size.height / 2);
- theBgRect = CGRectMake(0, 0, theSize.width, theSize.height);
if (theOffset.y < 0) {
yArrowOffset += theOffset.y;
@@ -252,13 +255,12 @@ - (void)determineGeometryForSize:(CGSize)theSize anchorRect:(CGRect)anchorRect d
break;
case UIPopoverArrowDirectionRight:
- anchorPoint = CGPointMake(CGRectGetMinX(anchorRect), CGRectGetMidY(anchorRect));
+ anchorPoint = CGPointMake(CGRectGetMinX(anchorRect) - displayArea.origin.x, CGRectGetMidY(anchorRect) - displayArea.origin.y);
xArrowOffset = theSize.width - properties.rightBgMargin;
yArrowOffset = theSize.height / 2 - rightArrowImage.size.width / 2;
theOffset = CGPointMake(anchorPoint.x - xArrowOffset - rightArrowImage.size.width, anchorPoint.y - yArrowOffset - rightArrowImage.size.height / 2);
- theBgRect = CGRectMake(0, 0, theSize.width, theSize.height);
if (theOffset.y < 0) {
yArrowOffset += theOffset.y;
@@ -275,14 +277,16 @@ - (void)determineGeometryForSize:(CGSize)theSize anchorRect:(CGRect)anchorRect d
theArrowRect = CGRectMake(xArrowOffset, yArrowOffset, rightArrowImage.size.width, rightArrowImage.size.height);
break;
+ default:
+ break;
}
CGRect bgFrame = CGRectOffset(theBgRect, theOffset.x, theOffset.y);
- CGFloat minMarginLeft = CGRectGetMinX(bgFrame) - CGRectGetMinX(displayArea);
- CGFloat minMarginRight = CGRectGetMaxX(displayArea) - CGRectGetMaxX(bgFrame);
- CGFloat minMarginTop = CGRectGetMinY(bgFrame) - CGRectGetMinY(displayArea);
- CGFloat minMarginBottom = CGRectGetMaxY(displayArea) - CGRectGetMaxY(bgFrame);
+ CGFloat minMarginLeft = CGRectGetMinX(bgFrame);
+ CGFloat minMarginRight = CGRectGetWidth(displayArea) - CGRectGetMaxX(bgFrame);
+ CGFloat minMarginTop = CGRectGetMinY(bgFrame);
+ CGFloat minMarginBottom = CGRectGetHeight(displayArea) - CGRectGetMaxY(bgFrame);
if (minMarginLeft < 0) {
// Popover is too wide and clipped on the left; decrease width
@@ -327,12 +331,11 @@ - (void)determineGeometryForSize:(CGSize)theSize anchorRect:(CGRect)anchorRect d
minMargin = MIN(minMargin, minMarginBottom);
// Calculate intersection and surface
- CGRect intersection = CGRectIntersection(displayArea, bgFrame);
- CGFloat surface = intersection.size.width * intersection.size.height;
+ CGFloat surface = theBgRect.size.width * theBgRect.size.height;
if (surface >= biggestSurface && minMargin >= currentMinMargin) {
biggestSurface = surface;
- offset = theOffset;
+ offset = CGPointMake(theOffset.x + displayArea.origin.x, theOffset.y + displayArea.origin.y);
arrowRect = theArrowRect;
bgRect = theBgRect;
arrowDirection = theArrowDirection;
@@ -356,6 +359,8 @@ - (void)determineGeometryForSize:(CGSize)theSize anchorRect:(CGRect)anchorRect d
case UIPopoverArrowDirectionRight:
arrowImage = [rightArrowImage retain];
break;
+ default:
+ break;
}
}
@@ -7,6 +7,7 @@
//
#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
#import "WEPopoverContainerView.h"
#import "WETouchableView.h"
@@ -25,6 +26,7 @@
@interface WEPopoverController : NSObject<WETouchableViewDelegate> {
UIViewController *contentViewController;
UIView *view;
+ UIView *parentView;
WETouchableView *backgroundView;
BOOL popoverVisible;
@@ -45,6 +47,7 @@
@property (nonatomic, assign) CGSize popoverContentSize;
@property (nonatomic, retain) WEPopoverContainerViewProperties *containerViewProperties;
@property (nonatomic, retain) id <NSObject> context;
+@property (nonatomic, assign) UIView *parentView;
@property (nonatomic, copy) NSArray *passthroughViews;
- (id)initWithContentViewController:(UIViewController *)theContentViewController;
@@ -64,4 +67,9 @@
inView:(UIView *)view
permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections;
+- (void)repositionPopoverFromRect:(CGRect)rect
+ inView:(UIView *)view
+ permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections
+ animated:(BOOL)animated;
+
@end
Oops, something went wrong. Retry.

0 comments on commit 9f46ca3

Please sign in to comment.