Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 8 presentationController determine if really is popover

I'm using the new adaptive "Present As Popover" capability of iOS 8. I wired up a simple segue in the StoryBoard to do the presentation. It works great on an iPhone 6 Plus as it presents the view as a popover and on an iPhone 4s it shows as a full screen view (sheet style).

The problem is when shown as a full screen view, I need to add a "Done" button to the view so dismissViewControllerAnimated can be called. And I don't want to show the "done" button when it's shown as a popover.

enter image description here

I tried looking at the properties of both presentationController and popoverPresentationController, and I can find nothing that tells me if it is actually being shown as a popover.

NSLog( @"View loaded %lx", (long)self.presentationController.adaptivePresentationStyle );          // UIModalPresentationFullScreen
NSLog( @"View loaded %lx", (long)self.presentationController.presentationStyle );                  // UIModalPresentationPopover
NSLog( @"View loaded %lx", (long)self.popoverPresentationController.adaptivePresentationStyle );   // UIModalPresentationFullScreen
NSLog( @"View loaded %lx", (long)self.popoverPresentationController.presentationStyle );           // UIModalPresentationPopover

adaptivePresentationStyle always returns UIModalPresentationFullScreen and presentationStyle always returns UIModalPresentationPopover

When looking at the UITraitCollection I did find a trait called "_UITraitNameInteractionModel" which was only set to 1 when it was actually displayed as a Popover. However, Apple doesn't provide direct access to that trait through the traitCollection of popoverPresentationController.

like image 714
Tod Cunningham Avatar asked Nov 01 '14 07:11

Tod Cunningham


3 Answers

The best way (least smelly) I've found to do this is to use the UIPopoverPresentationControllerDelegate.

• Ensure the presented view controller is set as the UIPopoverPresentationControllerDelegate on the UIPopoverPresentationController being used to manage the presentation. I'm using a Storyboard so set this in prepareForSegue:

segue.destinationViewController.popoverPresentationController.delegate = presentedVC;

• Create a property in the presented view controller to keep track of this state:

@property (nonatomic, assign) BOOL amDisplayedInAPopover;

• And add the following delegate method (or add to your existing delegate method):

- (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController
{
    // This method is only called if we are presented in a popover
    self.amDisplayedInAPopover = YES;
}

• And then finally in viewWillAppear: - viewDidLoad: is too early, the delegate prepare method is called between viewDidLoad: and viewWillAppear:

if (self.amDisplayedInAPopover) {
    // Hide the offending buttons in whatever manner you do so
    self.navigationItem.leftBarButtonItem = nil;
}

Edit: Simpler method!

Just set the delegate (making sure your presentedVC adopts the UIPopoverPresentationControllerDelegate):

segue.destinationViewController.popoverPresentationController.delegate = presentedVC;

And supply the method:

- (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController
{
    // This method is only called if we are presented in a popover
    // Hide the offending buttons in whatever manner you do so
    self.navigationItem.leftBarButtonItem = nil;
}
like image 132
Rob Glassey Avatar answered Oct 23 '22 16:10

Rob Glassey


I check to see if the popoverPresentationController's arrowDirection is set after the view is laid out. For my purposes, this works well enough and covers the case of popovers on smaller screened devices.

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    if (popoverPresentationController?.arrowDirection != UIPopoverArrowDirection.Unknown) {
        // This view controller is running in a popover
        NSLog("I'm running in a Popover")
    }
}
like image 37
John E. Ray Avatar answered Oct 23 '22 15:10

John E. Ray


How about

if (self.modalPresentationStyle == UIModalPresentationPopover)

It's working for me

like image 31
Scroot Avatar answered Oct 23 '22 17:10

Scroot