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
pic.2
pic.3
And here is what I would expect:
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.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With