Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIPopoverPresentationController on iOS 8 iPhone

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.

like image 690
Dave Avatar asked Aug 14 '14 23:08

Dave


People also ask

How do I show popover in iOS?

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.

What is popoverpresentationcontroller?

An object that manages the display of content in a popover.


2 Answers

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)

like image 93
Ivan Choo Avatar answered Sep 20 '22 22:09

Ivan Choo


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

like image 31
Desert Rose Avatar answered Sep 22 '22 22:09

Desert Rose