如何在iOS 8中正确呈现popover

我试图添加一个UIPopoverView到我的Swift iOS 8应用程序,但我无法访问PopoverContentSize属性,因为弹窗没有显示正确的形状。 我的代码:

var popover: UIPopoverController? = nil func addCategory() { var newCategory = storyboard.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController var nav = UINavigationController(rootViewController: newCategory) popover = UIPopoverController(contentViewController: nav) popover!.setPopoverContentSize(CGSizeMake(550, 600), animated: true) popover!.delegate = self popover!.presentPopoverFromBarButtonItem(self.navigationItem.rightBarButtonItem, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true) } 

输出:

在这里输入图像说明

当我通过UIPopoverPresentationController做同样的事情时,我仍然没有完成。 这是我的代码:

 func addCategory() { var popoverContent = self.storyboard.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController var nav = UINavigationController(rootViewController: popoverContent) nav.modalPresentationStyle = UIModalPresentationStyle.Popover var popover = nav.popoverPresentationController as UIPopoverPresentationController popover.delegate = self popover.popoverContentSize = CGSizeMake(1000, 300) popover.sourceView = self.view popover.sourceRect = CGRectMake(100,100,0,0) self.presentViewController(nav, animated: true, completion: nil) } 

我得到完全相同的输出。

我如何定制popover的大小? 任何帮助将不胜感激!

好吧,一个室友看了看,发现:

  func addCategory() { var popoverContent = self.storyboard?.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController var nav = UINavigationController(rootViewController: popoverContent) nav.modalPresentationStyle = UIModalPresentationStyle.Popover var popover = nav.popoverPresentationController popoverContent.preferredContentSize = CGSizeMake(500,600) popover.delegate = self popover.sourceView = self.view popover.sourceRect = CGRectMake(100,100,0,0) self.presentViewController(nav, animated: true, completion: nil) } 

就是这个方法。

你不再与popover本身聊天,你可以通过调用属性preferredContentSize来与其内部的视图控制器进行通信来设置内容的大小

其实它比这更简单。 在故事板中,您应该使您想用作popover的viewcontroller,并像往常一样为其制作viewcontroller类。 从你要打开popup窗口的对象中select一个如下所示的segue,在这种情况下是名为“Config”的UIBarButton

在这里输入图像说明

在“母UIPopoverPresentationControllerDelegate ”实现UIPopoverPresentationControllerDelegate和委托方法:

 func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) { //do som stuff from the popover } 

像这样覆盖prepareForSeque方法:

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { //segue for the popover configuration window if segue.identifier == "yourSegueIdentifierForPopOver" { if let controller = segue.destinationViewController as? UIViewController { controller.popoverPresentationController!.delegate = self controller.preferredContentSize = CGSize(width: 320, height: 186) } } } 

你完成了。 你现在可以把popover视图当作其他视图来处理,比如。 添加字段和什么不是! 通过使用popoverPresentationController.presentedViewController中的UIPopoverPresentationController方法,您可以掌握内容控制器。

另外在iPhone上,你将不得不覆盖

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

我find了一个完整的例子,如何让这一切工作,以便您可以随时显示popover无论设备/方向https://github.com/frogcjn/AdaptivePopover_iOS8_Swift

关键是要实现UIAdaptivePresentationControllerDelegate

 func adaptivePresentationStyleForPresentationController(PC: UIPresentationController!) -> UIModalPresentationStyle { // This *forces* a popover to be displayed on the iPhone return .None } 

然后扩展上面的例子(来自Imagine Digital):

 nav.popoverPresentationController!.delegate = implOfUIAPCDelegate 

Swift 2.0

那么我解决了。 看一看。 在StoryBoard中创build一个ViewController。 与PopOverViewController类相关联。

 import UIKit class PopOverViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() self.preferredContentSize = CGSizeMake(200, 200) self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: "dismiss:") } func dismiss(sender: AnyObject) { self.dismissViewControllerAnimated(true, completion: nil) } } 

请参阅ViewController:

 // ViewController.swift import UIKit class ViewController: UIViewController, UIPopoverPresentationControllerDelegate { func showPopover(base: UIView) { if let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("popover") as? PopOverViewController { let navController = UINavigationController(rootViewController: viewController) navController.modalPresentationStyle = .Popover if let pctrl = navController.popoverPresentationController { pctrl.delegate = self pctrl.sourceView = base pctrl.sourceRect = base.bounds self.presentViewController(navController, animated: true, completion: nil) } } } override func viewDidLoad(){ super.viewDidLoad() } @IBAction func onShow(sender: UIButton) { self.showPopover(sender) } func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle { return .None } } 

