Your code doesn't work because contentSizeForViewInPopover is called before viewWillDisplay, so the frames of the views haven't been set yet. There are a few things you can do though.
If you are using a UITableViewController a little known trick to sizing your UIPopoverViewController to match the height of your UITableView is to use the tableView's rectForSection method to give you the height. Use the height in your viewController's contentSizeForViewInPopover like this:
- (CGSize)contentSizeForViewInPopover
{
// Currently no way to obtain the width dynamically before viewWillAppear.
CGFloat width = 200.0;
NSInteger lastSectionIndex = [self.tableView numberOfSections] - 1;
CGRect rect = [self.tableView rectForSection:lastSectionIndex];
CGFloat height = CGRectGetMaxY(rect);
return (CGSize){width, height};
}
Or alternately, you can manually set the contentSizeForViewInPopopver property in your viewController's viewWillAppear: method and set the popover's size when you create it.
So, in your viewController which will be in the popover, you'll have this:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.contentSizeForViewInPopover = self.view.size
}
And you'd create your popover like this:
MyViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"vc"];
self.currentPopover = [[UIPopoverController alloc] initWithContentViewController:vc];
[self.currentPopover presentPopoverFromRect:sender.bounds
inView:sender
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
// resize the popover to match what you set in vc viewDidLoad
[self.currentPopover setPopoverContentSize:vc.contentSizeForViewInPopover animated:NO];