iPhone上的UIPopoverPresentationController不会产生popup窗口

我试图在我的iPhone应用程序中实现新的UIPopoverPresentationController (使用Objective C)。 我想要的是一个简单的popup式窗口,从发起button发出。

– 编辑 –

以下是我的REVISED代码,根据文档SO中的研究进行了改编,并从以下注释中进行了介绍:

 - (IBAction)selectCategoryBtn:(UIButton *)sender { [self performSegueWithIdentifier:@"CatSelectSegue" sender:self.selCatButton]; } -(void) prepareForSegue:(UIStoryboardSegue *) segue Sender:(id) sender { if (sender == self.selCatButton) { if ([segue.identifier isEqualToString:@"CatSelectSegue"]) { UIPopoverPresentationController *controller = segue.destinationViewController; controller.delegate = self; controller.sourceView = self.selCatButton; controller.sourceRect = self.selCatButton.frame; } } } -(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller { return UIModalPresentationNone; 

这是我的故事板连接:

在这里输入图像说明

但是,这只是以模式的方式呈现一个桌面视图,从底部上升,并消耗整个屏幕。

我search了一下,然后看了很久,但似乎我并不是唯一一个被我希望为iPhone解决一个棘手问题而困惑的人。

任何人都可以在我的代码中看到一个小故障,或指示我一个明确的教程? 我看了,但也许API是如此新的人没有得到它的处理呢。

谢谢!

第二编辑:

以上是代码的结果。 我减less了视图控制器中的表格视图的大小,我预计会显示为popup窗口。 我把背景变成灰色,只是为了澄清显示的是什么,而不是popup窗口。

在这里输入图像说明

脚步:

A)使用Present As Popover seguetypes将UIButton链接到popup窗口的视图控制器。 实际上,我不得不创build一个新的项目来实现这个function,但这可能与基础SDK有关。

B)使包含UIButton的View Controller符合<UIPopoverPresentationControllerDelegate> 。 例如在你的MyViewController.m文件中添加:

 @interface MyViewController () <UIPopoverPresentationControllerDelegate> 

C)将下面的方法添加到包含UIButton的View Controller中:

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

D)将下列内容添加到您的prepareForSegue:sender:replace您的segue.identifier检查:

 if ([segue.identifier isEqualToString:@"CatSelectSegue"]) { UIViewController *dvc = segue.destinationViewController; UIPopoverPresentationController *controller = dvc.popoverPresentationController; if (controller) { controller.delegate = self; } } 

代码testing和certificate它的工作原理:

iPhone上没有第三方控制的弹出窗口

编辑:我的testing应用程序TPOPViewController.m文件魔术发生的地方:

 #import "TPOPViewController.h" @interface TPOPViewController () <UIPopoverPresentationControllerDelegate>//, 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 

我的testing故事板也是这样的:

在iPhone测试故事板的Popover

显然上面的方法不再适用于iOS9 / Xcode7 。 这是因为如果您使用Interface Builder将segue样式设置为“Popover”,则Xcode在编译应用程序时会忽略它。 此外,下次打开项目时会自动将“继续”设置为“推送”。 如果你有像Git这样的版本控制软件,你将能够观察到这个不需要的改变。

但是,如果您手动呈现您想要显示为popup窗口的视图控制器,则仍然可以在iPhone上获得iPad风格的popup窗口。 示例Swift代码:

 // ViewController.swift // PopoverDemo // // Created by bhnascar on 12/2/15. // Copyright © 2015 bhnascar. All rights reserved. // import UIKit class ViewController: UIViewController, UIPopoverPresentationControllerDelegate { /* The bar button item that will present the popover. */ var popoverButton: UIBarButtonItem? override func viewDidLoad() { super.viewDidLoad() popoverButton = UIBarButtonItem(title: "Pop!", style: UIBarButtonItemStyle.Plain, target: self, action: "presentPopover") self.navigationItem.rightBarButtonItem = popoverButton } // Mark: - UIPopoverPresentationControllerDelegate func prepareForPopoverPresentation(popoverPresentationController: UIPopoverPresentationController) { popoverPresentationController.permittedArrowDirections = .any popoverPresentationController.barButtonItem = popoverButton } func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle { return .none } // Mark: - Callback function for popover button. func presentPopover() { let popoverContentController = UIViewController() popoverContentController.view.backgroundColor = .blue // Set your popover size. popoverContentController.preferredContentSize = CGSize(width: 300, height: 300) // Set the presentation style to modal so that the above methods get called. popoverContentController.modalPresentationStyle = .popover // Set the popover presentation controller delegate so that the above methods get called. popoverContentController.popoverPresentationController!.delegate = self // Present the popover. self.present(popoverContentController, animated: true, completion: nil) } } 

SWIFT 3.X

这将在屏幕中心显示popup窗口

 class CommonViewController: UIViewController, UIPopoverPresentationControllerDelegate{ func adaptivePresentationStyle( for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle { return .none } func showPopover(){ let storyboard = UIStoryboard(name: "Pickers", bundle: nil) let myViewController = UIViewController() myViewController.preferredContentSize = CGSize(width: 320, height: 200) myViewController.modalPresentationStyle = .popover let popOver = myViewController.popoverPresentationController popOver?.delegate = self self.present(myViewController, animated: true, completion: nil) popOver?.permittedArrowDirections = .init(rawValue: 0) popOver?.sourceView = self.view let rect = CGRect( origin: CGPoint(x: self.view.frame.width/2, y: self.view.frame.height/2), size: CGSize(width: 1, height: 1) ) popOver?.sourceRect = rect } 

从iPhone / iPad演示UIModalPresentationStyle popover:

 -(void)menuButtonPressed:(UIButton *)sender { self.menuPopoverController = [[DownloadMenuPopoverController alloc] initWithStyle:UITableViewStylePlain]; self.menuPopoverController.delegate = self; self.menuPopoverController.modalPresentationStyle = UIModalPresentationPopover; self.menuPopoverController.popoverPresentationController.delegate = self; self.menuPopoverController.preferredContentSize = CGSizeMake(250,80); self.menuPopoverController.popoverPresentationController.sourceRect = sender.frame;// rect to show view self.menuPopoverController.popoverPresentationController.sourceView = self.view; UIPopoverPresentationController *popPC = self.menuPopoverController.popoverPresentationController; popPC.permittedArrowDirections = UIPopoverArrowDirectionAny; popPC.delegate = self; [self presentViewController:self.menuPopoverController animated:YES completion:nil]; } #pragma mark - UIPresentationController Delegate methods - (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection { return UIModalPresentationNone; } - (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style { UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller.presentedViewController]; return navController; }