Uipopoverpresentationcontroller on iPhone Doesn't Produce Popover

UIPopoverPresentationController on iPhone doesn't produce popover

Steps:

A) Link your UIButton to the popover's view controller using the Present As Popover segue type. I actually had to create a new project to get this to appear but it's probably something to do with the base SDK.

B) Make the View Controller containing the UIButton conform to the . E.g. In your MyViewController.m file add:

@interface MyViewController () 

C) Add the method below to the View Controller containing the UIButton:

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {

return UIModalPresentationNone;
}

D) Add the following into your prepareForSegue:sender: replacing your segue.identifier check:

if ([segue.identifier isEqualToString:@"CatSelectSegue"]) {
UIViewController *dvc = segue.destinationViewController;
UIPopoverPresentationController *controller = dvc.popoverPresentationController;
if (controller) {
controller.delegate = self;
}
}

Code tested and proof it works:

Popover on iPhone without 3rd Party Controls

Edit: My test app TPOPViewController.m file where the magic happens:

#import "TPOPViewController.h"

@interface TPOPViewController () //, UIAdaptivePresentationControllerDelegate>

@end

@implementation TPOPViewController

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

NSString *identifier = segue.identifier;
if ([identifier isEqualToString:@"popover"]) {
UIViewController *dvc = segue.destinationViewController;
UIPopoverPresentationController *ppc = dvc.popoverPresentationController;
if (ppc) {
if ([sender isKindOfClass:[UIButton class]]) { // Assumes the popover is being triggered by a UIButton
ppc.sourceView = (UIButton *)sender;
ppc.sourceRect = [(UIButton *)sender bounds];
}
ppc.delegate = self;
}
}
}

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {

return UIModalPresentationNone;
}

@end

My test storyboard as well:

Popover on iPhone test storyboard

how to use popover controller in iPhone

Set yourself as the popover view controller's delegate before presenting it, and implement the delegate method adaptivePresentationStyle(for:traitCollection:) to return .none. This will cause the popover to stop adapting on iPhone as a fullscreen presented view controller and turn into an actual popover just like on the iPad.

This is a complete working example that presents the popover in response to a button tap:

class ViewController: UIViewController {
@IBAction func doButton(_ sender: Any) {
let vc = MyPopoverViewController()
vc.preferredContentSize = CGSize(400,500)
vc.modalPresentationStyle = .popover
if let pres = vc.presentationController {
pres.delegate = self
}
self.present(vc, animated: true)
if let pop = vc.popoverPresentationController {
pop.sourceView = (sender as! UIView)
pop.sourceRect = (sender as! UIView).bounds
}
}
}
extension ViewController : UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
return .none
}
}

popover doesn't display on iphone

After using this delegate method it is producing popover on iphone.

func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {

return UIModalPresentationStyle.none
}

Popover presentation on an iPhone using UIPopoverPresentationController

Here's your problem:

[self presentViewController:popupController animated:YES completion:nil];
popupPresentationController= [popupController popoverPresentationController];
popupPresentationController.delegate = self;

That code is in the wrong order. You must set the delegate before calling presentViewController.

UIPopoverPresentationController on iOS 8 iPhone

You can override the default adaptive behaviour (UIModalPresentationFullScreen in compact horizontal environment, i.e. iPhone) using the
adaptivePresentationStyleForPresentationController: method available through UIPopoverPresentationController.delegate.

UIPresentationController uses this method to ask the new presentation style to use, which in your case, simply returning UIModalPresentationNone will cause the UIPopoverPresentationController to render as a popover instead of fullscreen.

Here's an example of the popover using a segue setup in storyboard from a UIBarButtonItem to "present modally" a UIViewController

class SomeViewController: UIViewController, UIPopoverPresentationControllerDelegate {

// override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) { // swift < 3.0
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "PopoverSegue" {
if let controller = segue.destinationViewController as? UIViewController {
controller.popoverPresentationController.delegate = self
controller.preferredContentSize = CGSize(width: 320, height: 186)
}
}
}

// MARK: UIPopoverPresentationControllerDelegate

//func adaptivePresentationStyleForPresentationController(controller: UIPresentationController!) -> UIModalPresentationStyle { // swift < 3.0
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
// Return no adaptive presentation style, use default presentation behaviour
return .None
}
}

This trick was mentioned in WWDC 2014 session 214 "View Controller Advancement in iOS8" (36:30)

UIPopoverPresentationController is showing full screen modal on iPhone

In ViewController.h Firstly make a property of UIPopoverPresenatationController.

 @property(nonatomic,retain)UIPopoverPresentationController *dateTimePopover8;

Then to show PopOverPresentationcontroller

 UINavigationController *destNav = [[UINavigationController alloc] initWithRootViewController:dateVC];/*Here dateVC is controller you want to show in popover*/
dateVC.preferredContentSize = CGSizeMake(280,200);
destNav.modalPresentationStyle = UIModalPresentationPopover;
_dateTimePopover8 = destNav.popoverPresentationController;
_dateTimePopover8.delegate = self;
_dateTimePopover8.sourceView = self.view;
_dateTimePopover8.sourceRect = [sender frame];
destNav.modalPresentationStyle = UIModalPresentationPopover;
destNav.navigationBarHidden = YES;
[self presentViewController:destNav animated:YES completion:nil];

You must have noticed that we are presenting View Controller instead of presenting popOver.So we have to hide this in new way also.It hides automatically when we click on screen.

-(void)hideIOS8PopOver
{
[self dismissViewControllerAnimated:YES completion:nil];
}

We have to implement the delegate of UIPopoverPresenatationController in implementation file.Write below delegate method in implementation file.

- (UIModalPresentationStyle) adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller {
return UIModalPresentationNone;
}

UIPopoverPresentationController displaying popover as full screen

In iPhone, you should add the following in order to present a popover.

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController!) -> UIModalPresentationStyle {
// Return no adaptive presentation style, use default presentation behaviour
return .None
}

Trying to display popover controller on certain size

To be able to show such ViewController (the orange one) in a popover, you have to define the modalPresentationStyle as popover doing so:

class ParentViewController: UIViewController, UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return .none
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "PopoverSegue" {
let popoverVc = segue.destination
popoverVc.modalPresentationStyle = .popover
popoverVc.popoverPresentationController?.delegate = self;
popoverVc.preferredContentSize = CGSize(width: 250, height: 250)
}
}
}

remember to set the segue identifier (PopoverSegue or whatever) in the interface builder:

Sample Image

the following freeform size (ignored at runtime), will be important to simulate your popover view inside the interface builder:

Sample Image

final result is:

Sample Image

Force popover on iPhone with programmatically created UIPopoverPresentationController

It seems moving the line presentViewController(contentView, animated: true, completion: nil)
to the end of the function would fix the issue.



Related Topics



Leave a reply



Submit