Does anyone know if UIPopoverPresentationController
can be used to present popovers on iPhones? Wondering if Apple added this feature on iOS 8 in their attempt to create a more unified presentation controllers for iPad and iPhone.
Not sure if its OK to ask/answer questions from Beta. I will remove it in that case.
Add a new file to the project, Select File -> New ->File and then select iOS -> Source -> Cocoa Touch Class. Name it PopoverViewController and make it a subclass of UIViewController. Go back to Main. storyboard and select the added View Controller.
An object that manages the display of content in a popover.
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)
If anybody wants to present a popover with code only, you can use the following approach.
OBJECTIVE - C
Declare a property of UIPopoverPresentationController
:
@property(nonatomic,retain)UIPopoverPresentationController *dateTimePopover8;
Use the following method to present the popover from UIButton:
- (IBAction)btnSelectDatePressed:(id)sender { 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.navigationBarHidden = YES; [self presentViewController:destNav animated:YES completion:nil]; }
Use the following method to present the popover from UIBarButtonItem:
- (IBAction)btnSelectDatePressed:(id)sender { 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; CGRect frame = [[sender valueForKey:@"view"] frame]; frame.origin.y = frame.origin.y+20; _dateTimePopover8.sourceRect = frame; destNav.navigationBarHidden = YES; [self presentViewController:destNav animated:YES completion:nil]; }
Implement this delegate method too in your view controller:
- (UIModalPresentationStyle) adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller { return UIModalPresentationNone; }
To dismiss this popover, simply dismiss the view controller. Below is the code to dismiss the view controller:
-(void)hideIOS8PopOver { [self dismissViewControllerAnimated:YES completion:nil]; }
SWIFT
Use the following method to present the popover from UIButon:
func filterBooks(sender: UIButon) { let filterVC = FilterDistanceViewController(nibName: "FilterDistanceViewController", bundle: nil) var filterDistanceViewController = UINavigationController(rootViewController: filterVC) filterDistanceViewController.preferredContentSize = CGSizeMake(300, 205) let popoverPresentationViewController = filterDistanceViewController.popoverPresentationController popoverPresentationViewController?.permittedArrowDirections = .Any popoverPresentationViewController?.delegate = self popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem popoverPresentationViewController!.sourceView = self.view; popoverPresentationViewController!.sourceRect = sender.frame filterDistanceViewController.modalPresentationStyle = UIModalPresentationStyle.Popover filterDistanceViewController.navigationBarHidden = true self.presentViewController(filterDistanceViewController, animated: true, completion: nil) }
Use the following method to present the popover from UIBarButtonItem:
func filterBooks(sender: UIBarButtonItem) { let filterVC = FilterDistanceViewController(nibName: "FilterDistanceViewController", bundle: nil) var filterDistanceViewController = UINavigationController(rootViewController: filterVC) filterDistanceViewController.preferredContentSize = CGSizeMake(300, 205) let popoverPresentationViewController = filterDistanceViewController.popoverPresentationController popoverPresentationViewController?.permittedArrowDirections = .Any popoverPresentationViewController?.delegate = self popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem popoverPresentationViewController!.sourceView = self.view; var frame:CGRect = sender.valueForKey("view")!.frame frame.origin.y = frame.origin.y+20 popoverPresentationViewController!.sourceRect = frame filterDistanceViewController.modalPresentationStyle = UIModalPresentationStyle.Popover filterDistanceViewController.navigationBarHidden = true self.presentViewController(filterDistanceViewController, animated: true, completion: nil) }
Implement this delegate method too in your view controller:
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle{ return .None }
Please make sure to add delegate UIPopoverPresentationControllerDelegate
in .h/.m/.swift file
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With