iOS 8 iPhone上的UIPopoverPresentationController

有谁知道如果UIPopoverPresentationController可以用来呈现iPhone上的popup? 想知道如果苹果公司在iOS 8上添加了这个function,试图为iPad和iPhone创build一个更统一的演示控制器。

不知道是否可以提出/回答来自Beta的问题。 在这种情况下,我会删除它。

您可以使用可通过UIPopoverPresentationController.delegate使用的adaptivePresentationStyleForPresentationController:方法来覆盖默认的自适应行为(紧凑水平环境中的UIModalPresentationFullScreen ,即iPhone)。

UIPresentationController使用这种方法来要求使用新的performance风格,在你的情况下,只要返回UIModalPresentationNone就会使UIPopoverPresentationController呈现为UIPopoverPresentationController而不是全屏。

下面是一个在UIBarButtonItem中使用故事板中的segue设置来实现“ 模态呈现 ”一个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 } } 

WWDC 2014会议214“视图控制器在iOS8中的进步” (36:30)提到了这个技巧,

如果有人想仅用代码呈现popup窗口,则可以使用以下方法。

目标 – C

声明UIPopoverPresentationController的属性:

 @property(nonatomic,retain)UIPopoverPresentationController *dateTimePopover8; 

使用下面的方法来显示UIButton的popup窗口:

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

使用以下方法来显示UIBarButtonItem的popup窗口:

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

在您的视图控制器中也实现这个委托方法:

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

要解散这个popover,只需closures视图控制器。 以下是closures视图控制器的代码:

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

迅速

使用下面的方法来显示UIButon的popup窗口:

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

使用以下方法来显示UIBarButtonItem的popup窗口:

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

在您的视图控制器中也实现这个委托方法:

 func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle{ return .None } 

请确保在.h / .m / .swift文件中添加委托UIPopoverPresentationControllerDelegate

问题: iPhonepopup窗口显示全屏,不尊重preferredContentSize值。

解决scheme:与Apple在UIPopoverPresentationController类的参考中提出的build议相反,在获取对弹窗演示控制器的引用并对其进行configuration之后 ,显示视图控制器。

 // Get the popover presentation controller and configure it. //... // Present the view controller using the popover style. [self presentViewController:myPopoverViewController animated: YES completion: nil]; 

我find了一些解决方法。

在Xcode6.1上,使用presentationController.delegate而不是popoverPresentationController.delegate

 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier compare:@"showPopOver"] == NSOrderedSame) { UINavigationController * nvc = segue.destinationViewController; UIPresentationController * pc = nvc.presentationController; pc.delegate = self; } } #pragma mark == UIPopoverPresentationControllerDelegate == - (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller { return UIModalPresentationNone; } 

在WWDC 2014“View Controller Advancements in iOS8”中,下面的代码可以显示iPhone上的popup窗口。

 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { UINavigationController * nvc = segue.destinationViewController; UIPopoverPresentationController * pvc = nvc.popoverPresentationController; pvc.delegate = self; } #pragma mark == UIPopoverPresentationControllerDelegate == - (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller { return UIModalPresentationNone; } 

但在Xcode 6.1上,这些代码显示FullScreen演示文稿…(nvc.popoverPresentationController为零)

我怀疑这可能是一个苹果的错误。

确保实现UIAdaptivePresentationControllerDelegate

喜欢这个:

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

如果你不想全屏popup

在iOS 8.3及更高版本中,使用UIPopoverPresentationControllerDelegate协议中的以下语法来覆盖popup窗口的UIModalPresentationStyle

 func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle { return .none } 

在您的WEBVIEW类中添加这两个方法。 并添加

 -(void) prepareForSegue: (UIStoryboardSegue * ) segue sender: (id) sender { // Assuming you've hooked this all up in a Storyboard with a popover presentation style if ([segue.identifier isEqualToString: @"showPopover"]) { UINavigationController * destNav = segue.destinationViewController; pop = destNav.viewControllers.firstObject; // This is the important part UIPopoverPresentationController * popPC = destNav.popoverPresentationController; popPC.delegate = self; } } - (UIModalPresentationStyle) adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller { return UIModalPresentationNone; }