UIPopoverPresentationController is showing full screen modal on iPhone - ios

On iPad UIPopoverPresentationController working fine but on iPhone it is always showing full window modal popup. i am using following code:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MySecondViewController *contentVC = [storyboard instantiateViewControllerWithIdentifier:#"Pop"];
contentVC.modalPresentationStyle = UINavigationControllerOperationPop; // 13
UIPopoverPresentationController *popPC = contentVC.popoverPresentationController; // 14
contentVC.popoverPresentationController.sourceRect =CGRectMake(100, 130, 280, 230);
self.navigationController.preferredContentSize = CGSizeMake(200, self.parentViewController.childViewControllers.lastObject.preferredContentSize.height-100);
//self.showPop.frame; // 15
contentVC.popoverPresentationController.sourceView =
self.showPop; // 16
popPC.permittedArrowDirections = UIPopoverArrowDirectionAny; // 17
popPC.delegate = self; //18
[self presentViewController:contentVC animated:YES completion:nil];
-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}

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;
}

Popover controllers are for use exclusively on iPad devices.
Edit: As stated by Soberman, since iOS 8 it is possible to present popovers on iPhone using public APIs, so this answer is probably not relevant anymore.
As stated in Apple's documentation on UIPopoverController:
Popover controllers are for use exclusively on iPad devices.
So there is no way to use this class in iPhone application unfortunately. But there are a couple of custom third-party implementations of the functionality provided by UIPopoverController which add iPhone support and more. See https://github.com/50pixels/FPPopover for example.
Edit: There also is another highly customizable popover implementation for both iPhone/iPad worth checking out: https://github.com/nicolaschengdev/WYPopoverController.

Related

UIPopoverPresentationController showing full screen modal popup always

I am trying to show a view controller as UIPopoverPresentationController below the button or in center of window. But it is always showing as full window modal popup.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MySecondViewController *controller = [storyboard instantiateViewControllerWithIdentifier:#"Pop"];
// present the controller
// on iPad, this will be a Popover
// on iPhone, this will be an action sheet
controller.modalPresentationStyle = UINavigationControllerOperationPop;
[self presentViewController:controller animated:YES completion:nil];
controller.preferredContentSize = CGSizeMake(280, 230);
// configure the Popover presentation controller
UIPopoverPresentationController *popController = [controller popoverPresentationController];
popController.permittedArrowDirections = UIPopoverArrowDirectionUp;
popController.delegate = self;
// in case we don't have a bar button as reference
popController.sourceView = self.showPop;
popController.sourceRect = CGRectMake(384, -120, 280, 230);
-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
Try this code it is working
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SecondViewController *controller = [storyboard instantiateViewControllerWithIdentifier:#"pop"];
controller.modalPresentationStyle = UIModalPresentationPopover;
controller.preferredContentSize = CGSizeMake(280, 230);
// configure the Popover presentation controller
controller.popoverPresentationController.delegate = self;
controller.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionUp;
// in case we don't have a bar button as reference
controller.popoverPresentationController.sourceView = self.view;
controller.popoverPresentationController.sourceRect = CGRectMake(384, -120, 280, 230);
// controller.presentationController.delegate = self;
[self presentViewController:controller animated:YES completion:nil];
I have posted another question for the same question and i have resolved my issue. Here is the link of question:
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;
}
In Storyboard this is very easy. Just control drag from the control that will trigger the action (say a UIBarButton or a normal button) to the storyboard view controller (if root view of Navigation controller, drag to the navigation controller).
Select the segue and change the Kind in the attribute inspector to "Present Modally", presentation: Form sheet (if you want it to show at the centre), select the transition type you want (default is cool).
As #Lukas1 mentioned above, you should conform UIPopoverPresentationControllerDelegate and implement adaptivePresentationStyle method (which is actually defined in UIAdaptivePresentationControllerDelegate protocol, UIPopoverPresentationControllerDelegate parent class) and return .none
And here's implementation in Swift5 :
extension ViewController: UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.none
}
}

How do you programmatically configure and present a popover on iPhone in iOS 8+

How can you present a UIViewController in a popover on iPhone (all sizes and orientations), in iOS 8 using only Objective-C code, no Story Boards or other Interface Builder artifacts.
In iOS 8, you can configure any view controller to be displayed as a popover, like so:
UIViewController* controller = ...; // your initialization goes here
// set modal presentation style to popover on your view controller
// must be done before you reference controller.popoverPresentationController
controller.modalPresentationStyle = UIModalPresentationPopover;
controller.preferredContentSize = CGSizeMake(150, 300);
// configure popover style & delegate
UIPopoverPresentationController *popover = controller.popoverPresentationController;
popover.delegate = controller;
popover.sourceView = sourceView;
popover.sourceRect = CGRectMake(150,300,1,1);
popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
// display the controller in the usual way
[self presentViewController:controller animated:YES completion:nil];
So that it displays as a popover on iPhone, add this to the UIPopoverPresentationControllerDelegate delegate of the popover (that you set above):
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
return UIModalPresentationNone;
}

UIPopoverController alternative on iphone devices

