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:
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:
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:
the following freeform size (ignored at runtime), will be important to simulate your popover view inside the interface builder:
final result is:
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
Xcode Quits Unexpectedly Every Time I Open My Project
How to Delete Wkwebview Cookies
How to Opt Your iPad App Out of Multitasking on iOS 9
Ios9 Does Not Load Insecure Resources from a Secure Page (Ssl/Https)
How to Obtain a Dynamic Table View Section Header Height Using Auto Layout
With Auto Layout, How to Make a Uiimageview's Size Dynamic Depending on the Image
How to Implement the Uitapgesturerecognizer into My Application
Failed to Obtain a Cell from Its Datasource
Restrict to Certain iOS Target Devices for App Store Submission
How to Call Gesture Tap on Uiview Programmatically in Swift
Determine If the Access to Photo Library Is Set or Not - PHPhotolibrary
Programmatically Creating an Expanding Uitableviewcell
Uitableview - Change Section Header Color
How to Convert a String to an Md5 Hash in iOS Using Swift
iOS 9 Facebook Login Simulator -Canopenurl: Failed for Url: "Fbauth2:///" - Error: "(Null)"
Achieving Bright, Vivid Colors for an iOS 7 Translucent Uinavigationbar