注意:func showPopover(base:UIView)方法应放置在ViewDidLoad之前。 希望能帮助到你 !

在iOS9中,UIPopoverController已折旧。 所以可以在iOS9.x以上的Objective-C版本中使用下面的代码,

 - (IBAction)onclickPopover:(id)sender { UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; UIViewController *viewController = [sb instantiateViewControllerWithIdentifier:@"popover"]; viewController.modalPresentationStyle = UIModalPresentationPopover; viewController.popoverPresentationController.sourceView = self.popOverBtn; viewController.popoverPresentationController.sourceRect = self.popOverBtn.bounds; viewController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny; [self presentViewController:viewController animated:YES completion:nil]; } 

在这里,我转换“Joris416”Swift Code Objective-C,

 -(void) popoverstart { ViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"PopoverView"]; UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:controller]; nav.modalPresentationStyle = UIModalPresentationPopover; UIPopoverPresentationController *popover = nav.popoverPresentationController; controller.preferredContentSize = CGSizeMake(300, 200); popover.delegate = self; popover.sourceView = self.view; popover.sourceRect = CGRectMake(100, 100, 0, 0); popover.permittedArrowDirections = UIPopoverArrowDirectionAny; [self presentViewController:nav animated:YES completion:nil]; } -(UIModalPresentationStyle) adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller { return UIModalPresentationNone; } 

请记住添加
UIPopoverPresentationControllerDelegate, UIAdaptivePresentationControllerDelegate

这在iOS8逐日博客中得到了最好的解释

简而言之,一旦将UIViewController的modalPresentationStyle设置为.Popover,就可以通过控制器的popoverPresentationController属性获取UIPopoverPresentationClass(一个新的iOS8类)。

上面我做了一个Objective-C的Imagine Digitals快速答案。 我不认为我错过了任何事情,因为它似乎在初步testing工作,如果你发现让我知道的东西,我会更新它

 -(void) presentPopover { YourViewController* popoverContent = [[YourViewController alloc] init]; //this will be a subclass of UIViewController UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:popoverContent]; nav.modalPresentationStyle = UIModalPresentationPopover; UIPopoverPresentationController* popover = nav.popoverPresentationController; popoverContent.preferredContentSize = CGSizeMake(500,600); popover.delegate = self; popover.sourceRect = CGRectMake(100,100,0,0); //I actually used popover.barButtonItem = self.myBarButton; [self presentViewController:nav animated:YES completion:nil]; } 

在您的Viewcontroller中实现UIAdaptivePresentationControllerDelegate。 然后加 :

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

Swift 3:在我的情况下,先验知识只有底层的UIViewController是一个TextViewController(我需要popover的UIViewController的名称),它可能是一个popOverPresentationController,它包含一个NSMutableAttributedString。

这是通过使用NSMutableAttributedString的大小构造popOverPresentationController为正确大小所需的所有信息,然后将UIViewController的大小设置为传递给它的string的大小。 我创build一个NSMutableAttributedString,使用名为“createStats()”的方法设置其内容。

请注意,我需要设置底层的UIViewController的首选内容大小,所以我使用:tvc.preferredContentSize来设置它。 UIViewController被命名为“tvc”。 我使用tvc.preferredContentSize = CGSizeFromString(String(描述:myCreatedAttributedMutableString))。

我的popOverPresentationController(这是一个UIViewController)有一个textView。 所以在故事板中,我将textView设置为“Attributed”。 在这里input图像说明

textView有一个string(称为“操作”),用segue传递给它。 该string(“operations”)是发生popup时要显示的全部内容。

所以我的解决方法是在准备中使用以下内容(for segue:…)

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let tvc = segue.destination as? TextViewController { if let ppc = tvc.popoverPresentationController { ppc.delegate = self } let returnStatsStr: NSMutableAttributedString = createStats() let myCreatedAttributedMutableString = NSMutableAttributedString.init() myCreatedAttributedMutableString.append(returnStatsStr) tvc.operations = myCreatedAttributedMutableString tvc.preferredContentSize = CGSizeFromString(String(describing: myCreatedAttributedMutableString)) } } 

这是它popup时的显示方式。

在这里input图像说明