如何在 iOS 5 中设置最小 UIPopoverController 大小?
我正在使用 UIPopoverController 来显示我的 ContentItems 的属性。使用presentPopoverFromRect 在iOS 4.3 中一切正常。一些 ContentItem 矩形相当大,在 iOS 5 中,弹出窗口会调整自身大小以适合矩形边缘和屏幕边框之间的边距。在最坏的情况下,弹出窗口的高度低于 50 像素并覆盖导航栏。显然对用户不友好。
我重新编写了代码(下面是最新的尝试)来检测问题情况,并在 ContentItem 的中心点为弹出窗口提供一个 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;
}
}
I am using a UIPopoverController to display properties of my ContentItems. All worked fine in iOS 4.3 using presentPopoverFromRect. Some of the ContentItem rect's are fairly large, and in iOS 5, the popover re-sizes itself to fit in the margin between the rect's edges and the screen borders. In the worst cases the popover is less than 50 pixels tall and overlays the NavigationBar. Obviously not user friendly.
I've re-written the code (latest attempt below) to detect the problem cases and give the popover a 1 pixel rect at the center point of the ContentItem. This works most of the time although I'm still reverse-engineering the behavior for some boundary cases.
However I feel I must be missing something. During the iOS 5 Beta there was some discussion of the need to specify resizing masks of the Views the popover managed - but I just find it hard to believe the behavior I'm seeing is Apple fault and not mine. Advice is appreciated.
- (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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论