我正在使用UIPopoverController来显示我的ContentItems的属性。所有在iOS 4.3中都使用presentPopoverFromRect正常工作。一些ContentItem rect是相当大的,在iOS 5中,popover重新调整大小以适应rect的边缘和屏幕边框之间的边距。在最糟糕的情况下,弹出窗口的高度小于50像素,并覆盖NavigationBar。显然不是用户友好。
我重新编写了代码(下面的最新尝试)来检测问题案例,并在ContentItem的中心点为popover提供一个1像素的矩形。这在大多数时候都有效,尽管我仍然在对某些边界情况进行逆向工程。
然而,我觉得我必须遗漏一些东西。在iOS 5 Beta期间,有一些讨论需要指定弹出窗口管理的视图的大小调整掩码 - 但我发现很难相信我看到的行为是Apple故障而不是我的。建议表示赞赏。
- (IBAction)handleDoubleTap:(UIGestureRecognizer *)sender
{
int subViewTag = sender.view.tag;
DLog(@":tag = %d", subViewTag);
NSString* key = [NSString stringWithFormat:@"%d", subViewTag];
ContentItemView* contentItemView = [self.contentItemViewDict objectForKey:key];
ContentItem* theContentItem = [contentItemView contentItem];
ContentItemPropertiesViewController* contentPopover = [[[ContentItemPropertiesViewController alloc] initWithNibName:@"ContentItemPropertiesViewController"
bundle:[NSBundle mainBundle]] autorelease];
contentPopover.delegate = self;
contentPopover.theItem = theContentItem;
contentPopover.theView = sender.view;
[contentPopover setContentSizeForViewInPopover:/*k_contentItemPopoverSize*/ CGSizeMake(320, 344.0f)];
UIPopoverController* popover = [[UIPopoverController alloc] initWithContentViewController:contentPopover];
popover.delegate = self;
self.contentPopoverViewController = popover;
[popover setPopoverContentSize:CGSizeMake(320, 344.0f)];
[popover release];
// Check to see if there's room for the popover around the edges of the object
CGRect popoverRect = [self rectForPopover:sender.view.frame];
if (popoverRect.origin.x == 0 && popoverRect.origin.y == 0 &&
popoverRect.size.width == 0 && popoverRect.size.height == 0) {
popoverRect = sender.view.bounds;
}
CGRect theRect = [sender.view convertRect:popoverRect
toView:self.view];
DLog(@"popoverRect %f, %f, %f, %f", theRect.origin.x, theRect.origin.y, theRect.size.width, theRect.size.height);
[self.contentPopoverViewController presentPopoverFromRect:theRect
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
- (CGRect)rectForPopover:(CGRect)viewRect
{
#define k_popoverPad 30.0f // a little extra room for the popover borders and arrow
DLog();
// Get the width and height the popover controller needs to fully display itself
CGSize popoverSize = k_contentItemPopoverSize;
CGFloat popoverWidth = popoverSize.width;
CGFloat popoverHeight = popoverSize.height;
// Get the edges of the object's rect translated to sceneView's coordinates
CGFloat leftEdge = self.sceneView.frame.origin.x + viewRect.origin.x - k_popoverPad;
CGFloat rightEdge = leftEdge + viewRect.size.width + k_popoverPad;
CGFloat topEdge = self.sceneView.frame.origin.y + viewRect.origin.y - k_popoverPad;
CGFloat bottomEdge = topEdge + viewRect.size.height + k_popoverPad;
// Get the bounds of the view
CGFloat viewRightBound = self.view.bounds.origin.x + self.view.bounds.size.width;
CGFloat viewBottomBound = self.view.bounds.origin.y + self.view.bounds.size.height;
// Compare the "margin" between the screen bounds and object's edges
// to see if the popover will fit somewhere
if (leftEdge > popoverWidth || // room on the left
topEdge > popoverHeight || // room at the top
viewRightBound - rightEdge > popoverWidth || // room to the right
viewBottomBound - bottomEdge > popoverHeight) { // room at the bottom
return CGRectZero;
} else {
// return a rect that is (essentially) the centerpoint of the object
CGRect newRect = CGRectMake((rightEdge - leftEdge) / 2.0f, (bottomEdge - topEdge) / 2.0f, 1.0f, 1.0f);
return newRect;
}
}