Skip to content

Instantly share code, notes, and snippets.

@irace
Created August 13, 2014 20:03
Show Gist options
  • Save irace/927f843cb0f683a7f2c2 to your computer and use it in GitHub Desktop.
Save irace/927f843cb0f683a7f2c2 to your computer and use it in GitHub Desktop.
New iOS 8 APIs don't allow you to use a custom presentation controller for compact devices, in conjunction with a popover on "normal" size class devices
//
// ViewController.m
// PopoverPresentationControllerExample
//
// Created by Bryan Irace on 8/8/14.
// Copyright (c) 2014 Bryan Irace. All rights reserved.
//
#import "CustomCompactPresentationController.h"
#import "ViewController.h"
#import "ModalViewController.h"
@interface ViewController () <UIViewControllerTransitioningDelegate, UIPopoverPresentationControllerDelegate>
@end
@implementation ViewController
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
/**
This modal view controller should be displayed in a popover on normal size class devices, but should use a custom
presentation controller on devices with a compact size class.
I don't know how to accomplish this, though, since `UIPopoverPresentationControllerDelegate`'s
`adaptivePresentationStyleForPresentationController` method doesn't allow you to return `UIModalPresentationCustom`.
One way would be to:
1) Use `UIModalPresentationCustom` instead of `UIModalPresentationPopover`
2) Subclass `UIPopoverPresentationController`, implement this behavior myself, and return an instance of my subclass
from `presentationControllerForPresentedViewController:presentingViewController:sourceViewController`
instead of accessing `modal.popoverPresentationController` at all
But since popover presentation controllers are not intended to be instantiated directly, it feels like I'm fighting
the framework here.
*/
ModalViewController *modal = [[ModalViewController alloc] init];
modal.modalPresentationStyle = UIModalPresentationPopover;
modal.transitioningDelegate = self;
modal.popoverPresentationController.sourceView = self.view;
modal.popoverPresentationController.sourceRect = CGRectZero;
modal.popoverPresentationController.delegate = self;
[self presentViewController:modal animated:YES completion:nil];
}
#pragma mark - UIPopoverPresentationControllerDelegate
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
/**
The documentation says this can only return `UIModalPresentationFullScreen` or `UIModalPresentationOverFullScreen`,
or none.
It would be great if returning `UIModalPresentationCustom` here would allow the presenting view controller's
transitioning delegate to provide a custom presentation controller instance.
*/
return UIModalPresentationCustom;
}
#pragma mark - UIViewControllerTransitioningDelegate
- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented
presentingViewController:(UIViewController *)presenting
sourceViewController:(UIViewController *)source {
/**
This method is never called, because the view controller being presented has modal presentation style
`UIModalPresentationPopover` instead of `UIModalPresentationCustom`.
If this method were called, I could provide a custom presentation controller for usage on compact size class
devices where popovers are not supported.
*/
return [[CustomCompactPresentationController alloc] init];
}
@end
@malhal
Copy link

malhal commented Mar 4, 2016

UIModalPresentationCustom means you want to use a custom presentation controller. It doesn't make sense in this case to try to adapt to a a different controller when you already are using the popover presentation controller! There is only one ever one presentation controller. The popover controller has a delegate method you can use to easily adapt the views to or create new ones for display in full screen for compact devices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment