如何在 iOS 8 中正确呈现弹出框
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24635744/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to present popover properly in iOS 8
提问by Joris416
I'm trying to add a UIPopoverView to my Swift iOS 8 app, but I am unable to access the PopoverContentSize property, as the popover does not show in the correct shape. my code:
我正在尝试将 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)
}
output:
输出:
When I am doing the same thing through UIPopoverPresentationController, I still don't get it done. this is my code:
当我通过 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)
}
I get the exact same output.
我得到完全相同的输出。
How do I customize the size of my popover? Any help would be highly appreciated!
如何自定义弹出框的大小?任何帮助将不胜感激!
回答by Joris416
Okay, A housemate took a look at it and figured it out:
好吧,一个室友看了看,想通了:
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)
}
That's the way.
就是这样做。
You don't talk to the popover itself anymore, you talk to the view controller inside of it to set the content size, by calling the property preferredContentSize
您不再与 popover 本身对话,而是与其中的视图控制器对话以设置内容大小,方法是调用属性 preferredContentSize
回答by user1700737
Actually it is much simpler than that. In the storyboard you should make the viewcontroller you want to use as popover and make a viewcontroller class for it as usual. Make a segue as shown below from the object you want to open the popover, in this case the UIBarButton
named "Config".
实际上它比这简单得多。在情节提要中,您应该将要用作弹出窗口的视图控制器制作成通常的视图控制器类。从要打开弹出窗口的对象(在本例中为UIBarButton
名为“Config”)进行如下所示的转场。
In the "mother viewcontroller" implement the UIPopoverPresentationControllerDelegate
and the delegate method:
在“母视图控制器”中实现UIPopoverPresentationControllerDelegate
和委托方法:
func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) {
//do som stuff from the popover
}
Override the prepareForSeque
method like this:
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)
}
}
}
And you're done. And you can now treat the popover view as any other view, ie. add fields and what not! And you get hold of the the content controller by using the popoverPresentationController.presentedViewController
method in the UIPopoverPresentationController
.
你已经完成了。您现在可以将弹出视图视为任何其他视图,即。添加字段和什么不是!而通过使用获得该内容控制器保持popoverPresentationController.presentedViewController
的方法UIPopoverPresentationController
。
Also on an iPhone you would have to overwrite
同样在 iPhone 上,您必须覆盖
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.none
}
回答by David Hunt
I found a complete example of how to get this all to work so that you can alwaysdisplay a popover no matter the device/orientation https://github.com/frogcjn/AdaptivePopover_iOS8_Swift.
我找到了一个完整的示例,说明如何使这一切正常工作,以便无论设备/方向如何https://github.com/frogcjn/AdaptivePopover_iOS8_Swift,您都可以始终显示弹出窗口。
The key is to implement UIAdaptivePresentationControllerDelegate
关键是要实现 UIAdaptivePresentationControllerDelegate
func adaptivePresentationStyleForPresentationController(PC: UIPresentationController!) -> UIModalPresentationStyle {
// This *forces* a popover to be displayed on the iPhone
return .None
}
Then extend the example above (from Imagine Digital):
然后扩展上面的例子(来自 Imagine Digital):
nav.popoverPresentationController!.delegate = implOfUIAPCDelegate
回答by A.G
Swift 2.0
斯威夫特 2.0
Well I worked out. Have a look. Made a ViewController in StoryBoard. Associated with PopOverViewController class.
好吧,我解决了。看一看。在 StoryBoard 中创建了一个 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)
}
}
See 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
}
}
Note: The func showPopover(base: UIView) method should be placed before ViewDidLoad. Hope it helps !
注意:func showPopover(base: UIView) 方法应该放在 ViewDidLoad 之前。希望能帮助到你 !
回答by Vijay
In iOS9 UIPopoverController is depreciated. So can use the below code for Objective-C version above iOS9.x,
在 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]; }
回答by user2941395
Here i Convert "Joris416" Swift Code to Objective-c,
在这里,我将“Joris416”Swift 代码转换为 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;
}
Remember to ADDUIPopoverPresentationControllerDelegate, UIAdaptivePresentationControllerDelegate
记得添加UIPopoverPresentationControllerDelegate, UIAdaptivePresentationControllerDelegate
回答by Clafou
This is best explained on the iOS8 Day-by-Day blog
这在iOS8 Day-by-Day 博客中得到了最好的解释
In short, once you've set your UIViewController's modalPresentationStyle to .Popover, you can get hold of a UIPopoverPresentationClass (a new iOS8 class) via the controller's popoverPresentationController property.
简而言之,一旦您将 UIViewController 的 modalPresentationStyle 设置为 .Popover,您就可以通过控制器的 popoverPresentationController 属性获得一个 UIPopoverPresentationClass(一个新的 iOS8 类)。
回答by narco
I made an Objective-C version of Imagine Digitals swift answer above. I don't think I missed anything as it seems to work under preliminary testing, if you spot something let me know, and I'll update it
我在上面制作了一个 Objective-C 版本的 Imagine Digitals 快速答案。我不认为我错过了任何东西,因为它似乎在初步测试中工作,如果你发现了什么让我知道,我会更新它
-(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];
}
回答by ingconti
my two cents for xcode 9.1 / swift 4.
我的 xcode 9.1 / swift 4 两美分。
class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {
override func viewDidLoad(){
super.viewDidLoad()
let when = DispatchTime.now() + 0.5
DispatchQueue.main.asyncAfter(deadline: when, execute: { () -> Void in
// to test after 05.secs... :)
self.showPopover(base: self.view)
})
}
func showPopover(base: UIView) {
if let viewController = self.storyboard?.instantiateViewController(withIdentifier: "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.present(navController, animated: true, completion: nil)
}
}
}
@IBAction func onShow(sender: UIButton){
self.showPopover(base: sender)
}
func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle{
return .none
}
and experiment in:
并在以下方面进行实验:
func adaptivePresentationStyle...
func 自适应演示样式...
return .popover
or: return .pageSheet.... and so on..
或:返回 .pageSheet.... 等等..
回答by Nyakiba
Implement UIAdaptivePresentationControllerDelegate in your Viewcontroller. Then add :
在您的视图控制器中实现 UIAdaptivePresentationControllerDelegate。然后加 :
func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle{
return .none
}