如何在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:15:54  来源:igfitidea点击:

How to present popover properly in iOS 8

iosswiftuipopovercontrollerios8uipopover

提问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:

输出:

enter image description here

在此处输入图片说明

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 UIBarButtonnamed "Config".

实际上它比这简单得多。在情节提要中,您应该将要用作弹出窗口的视图控制器制作成通常的视图控制器类。从要打开弹出窗口的对象(在本例中为UIBarButton名为“Config”)进行如下所示的转场。

enter image description here

在此处输入图片说明

In the "mother viewcontroller" implement the UIPopoverPresentationControllerDelegateand the delegate method:

在“母视图控制器”中实现UIPopoverPresentationControllerDelegate和委托方法:

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

Override the prepareForSequemethod 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.presentedViewControllermethod 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 ADD
UIPopoverPresentationControllerDelegate, 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
}