I have been searching for almost 2 hours on how to implement UIPopoverController in swift language, at the end, i found out that this api are exclusive for iPad devices only.
How will i be able to make a drop down list on iPhone devices?
please someone help me, at lease with the name of the api so that i know what to search for
You can you third party libraries for that:
FPPopover
WEPopover
or if you don't need iOS 7 support you can use iOS 8 new API which answered in this question
UIPopoverPresentationController on iOS 8 iPhone
i depends on your needs. You can show UIPickerView, present an action sheet or segue to another VC and then go back - these are standard ways.
#property(nonatomic,retain) UIPopoverPresentationController *popoverPresentationController;
- (IBAction)showPopover:(id)sender {
UIViewController *popoverViewController = [[UIViewController alloc] initWithNibName:#"NameViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:popoverViewController];
popoverViewController.preferredContentSize = CGSizeMake(280, 200);
navigationController.modalPresentationStyle = UIModalPresentationPopover;
_popoverPresentationController = navigationController.popoverPresentationController;
_popoverPresentationController.delegate = self;
_popoverPresentationController.sourceView = self.view;
_popoverPresentationController.sourceRect = [sender frame];
navigationController.modalPresentationStyle = UIModalPresentationPopover;
navigationController.navigationBarHidden = YES;
[_viewController presentViewController:navigationController animated:YES completion:nil];
}

UIPopoverController displayed as modalViewController in iOS 8

I just ran into a very frustrating problem. I don't know if it's an iOS8 bug or it's something else.
I'm loading the view from a nib, which looks like this:
Here ist my code:
UIViewController *popoverViewController = [[UIViewController alloc] init];
[popoverViewController setView:poppverViewFromNib];
_popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverViewController];
[_popverController presentPopoverFromRect:CGRectMake(100, 100, 10, 10) inView:[self view] permittedArrowDirections:UIPopverArrowDirectionAny animated:YES];
The iOS simulator as well as the real device are displaying the viewController modally like you can see here:
EDIT
As requested in comments, I tell you what I expect when using UIPopoverController:
I expect an UIPopover, not a modalViewController.
So here my question to all of those how didn't get it: Why does my UIPopoverController does not display as a popover but as modalViewController? How can I fix it?
Read the documentation. Popover presentation is only available for horizontally regular size classes. Currently, this is only on iPad. Popover presentation on iPhone will always be executed as full screen modal presentation. See here.
You are lucky that iOS8 doesn't crash, as iOS7 and below, if you used UIPopoverController on a phone idiom, your app would crash. UIPopoverController is deprecated in iOS8 in favor of popover modal presentation. This is why your app does not crash.
You could keep the same code for UIPopoverController as iOS 7
just set ViewController.preferredContentSize = CGSizeMake(300, 290);
It will work.
Other Solution
iOS 8 has a new PopOverController called UIPopoverPresentationController
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController *navController = [storyboard instantiateViewControllerWithIdentifier:#"Terms_NC"];
navController.preferredContentSize = CGSizeMake(300, 290);
// Present the view controller using the popover style.
navController.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:navController animated: YES completion: nil];
// Get the popover presentation controller and configure it.
UIPopoverPresentationController *presentationController =
[navController popoverPresentationController];
presentationController.permittedArrowDirections =0;
presentationController.sourceView = self.view;
presentationController.sourceRect = CGRectMake(100, 100, 300, 340);

dismissModalViewControllerAnimated crashes in ios 6.0 ipad simulator

I am using the following code to dismiss modal view controllers:
- (IBAction)done {
#ifdef __IPHONE_5_0
if ([self respondsToSelector:#selector(presentingViewController)])
[self.presentingViewController dismissModalViewControllerAnimated:YES];
else
#endif
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
If I runt he simulator using iOS 4.3 iPad, it uses self.parentViewController and works fine. However, when I runt he simulator using iOS 6.0 iPad the simulator crashes right after the view is dismissed using self.presentingViewController.
I do not have an actual iPad to test on... any ideas?
EDIT:
below is the code that creates the modal view controller.
NSArray* errors = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Errors" ofType:#"plist"]];
UIViewController* vc;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
DocumentsViewController_iPad* docsVC = [[DocumentsViewController_iPad alloc] initWithNibName:#"DocumentsViewController-iPad" bundle:nil];
docsVC.documents = errors;
docsVC.errors = YES;
docsVC.navTitle = #"Troubleshooting";
vc = docsVC;
} else {
DocumentsViewController* docsVC = [[DocumentsViewController alloc] initWithNibName:nil bundle:nil];
docsVC.documents = errors;
docsVC.errors = YES;
docsVC.navTitle = #"Troubleshooting";
vc = docsVC;
}
vc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:vc animated:YES];
[vc release];
A few things:
Yes, you should use dismissViewControllerAnimated:completion: as #rdelmar said
You should call it on presentingViewController, not parent
You can skip going to the presenting controller and dismiss self, it will forward this message to the presenting controller if needed.
dismissModalViewControllerAnimated: is depreciated, use dismissViewControllerAnimated:completion: instead.

Resources