I'm having an issue displaying a UIViewController with a popover presentation from iPhone within a UITableViewController. The code I have been using works to display a popover from any other UIViewController, just not a UITableViewController on iPhone. It does work from a UITableViewController on iPad.
When the code is executed, the view is presented modally temporarily (as you might expect if I did not implement adaptivePresentationStyleForPresentationController) and then covered by black, as if some sort of Auto Layout error occurred (though there's nothing in the console to indicate otherwise).
As I mentioned, the following works outside of a UITableViewController on iPhone, and works all the time on iPad. I'm sure I'm missing something fairly simple. Any ideas?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
/* Create label */
UILabel *label = [UILabel new];
label.text = @"This should be in a popover.";
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
/* Add label to new ViewController */
UIViewController *popoverVC = [UIViewController new];
[popoverVC.view addSubview:label];
label.translatesAutoresizingMaskIntoConstraints = NO;
[popoverVC.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[label]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(label)]];
[popoverVC.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[label]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(label)]];
/* Define ViewController to present as a popover and display */
popoverVC.modalPresentationStyle = UIModalPresentationPopover;
popoverVC.preferredContentSize = CGSizeMake(320, 50);
[self presentViewController:popoverVC animated:YES completion:nil];
/* Grab handle to ViewController's popoverPresentationController after displaying */
UIPopoverPresentationController *popoverController = [popoverVC popoverPresentationController];
if (popoverController == nil)
NSLog(@"popoverController is nil");
else {
popoverController.delegate = self;
popoverController.popoverLayoutMargins = UIEdgeInsetsMake(15, 15, 15, 15);
popoverController.sourceView = tableView;
popoverController.sourceRect = [tableView rectForRowAtIndexPath:indexPath];
self.definesPresentationContext = YES;
}
}
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection
{
NSLog(@"%s", __PRETTY_FUNCTION__);
return (UIModalPresentationNone);
}
FWIW: One way to quickly prototype this code is to add the above to MasterViewController.m from a new "Master-Detail Application" template in Xcode, and define this message to avoid pushing the DetailViewController:
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
return (NO);
}
You'll also need to set MasterViewController.h to adopt the UIPopoverPresentationControllerDelegate protocol.