Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extra height of popover's content view

I open UIPopoverController popover with UITableViewController as it's content view controller.

Popover has the proper size, and it's content view at first glance adjusts correct, but if I try to scroll inside popover, it scrolls, though it shouldn't. Seems that the content view becomes about 20 px higher after -(void)viewDidAppear (pic 1, 2). What do I do to check sizes:

- (void)viewDidAppear:(BOOL)animated
{
    NSLog(@"%@", self.view);
}

Output is

Popovers[3016:c07] <UITableView: 0x10b80600; frame = (0 0; 200 66); autoresize = W+H; gestureRecognizers = <NSArray: 0x1004cc20>; layer = <CALayer: 0x1004c4a0>; contentOffset: {0, 0}>

At this point the size is correct, and it is equal to the size of popover. After popover is opened it's inner size without margins is 66 px (measured with the help of Ruler app). So, it seems that it should fit exactly to the size of content view. But unexpected vertical scrolling appears somehow.

Than, if I add 20 px to the height of popover, [mOptionPopoverController setPopoverContentSize:(CGSize){200, 86}]; than it's content view also increases and fits as expected, without any scrollers. Only issue is that I don't need empty 20 px at the bottom of popover (pic. 3).

I made a small test project to reproduce my problem. Here is the important code:

@implementation ViewController

- (IBAction)buttonPressed:(id)sender
{
    TableViewController *popoverViewController = [[TableViewController alloc] initWithStyle:UITableViewStyleGrouped];
    UIPopoverController* mOptionPopoverController = [[UIPopoverController alloc] initWithContentViewController:popoverViewController];
    [mOptionPopoverController setPopoverContentSize:(CGSize){200, 66}]; 
    CGRect popoverRect = [self.view convertRect:[sender frame] fromView:[sender superview]];
    [mOptionPopoverController presentPopoverFromRect:popoverRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}

@end

@implementation TableViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        self.tableView.bounces = NO;
    }
    return self;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

    return cell;
}

- (void)viewDidAppear:(BOOL)animated
{
    NSLog(@"%@", self.view);
}

@end

pic.1 enter image description here

pic.2 enter image description here

pic.3 enter image description here

And here is what I would expect: enter image description here

UPD.

I've made further investigation. I used KVO to follow the changes of frame. I was expecting it will help to find something useful. And I found something, but it didn't make things clearer.

So, I added [self.view addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil]; in the - (id)initWithStyle:(UITableViewStyle)style method of TableViewController, and the observing method is

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"%@", [object valueForKeyPath:keyPath]);
}

And here is output:

2013-05-27 15:52:12.755 Popovers[1547:c07] NSRect: {{0, 0}, {200, 84}}
2013-05-27 15:52:12.756 Popovers[1547:c07] NSRect: {{0, 0}, {200, 84}}
2013-05-27 15:52:12.756 Popovers[1547:c07] NSRect: {{0, 0}, {200, 66}}
2013-05-27 15:52:12.759 Popovers[1547:c07] <UITableView: 0x9337600; frame = (0 0; 200 66); autoresize = W+H; gestureRecognizers = <NSArray: 0x8949760>; layer = <CALayer: 0x8944690>; contentOffset: {0, 0}>

(the last one is from - (void)viewDidAppear:(BOOL)animated).

Why 84? It's 84-66=18, and these are not those 20 px that I'm looking for. Additionally, all of three calls of observer's method are happen before tableView data source method are called. How the frame can be known before tableView is built?

(Having too many questions I currently use suggested by @robmayoff tableView.scrollEnabled = NO; to suppress unnecessary popovers.)

UPD. Even Apple system printing popover has that 20 px and unnecessary scroller in the printer selection list.

like image 319
Anastasia Avatar asked Nov 12 '22 04:11

Anastasia


1 Answers

This is apparently the Apple Bug, as this question has been asked apple engineers during WWDC 2013 and got no answer.

The workaround is

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 0.1f;
}
like image 129
Anastasia Avatar answered Nov 15 '22 05:11

Anastasia