Как установить минимальный размер UIPopoverController в iOS 5? - PullRequest
2 голосов
/ 10 ноября 2011

Я использую UIPopoverController для отображения свойств моих ContentItems.Все работало нормально в iOS 4.3 с использованием presentPopoverFromRect.Некоторые из прямоугольников ContentItem довольно велики, и в iOS 5 поповер изменяет свои размеры, чтобы поместиться в поле между краями прямоугольника и границами экрана.В худшем случае всплывающее окно имеет высоту менее 50 пикселей и перекрывает панель навигации.Очевидно, что это не удобно для пользователя.

Я переписал код (последняя попытка ниже), чтобы обнаружить проблемные случаи и дать поповеру прямоугольник в 1 пиксель в центральной точке ContentItem.Это работает большую часть времени, хотя я до сих пор реинжиниринг поведения для некоторых граничных случаев.

Однако я чувствую, что я что-то упускаю.Во время бета-версии iOS 5 обсуждалась необходимость указания масок изменения размеров для представлений, которыми управлял поповер - но мне просто трудно поверить, что поведение, которое я вижу, является ошибкой 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;
    }
}
...