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.
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.
I tested all solutions presented in this post. Sorry, none works correctly in all cases. For example in iPad split view presentation style can change while dragging split view line, so we need specific notification for that. After few hours of researches i found solution in apple sample (swift): https://developer.apple.com/library/ios/samplecode/AdaptivePhotos/Introduction/Intro.html#//apple_ref/doc/uid/TP40014636
Here is the same solution in obj-c.
First in prepareForSegue function set the popoverPresentationController delegate. It can be also set in MyViewController "init", but not in "viewDidLoad" (because first willPresentWithAdaptiveStyle is called before viewDidLoad).
Now MyViewController object will receive this notification every time iOS changes presentation style, including first presenting. Here is example implementation which shows/hides "Close" button in navigationController:
My tricky solution, works perfectly.
In the
PopoverViewController
'sviewDidLoad
.The idea is simple, A Popover's view size is never equal to the device screen size unless it's not a Popover.
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 theUIPopoverPresentationController
being used to manage the presentation. I'm using a Storyboard so set this inprepareForSegue:
• Create a property in the presented view controller to keep track of this state:
• And add the following delegate method (or add to your existing delegate method):
• And then finally in
viewWillAppear:
-viewDidLoad:
is too early, the delegate prepare method is called betweenviewDidLoad:
andviewWillAppear:
Edit: Simpler method!
Just set the delegate (making sure your presentedVC adopts the
UIPopoverPresentationControllerDelegate
):And supply the method:
How about
It's working for me
The official way to implement this is first remove the Done button from your view controller and second, when adapting to compact embed your view controller in a navigation controller, adding the done button as a navigation item:
Full Tutorial
Solution that works with multitasking
Assign the presenting controller as the popover's delegate
Then, in the controller, implement the delegate methods: